@zoho_apptics/apptics-js-sdk 1.0.1 → 2.0.0-beta

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.
Files changed (226) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/LICENSE +13 -0
  3. package/README.md +747 -11
  4. package/dist/apptics.esm.min.js +3 -0
  5. package/dist/apptics.esm.min.js.map +1 -0
  6. package/dist/apptics.min.js +3 -0
  7. package/dist/apptics.min.js.map +1 -0
  8. package/dist/chunks/batch-BU_mTpm1.min.js +3 -0
  9. package/dist/chunks/batch-BU_mTpm1.min.js.map +1 -0
  10. package/dist/chunks/logs-Bea5zUW_.min.js +3 -0
  11. package/dist/chunks/logs-Bea5zUW_.min.js.map +1 -0
  12. package/dist/cjs/auto-init.d.ts +8 -0
  13. package/dist/cjs/auto-init.js +32 -0
  14. package/dist/cjs/core/attempts.d.ts +28 -0
  15. package/dist/cjs/core/attempts.js +113 -0
  16. package/dist/cjs/core/batch.d.ts +32 -0
  17. package/dist/cjs/core/batch.js +115 -0
  18. package/dist/cjs/core/callsite.d.ts +28 -0
  19. package/dist/cjs/core/callsite.js +93 -0
  20. package/dist/cjs/core/consent.d.ts +23 -0
  21. package/dist/cjs/core/consent.js +130 -0
  22. package/dist/cjs/core/constants.d.ts +212 -0
  23. package/dist/cjs/core/constants.js +299 -0
  24. package/dist/cjs/core/db.d.ts +40 -0
  25. package/dist/cjs/core/db.js +334 -0
  26. package/dist/cjs/core/debug.d.ts +22 -0
  27. package/dist/cjs/core/debug.js +88 -0
  28. package/dist/cjs/core/env.d.ts +28 -0
  29. package/dist/cjs/core/env.js +267 -0
  30. package/dist/cjs/core/framework-id.d.ts +1 -0
  31. package/dist/cjs/core/framework-id.js +9 -0
  32. package/dist/cjs/core/guard.d.ts +2 -0
  33. package/dist/cjs/core/guard.js +72 -0
  34. package/dist/cjs/core/hooks.d.ts +41 -0
  35. package/dist/cjs/core/hooks.js +23 -0
  36. package/dist/cjs/core/logger.d.ts +16 -0
  37. package/dist/cjs/core/logger.js +86 -0
  38. package/dist/cjs/core/state.d.ts +69 -0
  39. package/dist/cjs/core/state.js +78 -0
  40. package/dist/cjs/core/storage.d.ts +46 -0
  41. package/dist/cjs/core/storage.js +229 -0
  42. package/dist/cjs/core/transport.d.ts +83 -0
  43. package/dist/cjs/core/transport.js +441 -0
  44. package/dist/cjs/core/utils.d.ts +26 -0
  45. package/dist/cjs/core/utils.js +175 -0
  46. package/dist/cjs/core/validate.d.ts +18 -0
  47. package/dist/cjs/core/validate.js +233 -0
  48. package/dist/cjs/device/appversion.d.ts +20 -0
  49. package/dist/cjs/device/appversion.js +158 -0
  50. package/dist/cjs/device/index.d.ts +23 -0
  51. package/dist/cjs/device/index.js +372 -0
  52. package/dist/cjs/engagement/api-rules.d.ts +84 -0
  53. package/dist/cjs/engagement/api-rules.js +219 -0
  54. package/dist/cjs/engagement/auto-api.d.ts +7 -0
  55. package/dist/cjs/engagement/auto-api.js +200 -0
  56. package/dist/cjs/engagement/auto-screen.d.ts +16 -0
  57. package/dist/cjs/engagement/auto-screen.js +241 -0
  58. package/dist/cjs/engagement/defined-events.d.ts +23 -0
  59. package/dist/cjs/engagement/defined-events.js +58 -0
  60. package/dist/cjs/engagement/send.d.ts +6 -0
  61. package/dist/cjs/engagement/send.js +99 -0
  62. package/dist/cjs/engagement/session.d.ts +42 -0
  63. package/dist/cjs/engagement/session.js +327 -0
  64. package/dist/cjs/engagement/track.d.ts +56 -0
  65. package/dist/cjs/engagement/track.js +350 -0
  66. package/dist/cjs/errors/send.d.ts +6 -0
  67. package/dist/cjs/errors/send.js +73 -0
  68. package/dist/cjs/errors/track.d.ts +4 -0
  69. package/dist/cjs/errors/track.js +127 -0
  70. package/dist/cjs/feedback/controls.d.ts +31 -0
  71. package/dist/cjs/feedback/controls.js +286 -0
  72. package/dist/cjs/feedback/index.d.ts +8 -0
  73. package/dist/cjs/feedback/index.js +37 -0
  74. package/dist/cjs/feedback/logs.d.ts +40 -0
  75. package/dist/cjs/feedback/logs.js +202 -0
  76. package/dist/cjs/feedback/send.d.ts +25 -0
  77. package/dist/cjs/feedback/send.js +178 -0
  78. package/dist/cjs/feedback/template.d.ts +2 -0
  79. package/dist/cjs/feedback/template.js +162 -0
  80. package/dist/cjs/feedback/ui.d.ts +55 -0
  81. package/dist/cjs/feedback/ui.js +631 -0
  82. package/dist/cjs/heatmap/index.d.ts +16 -0
  83. package/dist/cjs/heatmap/index.js +22 -0
  84. package/dist/cjs/heatmap/send.d.ts +13 -0
  85. package/dist/cjs/heatmap/send.js +82 -0
  86. package/dist/cjs/heatmap/track.d.ts +4 -0
  87. package/dist/cjs/heatmap/track.js +377 -0
  88. package/dist/cjs/index.d.ts +68 -0
  89. package/dist/cjs/index.js +150 -0
  90. package/dist/cjs/lifecycle.d.ts +14 -0
  91. package/dist/cjs/lifecycle.js +538 -0
  92. package/dist/cjs/package.json +3 -0
  93. package/dist/cjs/remoteconfig/custom.d.ts +10 -0
  94. package/dist/cjs/remoteconfig/custom.js +78 -0
  95. package/dist/cjs/remoteconfig/evaluate.d.ts +24 -0
  96. package/dist/cjs/remoteconfig/evaluate.js +171 -0
  97. package/dist/cjs/remoteconfig/fetch.d.ts +24 -0
  98. package/dist/cjs/remoteconfig/fetch.js +214 -0
  99. package/dist/cjs/remoteconfig/index.d.ts +13 -0
  100. package/dist/cjs/remoteconfig/index.js +90 -0
  101. package/dist/cjs/remoteconfig/store.d.ts +18 -0
  102. package/dist/cjs/remoteconfig/store.js +98 -0
  103. package/dist/cjs/remotelog/gate.d.ts +11 -0
  104. package/dist/cjs/remotelog/gate.js +54 -0
  105. package/dist/cjs/remotelog/index.d.ts +25 -0
  106. package/dist/cjs/remotelog/index.js +55 -0
  107. package/dist/cjs/remotelog/logger.d.ts +28 -0
  108. package/dist/cjs/remotelog/logger.js +139 -0
  109. package/dist/cjs/remotelog/send.d.ts +13 -0
  110. package/dist/cjs/remotelog/send.js +153 -0
  111. package/dist/cjs/scheduler.d.ts +8 -0
  112. package/dist/cjs/scheduler.js +78 -0
  113. package/dist/cjs/types.d.ts +312 -0
  114. package/dist/cjs/user/index.d.ts +33 -0
  115. package/dist/cjs/user/index.js +178 -0
  116. package/dist/esm/auto-init.d.ts +8 -0
  117. package/dist/esm/auto-init.js +29 -0
  118. package/dist/esm/core/attempts.d.ts +28 -0
  119. package/dist/esm/core/attempts.js +106 -0
  120. package/dist/esm/core/batch.d.ts +32 -0
  121. package/dist/esm/core/batch.js +108 -0
  122. package/dist/esm/core/callsite.d.ts +28 -0
  123. package/dist/esm/core/callsite.js +89 -0
  124. package/dist/esm/core/consent.d.ts +23 -0
  125. package/dist/esm/core/consent.js +120 -0
  126. package/dist/esm/core/constants.d.ts +212 -0
  127. package/dist/esm/core/constants.js +277 -0
  128. package/dist/esm/core/db.d.ts +40 -0
  129. package/dist/esm/core/db.js +324 -0
  130. package/dist/esm/core/debug.d.ts +22 -0
  131. package/dist/esm/core/debug.js +81 -0
  132. package/dist/esm/core/env.d.ts +28 -0
  133. package/dist/esm/core/env.js +251 -0
  134. package/dist/esm/core/framework-id.d.ts +1 -0
  135. package/dist/esm/core/framework-id.js +7 -0
  136. package/dist/esm/core/guard.d.ts +2 -0
  137. package/dist/esm/core/guard.js +70 -0
  138. package/dist/esm/core/hooks.d.ts +41 -0
  139. package/dist/esm/core/hooks.js +21 -0
  140. package/dist/esm/core/logger.d.ts +16 -0
  141. package/dist/esm/core/logger.js +82 -0
  142. package/dist/esm/core/state.d.ts +69 -0
  143. package/dist/esm/core/state.js +73 -0
  144. package/dist/esm/core/storage.d.ts +46 -0
  145. package/dist/esm/core/storage.js +219 -0
  146. package/dist/esm/core/transport.d.ts +83 -0
  147. package/dist/esm/core/transport.js +425 -0
  148. package/dist/esm/core/utils.d.ts +26 -0
  149. package/dist/esm/core/utils.js +161 -0
  150. package/dist/esm/core/validate.d.ts +18 -0
  151. package/dist/esm/core/validate.js +226 -0
  152. package/dist/esm/device/appversion.d.ts +20 -0
  153. package/dist/esm/device/appversion.js +153 -0
  154. package/dist/esm/device/index.d.ts +23 -0
  155. package/dist/esm/device/index.js +362 -0
  156. package/dist/esm/engagement/api-rules.d.ts +84 -0
  157. package/dist/esm/engagement/api-rules.js +211 -0
  158. package/dist/esm/engagement/auto-api.d.ts +7 -0
  159. package/dist/esm/engagement/auto-api.js +198 -0
  160. package/dist/esm/engagement/auto-screen.d.ts +16 -0
  161. package/dist/esm/engagement/auto-screen.js +238 -0
  162. package/dist/esm/engagement/defined-events.d.ts +23 -0
  163. package/dist/esm/engagement/defined-events.js +55 -0
  164. package/dist/esm/engagement/send.d.ts +6 -0
  165. package/dist/esm/engagement/send.js +96 -0
  166. package/dist/esm/engagement/session.d.ts +42 -0
  167. package/dist/esm/engagement/session.js +315 -0
  168. package/dist/esm/engagement/track.d.ts +56 -0
  169. package/dist/esm/engagement/track.js +340 -0
  170. package/dist/esm/errors/send.d.ts +6 -0
  171. package/dist/esm/errors/send.js +70 -0
  172. package/dist/esm/errors/track.d.ts +4 -0
  173. package/dist/esm/errors/track.js +123 -0
  174. package/dist/esm/feedback/controls.d.ts +31 -0
  175. package/dist/esm/feedback/controls.js +280 -0
  176. package/dist/esm/feedback/index.d.ts +8 -0
  177. package/dist/esm/feedback/index.js +30 -0
  178. package/dist/esm/feedback/logs.d.ts +40 -0
  179. package/dist/esm/feedback/logs.js +188 -0
  180. package/dist/esm/feedback/send.d.ts +25 -0
  181. package/dist/esm/feedback/send.js +175 -0
  182. package/dist/esm/feedback/template.d.ts +2 -0
  183. package/dist/esm/feedback/template.js +159 -0
  184. package/dist/esm/feedback/ui.d.ts +55 -0
  185. package/dist/esm/feedback/ui.js +626 -0
  186. package/dist/esm/heatmap/index.d.ts +16 -0
  187. package/dist/esm/heatmap/index.js +17 -0
  188. package/dist/esm/heatmap/send.d.ts +13 -0
  189. package/dist/esm/heatmap/send.js +79 -0
  190. package/dist/esm/heatmap/track.d.ts +4 -0
  191. package/dist/esm/heatmap/track.js +374 -0
  192. package/dist/esm/index.d.ts +68 -0
  193. package/dist/esm/index.js +122 -0
  194. package/dist/esm/lifecycle.d.ts +14 -0
  195. package/dist/esm/lifecycle.js +534 -0
  196. package/dist/esm/package.json +3 -0
  197. package/dist/esm/remoteconfig/custom.d.ts +10 -0
  198. package/dist/esm/remoteconfig/custom.js +74 -0
  199. package/dist/esm/remoteconfig/evaluate.d.ts +24 -0
  200. package/dist/esm/remoteconfig/evaluate.js +166 -0
  201. package/dist/esm/remoteconfig/fetch.d.ts +24 -0
  202. package/dist/esm/remoteconfig/fetch.js +210 -0
  203. package/dist/esm/remoteconfig/index.d.ts +13 -0
  204. package/dist/esm/remoteconfig/index.js +85 -0
  205. package/dist/esm/remoteconfig/store.d.ts +18 -0
  206. package/dist/esm/remoteconfig/store.js +91 -0
  207. package/dist/esm/remotelog/gate.d.ts +11 -0
  208. package/dist/esm/remotelog/gate.js +48 -0
  209. package/dist/esm/remotelog/index.d.ts +25 -0
  210. package/dist/esm/remotelog/index.js +51 -0
  211. package/dist/esm/remotelog/logger.d.ts +28 -0
  212. package/dist/esm/remotelog/logger.js +136 -0
  213. package/dist/esm/remotelog/send.d.ts +13 -0
  214. package/dist/esm/remotelog/send.js +149 -0
  215. package/dist/esm/scheduler.d.ts +8 -0
  216. package/dist/esm/scheduler.js +74 -0
  217. package/dist/esm/types.d.ts +312 -0
  218. package/dist/esm/user/index.d.ts +33 -0
  219. package/dist/esm/user/index.js +170 -0
  220. package/dist/feedback.esm.min.js +3 -0
  221. package/dist/feedback.esm.min.js.map +1 -0
  222. package/dist/heatmap.esm.min.js +3 -0
  223. package/dist/heatmap.esm.min.js.map +1 -0
  224. package/dist/style.css +1 -0
  225. package/package.json +124 -7
  226. package/src/appticssdk.js +0 -3817
@@ -0,0 +1,631 @@
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
2
+ 'use strict';
3
+
4
+ var constants = require('../core/constants.js');
5
+ var state = require('../core/state.js');
6
+ var logger = require('../core/logger.js');
7
+ var utils = require('../core/utils.js');
8
+ var consent = require('../core/consent.js');
9
+ var template = require('./template.js');
10
+ var send = require('./send.js');
11
+ var controls = require('./controls.js');
12
+
13
+ // Quartz is an optional page-level SDK. Without it every call is a no-op (fix #5).
14
+ const QUARTZ_NOOP = {
15
+ startRecording() { },
16
+ previewVideo() { },
17
+ editVideo() { },
18
+ clearFeedback() { },
19
+ endRecording() { },
20
+ setVideoContent() { },
21
+ submitRecording() { return Promise.resolve({}); }
22
+ };
23
+ const QUARTZ_CONSTANTS_NOOP = { ErrorType: {}, FeedbackState: {} };
24
+ function hasQuartz() {
25
+ return typeof Quartz !== 'undefined' && !!Quartz; // no i18n
26
+ }
27
+ function quartz() {
28
+ return typeof Quartz !== 'undefined' && Quartz ? Quartz : QUARTZ_NOOP; // no i18n
29
+ }
30
+ function quartzConstants() {
31
+ return typeof QuartzConstants !== 'undefined' && QuartzConstants ? QuartzConstants : QUARTZ_CONSTANTS_NOOP; // no i18n
32
+ }
33
+ /**
34
+ * Sends feedback and reflects the outcome in the modal (if open). Resolves with the outcome, or
35
+ * null when nothing was attempted (offline, or Apptics is disabled for this client).
36
+ */
37
+ function submitFeedback(dataobj) {
38
+ return send.sendFeedbackData(dataobj).then(function (result) {
39
+ if (!result) {
40
+ return null;
41
+ }
42
+ feedback.handleStatusmsg(result.ok, result.message);
43
+ if (result.ok) {
44
+ setTimeout(() => {
45
+ feedback.close();
46
+ }, 2000);
47
+ }
48
+ return result;
49
+ });
50
+ }
51
+ function sendFeedback(feedbackType, feedbackMessage, attachments, logsFiles, includeDyninfo, includeLog) {
52
+ const dataobj = {
53
+ type: !utils.isEmpty(feedbackType) ? feedbackType : 1,
54
+ message: feedbackMessage || '', // no i18n
55
+ attachment: attachments || null,
56
+ logsFiles: logsFiles || null,
57
+ // both flags stay as given: unset lets send.ts decide from what is actually stored
58
+ includeDyninfo: includeDyninfo,
59
+ includeLog: includeLog,
60
+ quartzid: '' // no i18n
61
+ };
62
+ // an app awaiting this must be able to tell its user the feedback did not go: resolving on a
63
+ // failure would have it say "thanks, sent" for a report the server never received
64
+ return submitFeedback(dataobj).then(function (result) {
65
+ if (!result) {
66
+ throw new Error('apptics.sendFeedback: not sent, the browser is offline or Apptics is disabled for this client'); // no i18n
67
+ }
68
+ if (!result.ok) {
69
+ throw new Error('apptics.sendFeedback: not sent, ' + result.message); // no i18n
70
+ }
71
+ });
72
+ }
73
+ /**
74
+ * The request both submit buttons send. A recording only adds its quartzid; everything else — the
75
+ * chosen type, the attachments, the log and diagnostics toggles — is read the same way, so one
76
+ * builder keeps the recording path from quietly falling behind the plain one.
77
+ */
78
+ function buildFeedbackRequest(modal, message, quartzid) {
79
+ var seltype = modal.querySelector('.zasdk-selected').getAttribute('data-type'); // no i18n
80
+ var fileInput = modal.querySelector("#zasdkFileInput"); // no i18n
81
+ var files = fileInput.files;
82
+ return {
83
+ type: !utils.isEmpty(seltype) ? feedback.typeObj[seltype] : 1,
84
+ message: message,
85
+ attachment: (files && files.length > 0) ? files : (feedback._opts.attachments || null),
86
+ logsFiles: feedback._opts.logFiles || null,
87
+ includeLog: controls.logChoice.includeLog,
88
+ includeDyninfo: controls.logChoice.includeDyninfo,
89
+ quartzid: quartzid
90
+ };
91
+ }
92
+ /**
93
+ * Opens the form, optionally pre-filled. `isAnonymous` starts the user picker on Anonymous even
94
+ * when a user is registered; the include flags start their toggles on.
95
+ */
96
+ /**
97
+ * A DataTransfer to hold the chosen attachments, or null where one cannot be made.
98
+ *
99
+ * It is the only way to build a FileList, which is what an <input type="file"> will accept back,
100
+ * so the attachment list is kept in one. The constructor is newer than the rest of the modal -
101
+ * Safari only gained it in 14.1 - and a plain `new DataTransfer()` throws on anything older,
102
+ * which took the whole form down with it on open. Feedback without attachments is worth far more
103
+ * than no feedback at all, so the form opens either way and the file input is left alone.
104
+ */
105
+ function newTransfer() {
106
+ try {
107
+ return typeof DataTransfer === 'function' ? new DataTransfer() : null; // no i18n
108
+ }
109
+ catch (err) {
110
+ logger.Console.warn('apptics.feedback: this browser cannot build a file list, attachments are off'); // no i18n
111
+ return null;
112
+ }
113
+ }
114
+ function feedbackOpen(type, message, includeLog, includeDyninfo, attachments, logFiles, isAnonymous) {
115
+ const opts = {
116
+ includeLog: includeLog === true,
117
+ includeDyninfo: includeDyninfo === true,
118
+ isAnonymous: isAnonymous === true,
119
+ };
120
+ if (typeof type === 'number')
121
+ opts.type = type; // no i18n
122
+ if (typeof message === 'string' && message.length > 0)
123
+ opts.message = message; // no i18n
124
+ if (attachments && attachments.length > 0)
125
+ opts.attachments = attachments;
126
+ if (logFiles && logFiles.length > 0)
127
+ opts.logFiles = logFiles;
128
+ feedback.init(opts);
129
+ }
130
+ function feedbackClose() {
131
+ feedback.close();
132
+ }
133
+ const feedback = {
134
+ feedbackUIHtml: template.feedbackUIHtml,
135
+ timerHtml: template.timerHtml,
136
+ uploadFileAry: [],
137
+ fileInput: null,
138
+ selectedFiles: null,
139
+ isScaled: false,
140
+ isHidden: false,
141
+ timerDisplay: null,
142
+ recordButton: null,
143
+ TOTAL_TIME: 5 * 60,
144
+ remainingTime: 5 * 60,
145
+ isRecording: false,
146
+ timerInterval: null,
147
+ uploadTotalSize: 0,
148
+ MaxFileSize: 10 * 1024 * 1024,
149
+ _opts: {},
150
+ typeObj: { 'bug': 0, 'feedback': 1, 'help': 2, 'report': 3 }, // no i18n
151
+ init: function (opts) {
152
+ feedback._opts = opts || {};
153
+ var modal = document.getElementById("zasdkFeedbackModal"); // no i18n
154
+ if (!utils.isEmpty(modal)) {
155
+ return;
156
+ }
157
+ const tempContainer = document.createElement('div'); // no i18n
158
+ feedback.uploadFileAry = [];
159
+ tempContainer.id = 'zasdkFeedbackModal'; // no i18n
160
+ tempContainer.className = 'zasdk-modal'; // no i18n
161
+ tempContainer.innerHTML = feedback.feedbackUIHtml;
162
+ document.body.appendChild(tempContainer);
163
+ var modal = document.getElementById("zasdkFeedbackModal"); // no i18n
164
+ var defaultoption = state._ZAP._defaultoptions;
165
+ var qz_ws_key = defaultoption.quartz_workspace_key;
166
+ var qz_dp_key = defaultoption.quartz_department_key;
167
+ var quartz_DC = {
168
+ "Local": "https://quartz.localzoho.com", // no i18n
169
+ "US": "https://quartz.zoho.com", // no i18n
170
+ "EU": "https://quartz.zoho.eu", // no i18n
171
+ "IN": "https://quartz.zoho.in", // no i18n
172
+ "AU": "https://quartz.zoho.com.au", // no i18n
173
+ "CN": "https://quartz.zoho.com.cn", // no i18n
174
+ "CA": "https://quartz.zohocloud.ca", // no i18n
175
+ "JP": "https://quartz.zoho.jp", // no i18n
176
+ "SA": "https://quartz.zoho.sa", // no i18n
177
+ "AE": "https://quartz.zoho.ae" // no i18n
178
+ };
179
+ var qz_dc_key = (!utils.isEmpty(defaultoption.DC) && defaultoption.DC !== '-') ? (quartz_DC[defaultoption.DC] || '') : ''; // no i18n
180
+ var closeBtn = modal.querySelector("#appticsfeedbackclose"); // no i18n
181
+ var feedbackTypes = modal.querySelectorAll(".zasdk-feedback-type"); // no i18n
182
+ feedback.fileInput = modal.querySelector("#zasdkFileInput"); // no i18n
183
+ var quartzrecbtn = modal.querySelector("#zasdkqz_rec_button"); // no i18n
184
+ var submitbtn = modal.querySelector("#zasdk_submit_btn"); // no i18n
185
+ var submitbtncnt = modal.querySelector("#zasdk_submit_btnsubcnt"); // no i18n
186
+ const checkbox = modal.querySelector('#zasdkqz-consent'); // no i18n
187
+ const content = modal.querySelector('#zasdkqz-content'); // no i18n
188
+ const preivewButton = modal.querySelector('#preivewPlayButton'); // no i18n
189
+ const videoEditButton = modal.querySelector('#videoEditButton'); // no i18n
190
+ const deleteVideoButton = modal.querySelector('#videoDelButton'); // no i18n
191
+ const feedbackbox = modal.querySelector('#zasdkFeedbackconatiner'); // no i18n
192
+ const descriptionField = modal.querySelector('#zasdkDescription'); // no i18n
193
+ controls.wireDrag(feedbackbox);
194
+ controls.wireUserPicker(modal, feedback._opts.isAnonymous === true);
195
+ controls.wireLogControls(modal, feedback._opts);
196
+ feedback.isScaled = false;
197
+ feedback.isHidden = false;
198
+ document.removeEventListener('quartz-feedback-state', feedback.bindQuartzEvent); // no i18n
199
+ document.addEventListener('quartz-feedback-state', feedback.bindQuartzEvent); // no i18n
200
+ document.removeEventListener('quartz-feedback-error', feedback.handleErrorQuartzEvent); // no i18n
201
+ document.addEventListener('quartz-feedback-error', feedback.handleErrorQuartzEvent); // no i18n
202
+ // the consent checkbox and its label only when a recording can actually be made: the Quartz
203
+ // script on the page, a DC it knows, and both keys. "-" for any of them turns it off; DC "-"
204
+ // has already become '' above. A checkbox that leads only to "unavailable" is not offered
205
+ var recordingAvailable = hasQuartz() && !utils.isEmpty(qz_dc_key)
206
+ && !utils.isEmpty(qz_ws_key) && qz_ws_key !== "-" && !utils.isEmpty(qz_dp_key) && qz_dp_key !== "-"; // no i18n
207
+ modal.querySelector("#zasdkreccheckcnt").style.display = recordingAvailable ? "block" : "none"; // no i18n
208
+ feedbackbox.addEventListener('transitionend', function (event) {
209
+ if (event.propertyName === 'transform' && feedback.isScaled) { // no i18n
210
+ feedback.toggleWindowAnimation();
211
+ }
212
+ });
213
+ quartzrecbtn.onclick = function (e) {
214
+ e.stopImmediatePropagation();
215
+ let recordingDetails = {
216
+ workspaceLinkName: qz_ws_key,
217
+ departmentLinkName: qz_dp_key,
218
+ recordingDomain: qz_dc_key
219
+ };
220
+ feedback.handleStatusmsg();
221
+ // 1.x pressed on regardless and the button did nothing anyone could explain; the rest
222
+ // of the form still works, so say what is missing and leave it usable
223
+ if (!hasQuartz()) {
224
+ feedback.handleStatusmsg(false, 'Screen recording is unavailable on this page.'); // no i18n
225
+ return;
226
+ }
227
+ if (utils.isEmpty(qz_ws_key) || utils.isEmpty(qz_dp_key) || utils.isEmpty(qz_dc_key)) {
228
+ feedback.handleStatusmsg(false, 'Screen recording is not configured for this app.'); // no i18n
229
+ return;
230
+ }
231
+ quartz().startRecording(recordingDetails);
232
+ };
233
+ closeBtn.onclick = function () {
234
+ feedback.close();
235
+ };
236
+ preivewButton.addEventListener('click', function () {
237
+ quartz().previewVideo();
238
+ });
239
+ videoEditButton.addEventListener('click', function () {
240
+ quartz().editVideo({ quartzBranding: false });
241
+ });
242
+ deleteVideoButton.addEventListener('click', function () {
243
+ var modal = document.getElementById("zasdkFeedbackModal"); // no i18n
244
+ quartz().clearFeedback();
245
+ checkbox.checked = false;
246
+ content.classList.remove('zasdkqz-show'); // no i18n
247
+ modal.querySelector("#editRecordedVideo").style.display = "none"; // no i18n
248
+ modal.querySelector("#zasdkreccheckcnt").style.display = "block"; // no i18n
249
+ feedback.validateFeedbackField();
250
+ });
251
+ submitbtn.addEventListener('click', async () => {
252
+ // Disable button and show loader
253
+ feedback.validateFeedbackField();
254
+ submitbtn.disabled = true;
255
+ submitbtncnt.classList.add('zasdkbtndisabled'); // no i18n
256
+ submitbtn.value = '';
257
+ try {
258
+ let videoElement = modal.querySelector('#previewVideoElemId'), // no i18n
259
+ videoVisible = videoElement && videoElement.offsetParent !== null;
260
+ if (videoVisible) {
261
+ feedback.submitRecording();
262
+ }
263
+ else {
264
+ let message = modal.querySelector('#zasdkDescription').value.trim(); // no i18n
265
+ if (message.length > 0) {
266
+ submitFeedback(buildFeedbackRequest(modal, message, '')); // no i18n
267
+ }
268
+ else {
269
+ feedback.handleStatusmsg(false, 'Please provide more details for us to help you better.'); // no i18n
270
+ }
271
+ }
272
+ }
273
+ catch (error) {
274
+ logger.Console.error("sendFeedbackData : " + error); // no i18n
275
+ }
276
+ });
277
+ checkbox.addEventListener('change', function () {
278
+ if (this.checked) {
279
+ content.classList.add('zasdkqz-show'); // no i18n
280
+ }
281
+ else {
282
+ content.classList.remove('zasdkqz-show'); // no i18n
283
+ }
284
+ });
285
+ descriptionField.addEventListener('input', feedback.validateFeedbackField); // no i18n
286
+ feedbackTypes.forEach(function (type) {
287
+ type.addEventListener("click", function () {
288
+ feedbackTypes.forEach(function (t) {
289
+ t.classList.remove("zasdk-selected"); // no i18n
290
+ });
291
+ this.classList.add("zasdk-selected"); // no i18n
292
+ });
293
+ });
294
+ // what feedbackOpen() was given: select that type, fill the description
295
+ if (typeof feedback._opts.type === 'number') { // no i18n
296
+ var wanted = Object.keys(feedback.typeObj).filter(function (name) {
297
+ return feedback.typeObj[name] === feedback._opts.type;
298
+ })[0];
299
+ var wantedTab = wanted ? modal.querySelector('.zasdk-feedback-type[data-type="' + wanted + '"]') : null; // no i18n
300
+ if (wantedTab) {
301
+ feedbackTypes.forEach(function (t) { t.classList.remove("zasdk-selected"); }); // no i18n
302
+ wantedTab.classList.add("zasdk-selected"); // no i18n
303
+ }
304
+ }
305
+ if (!utils.isEmpty(feedback._opts.message)) {
306
+ descriptionField.value = String(feedback._opts.message);
307
+ feedback.updateLeftCount();
308
+ feedback.validateFeedbackField();
309
+ }
310
+ feedback.selectedFiles = newTransfer();
311
+ feedback.fileInput.onchange = function () {
312
+ const self = this;
313
+ var chosen = feedback.selectedFiles;
314
+ if (chosen === null) {
315
+ return; // no file list on this browser; see newTransfer()
316
+ }
317
+ if (chosen.files.length + self.files.length > 5) {
318
+ feedback.handleStatusmsg(false, 'Maximum 5 attachments is allowed'); // no i18n
319
+ feedback.fileInput.files = chosen.files;
320
+ self.files = chosen.files;
321
+ return;
322
+ }
323
+ if (self.files.length > 0) {
324
+ let filesize = 0;
325
+ for (let file of self.files) {
326
+ filesize = filesize + file.size;
327
+ if (filesize > 10485760) {
328
+ feedback.handleStatusmsg(false, 'Maximum limit reached. The total file size cannot exceed 10MB.'); // no i18n
329
+ self.files = chosen.files;
330
+ return;
331
+ }
332
+ else {
333
+ chosen.items.add(file); // Add new files
334
+ }
335
+ }
336
+ self.files = chosen.files; // Update input with all files
337
+ feedback.fileAttachment(); // Update UI
338
+ }
339
+ else if (chosen.files.length > 0) {
340
+ // Restore previous files if the user cancels
341
+ self.files = chosen.files;
342
+ }
343
+ };
344
+ feedback.handleStatusmsg();
345
+ feedback.updateLeftCount();
346
+ },
347
+ updateLeftCount: function () {
348
+ document.querySelectorAll("[reqname]").forEach(function (elem) {
349
+ let val = elem.value;
350
+ let maxLength = parseInt(elem.getAttribute("maxlength") || '', 10); // no i18n
351
+ let counterElem = elem.parentElement ? elem.parentElement.querySelector(".zaleftcharcnt") : null; // no i18n
352
+ if (counterElem) {
353
+ counterElem.textContent = String(maxLength - val.length); // Update remaining count
354
+ }
355
+ });
356
+ },
357
+ handleStatusmsg: function (isSuccess, stsmsg) {
358
+ var modal = document.getElementById("zasdkFeedbackModal"); // no i18n
359
+ if (utils.isEmpty(modal)) {
360
+ return;
361
+ }
362
+ var stscnt = modal.querySelector("#zasdksubmitstatus"); // no i18n
363
+ var submitbtn = modal.querySelector("#zasdk_submit_btn"); // no i18n
364
+ var submitbtncnt = modal.querySelector("#zasdk_submit_btnsubcnt"); // no i18n
365
+ var successmsgclass = ''; // no i18n
366
+ var successmsg = ''; // no i18n
367
+ stscnt.style.display = "none"; // no i18n
368
+ if (!utils.isEmpty(isSuccess)) {
369
+ successmsgclass = isSuccess ? 'zasdkstssucs' : 'zasdkstserror'; // no i18n
370
+ successmsg = !utils.isEmpty(stsmsg) ? stsmsg : ''; // no i18n
371
+ stscnt.textContent = successmsg;
372
+ stscnt.classList.add(successmsgclass);
373
+ stscnt.style.display = "block"; // no i18n
374
+ submitbtncnt.classList.remove('zasdkbtndisabled'); // no i18n
375
+ submitbtn.disabled = false;
376
+ submitbtn.value = 'Send'; // no i18n
377
+ }
378
+ },
379
+ handleErrorQuartzEvent: function (event) {
380
+ let errorType = event.detail.error.name;
381
+ let errorMessage = event.detail.error.message;
382
+ if (errorType == quartzConstants().ErrorType.RECORDING_INTERRUPTED || errorType == quartzConstants().ErrorType.FEEDBACK_TIMEOUT) {
383
+ feedback.stopRecording();
384
+ }
385
+ feedback.handleStatusmsg(false, errorMessage);
386
+ },
387
+ bindQuartzEvent: function (event) {
388
+ let feedbackState = event.detail.feedbackState;
389
+ if (feedbackState == quartzConstants().FeedbackState.RECORDING_IN_PROGRESS) {
390
+ var feedbacktimer = document.getElementById("zasdkrectimer"); // no i18n
391
+ if (!utils.isEmpty(feedbacktimer)) {
392
+ feedbacktimer.remove();
393
+ }
394
+ const tempDiv = document.createElement("div"); // no i18n
395
+ tempDiv.innerHTML = feedback.timerHtml;
396
+ const node = tempDiv.firstElementChild;
397
+ document.body.appendChild(node);
398
+ var feedbacktimer = document.getElementById("zasdkrectimer"); // no i18n
399
+ feedback.timerDisplay = feedbacktimer.querySelector('#zasdkTimerDisplay'); // no i18n
400
+ feedback.recordButton = feedbacktimer;
401
+ feedback.TOTAL_TIME = 5 * 60; // 5 minutes in seconds
402
+ feedback.remainingTime = feedback.TOTAL_TIME;
403
+ feedback.isRecording = true;
404
+ feedback.recordButton.addEventListener('click', feedback.toggleRecording); // no i18n
405
+ feedback.startRecording();
406
+ feedback.toggleWindowAnimation();
407
+ }
408
+ },
409
+ close: function () {
410
+ var modal = document.getElementById("zasdkFeedbackModal"); // no i18n
411
+ document.removeEventListener('quartz-feedback-state', feedback.bindQuartzEvent); // no i18n
412
+ quartz().clearFeedback();
413
+ if (!utils.isEmpty(modal)) {
414
+ modal.remove();
415
+ }
416
+ },
417
+ toggleWindowAnimation: function () {
418
+ var modal = document.getElementById("zasdkFeedbackModal"); // no i18n
419
+ const box = modal.querySelector('#zasdkFeedbackconatiner'); // no i18n
420
+ if (feedback.isHidden) {
421
+ modal.style.display = 'block'; // no i18n
422
+ setTimeout(() => {
423
+ box.style.transform = 'scale(1)'; // no i18n
424
+ feedback.validateFeedbackField();
425
+ }, 10);
426
+ feedback.isHidden = false;
427
+ feedback.isScaled = false;
428
+ }
429
+ else if (feedback.isScaled) {
430
+ modal.style.display = 'none'; // no i18n
431
+ feedback.isHidden = true;
432
+ }
433
+ else {
434
+ box.style.transform = 'scale(0)'; // no i18n
435
+ feedback.isScaled = true;
436
+ }
437
+ },
438
+ fileAttachment: function () {
439
+ var uploadedFiles = feedback.fileInput.files;
440
+ feedback.uploadTotalSize = 0;
441
+ feedback.MaxFileSize = 10 * 1024 * 1024; //10 MB
442
+ var modal = document.getElementById("zasdkFeedbackModal"); // no i18n
443
+ var sizeInfo = modal.querySelector("#zasdkfilesizeinfo"); // no i18n
444
+ var fileUl = modal.querySelector("#zasakfileList"); // no i18n
445
+ sizeInfo.textContent = ""; // no i18n
446
+ if ((uploadedFiles.length) > 5) {
447
+ feedback.fileLimitExceeded(false, true);
448
+ feedback.validateFeedbackField();
449
+ return;
450
+ }
451
+ fileUl.innerHTML = ''; // no i18n
452
+ if (uploadedFiles.length > 0) {
453
+ var totalSize = 0;
454
+ for (var i = 0; i < uploadedFiles.length; i++) {
455
+ var fileName = uploadedFiles[i].name;
456
+ var fName = fileName.substring(0, fileName.lastIndexOf('.')); // no i18n
457
+ var extension = fileName.substring(fileName.lastIndexOf('.') + 1); // no i18n
458
+ var bytes = uploadedFiles[i].size;
459
+ totalSize += bytes;
460
+ var fileLi = feedback.elementCreator("li"); // no i18n
461
+ fileLi.title = fileName;
462
+ var span1 = feedback.elementCreator("span"); // no i18n
463
+ span1.className = "zaskFdBckFlName"; // no i18n
464
+ span1.innerText = (fName.length > 10) ? fName.slice(0, 3) + "..." + fName.slice(-3) : fName; // no i18n
465
+ var span2 = feedback.elementCreator("span"); // no i18n
466
+ span2.innerText = "." + extension; // no i18n
467
+ var span3 = feedback.elementCreator("span"); // no i18n
468
+ span3.className = "zasdkFdBckFlCls"; // no i18n
469
+ span3.setAttribute("data-name", fileName); // no i18n
470
+ span3.innerHTML = "&times;"; // no i18N
471
+ fileLi.appendChild(span1);
472
+ fileLi.appendChild(span2);
473
+ fileLi.appendChild(span3);
474
+ fileUl.appendChild(fileLi);
475
+ }
476
+ var limitReached = totalSize > feedback.MaxFileSize;
477
+ feedback.fileLimitExceeded(limitReached);
478
+ sizeInfo.textContent = `${feedback.formatFileSize(totalSize)} Used / 10 MB`; // no i18n
479
+ const clearFile = modal.querySelectorAll('.zasdkFdBckFlCls'); // no i18n
480
+ Array.from(clearFile).forEach(function (element) {
481
+ element.addEventListener('click', function () {
482
+ feedback.handleStatusmsg();
483
+ feedback.removeFileFromList(this);
484
+ feedback.fileAttachment();
485
+ });
486
+ });
487
+ }
488
+ feedback.validateFeedbackField();
489
+ },
490
+ elementCreator: function (elType) {
491
+ return document.createElement(elType);
492
+ },
493
+ fileLimitExceeded: function (limitReached, filesLengthReached) {
494
+ var infoMsg = "";
495
+ if (filesLengthReached || limitReached) {
496
+ infoMsg = filesLengthReached ? 'Maximum 5 attachments is allowed' : 'Maximum limit reached. The total file size cannot exceed 10MB.'; // no i18n
497
+ }
498
+ feedback.handleStatusmsg(false, infoMsg);
499
+ },
500
+ removeFileFromList: function (elem) {
501
+ elem.getAttribute('data-name'); // no i18n
502
+ const listItem = elem.parentElement; // the <li> holding this file
503
+ // Find the index of the element in the file preview list
504
+ const indexToRemove = Array.from(listItem.parentElement.children).indexOf(listItem);
505
+ listItem.remove(); // Remove the file preview
506
+ let newFiles = newTransfer();
507
+ feedback.selectedFiles = newTransfer();
508
+ if (newFiles === null || feedback.selectedFiles === null) {
509
+ return; // no file list to rebuild; the preview row is already gone
510
+ }
511
+ for (let i = 0; i < feedback.fileInput.files.length; i++) {
512
+ if (i !== indexToRemove) {
513
+ newFiles.items.add(feedback.fileInput.files[i]);
514
+ feedback.selectedFiles.items.add(feedback.fileInput.files[i]);
515
+ }
516
+ }
517
+ feedback.fileInput.files = newFiles.files;
518
+ },
519
+ formatFileSize: function (bytes) {
520
+ if (bytes === 0)
521
+ return '0 KB'; // no i18n
522
+ const k = 1024;
523
+ const sizeInKB = bytes / k;
524
+ const sizeInMB = bytes / (k * k);
525
+ const sizeInGB = bytes / (k * k * k);
526
+ if (sizeInGB >= 1) {
527
+ return sizeInGB.toFixed(2) + ' GB'; // no i18n
528
+ }
529
+ else if (sizeInMB >= 1) {
530
+ return sizeInMB.toFixed(2) + ' MB'; // no i18n
531
+ }
532
+ else {
533
+ return sizeInKB.toFixed(2) + ' KB'; // no i18n
534
+ }
535
+ },
536
+ toggleRecording: function () {
537
+ feedback.isRecording = !feedback.isRecording;
538
+ if (feedback.isRecording) {
539
+ feedback.startRecording();
540
+ }
541
+ else {
542
+ feedback.stopRecording();
543
+ }
544
+ },
545
+ startRecording: function () {
546
+ if (!feedback.timerInterval) {
547
+ feedback.timerInterval = setInterval(feedback.updateTimer, 1000);
548
+ }
549
+ },
550
+ stopRecording: function () {
551
+ var modal = document.getElementById("zasdkFeedbackModal"); // no i18n
552
+ clearInterval(feedback.timerInterval || undefined);
553
+ feedback.timerInterval = null;
554
+ document.querySelector("#zasdkrectimer").remove(); // no i18n
555
+ feedback.toggleWindowAnimation();
556
+ modal.querySelector("#editRecordedVideo").style.display = "block"; // no i18n
557
+ modal.querySelector("#zasdkreccheckcnt").style.display = "none"; // no i18n
558
+ let videoElem = modal.querySelector('#previewVideoElemId'); // no i18n
559
+ quartz().endRecording();
560
+ quartz().setVideoContent(videoElem);
561
+ },
562
+ submitRecording: function () {
563
+ var modal = document.getElementById("zasdkFeedbackModal"); // no i18n
564
+ // the recording is filed for whoever the form's picker selected, falling back to the
565
+ // registered user; an anonymous report, a non-email id or a PII opt-out all send the
566
+ // placeholder instead, so Quartz never receives an address the user did not offer
567
+ let testEmail = 'user@example.com', // no i18n
568
+ testMessage = '-', picked = controls.userChoice.anonymous ? '' : String(controls.userChoice.userid || ''), // no i18n
569
+ active = !utils.isEmpty(state._ZAP._user_info.userid) ? String(state._ZAP._user_info.userid) : '', // no i18n
570
+ userEmail = !utils.isEmpty(picked) ? picked : active, subject = modal.querySelector('#zasdkDescription').value.trim() || testMessage, // no i18n
571
+ emailRegex = /^[\w]([\w\-\.\+\'=]*)@([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,22}$/;
572
+ userEmail = (emailRegex.test(userEmail) && consent.opt_in_status() == constants.AP_TRACKING_STATUS.USAGE_TRACKING_WITH_PII) ? userEmail : testEmail;
573
+ // Submit the recording
574
+ quartz().submitRecording({
575
+ email: userEmail,
576
+ subject: subject,
577
+ })
578
+ .then((response) => {
579
+ var zqrecid = !utils.isEmptyObj(response) && response && response.hasOwnProperty('feedbackLink') ? (response.feedbackLink || '') : ''; // no i18n
580
+ submitFeedback(buildFeedbackRequest(modal, subject, zqrecid));
581
+ })
582
+ .catch((error) => {
583
+ // the upload is Quartz's to do; if it fails, hand the form back rather than leaving
584
+ // the submit button spinning with nothing said
585
+ logger.Console.error("submitRecording : " + error); // no i18n
586
+ feedback.handleStatusmsg(false, 'Could not upload the recording. Please try again.'); // no i18n
587
+ });
588
+ },
589
+ updateTimer: function () {
590
+ if (feedback.remainingTime > 0) {
591
+ feedback.remainingTime--;
592
+ feedback.updateDisplay();
593
+ }
594
+ else {
595
+ feedback.stopRecording();
596
+ }
597
+ },
598
+ updateDisplay: function () {
599
+ const minutes = Math.floor(feedback.remainingTime / 60);
600
+ const seconds = feedback.remainingTime % 60;
601
+ feedback.timerDisplay.textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; // no i18n
602
+ },
603
+ validateFeedbackField: function () {
604
+ feedback.updateLeftCount();
605
+ var modal = document.getElementById("zasdkFeedbackModal"); // no i18n
606
+ const descriptionField = modal.querySelector('#zasdkDescription'); // no i18n
607
+ const attachmentField = modal.querySelector('#zasdkFileInput'); // no i18n
608
+ const videoElement = modal.querySelector('#previewVideoElemId'); // no i18n
609
+ const sendButton = modal.querySelector('#zasdk_submit_btn'); // no i18n
610
+ const descriptionFilled = descriptionField && descriptionField.value.trim() !== '' && descriptionField.value.trim().length > 0; // no i18n
611
+ attachmentField && attachmentField.files && attachmentField.files.length > 0;
612
+ videoElement && videoElement.offsetParent !== null; // Check if visible
613
+ const errorElements = modal.querySelectorAll('.zasdkmaxerror'); // no i18n
614
+ const hasErrors = feedback.getVisibleErrorCount(errorElements) > 0;
615
+ if (!hasErrors && descriptionFilled) {
616
+ sendButton.classList.remove('zasdkbtndisableclr'); // no i18n
617
+ feedback.handleStatusmsg();
618
+ }
619
+ else {
620
+ sendButton.classList.add('zasdkbtndisableclr'); // no i18n
621
+ }
622
+ },
623
+ getVisibleErrorCount: function (elements) {
624
+ return Array.from(elements).filter(element => element.offsetParent !== null).length;
625
+ }
626
+ };
627
+
628
+ exports.feedback = feedback;
629
+ exports.feedbackClose = feedbackClose;
630
+ exports.feedbackOpen = feedbackOpen;
631
+ exports.sendFeedback = sendFeedback;
@@ -0,0 +1,16 @@
1
+ import { enableHeatmap as enableHeatmapImpl } from './track.js';
2
+ import './send.js';
3
+ /**
4
+ * Heatmap capture, from '@zoho_apptics/apptics-js-sdk/heatmap'.
5
+ *
6
+ * Its own entry point, like the feedback modal: an app that does not want heatmaps ships none of
7
+ * this. Importing it is what makes `track_heatmap: true` do anything — the config flag on its own
8
+ * has nothing to switch on.
9
+ */
10
+ /** Starts or stops recording clicks and scrolls. */
11
+ export declare const enableHeatmap: typeof enableHeatmapImpl;
12
+ export type { HeatmapRecord } from '../types.js';
13
+ declare const heatmap: {
14
+ enableHeatmap: typeof enableHeatmapImpl;
15
+ };
16
+ export default heatmap;
@@ -0,0 +1,22 @@
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var guard = require('../core/guard.js');
7
+ var track = require('./track.js');
8
+ require('./send.js');
9
+
10
+ /**
11
+ * Heatmap capture, from '@zoho_apptics/apptics-js-sdk/heatmap'.
12
+ *
13
+ * Its own entry point, like the feedback modal: an app that does not want heatmaps ships none of
14
+ * this. Importing it is what makes `track_heatmap: true` do anything — the config flag on its own
15
+ * has nothing to switch on.
16
+ */
17
+ /** Starts or stops recording clicks and scrolls. */
18
+ const enableHeatmap = guard.guard('enableHeatmap', track.enableHeatmap); // no i18n
19
+ const heatmap = { enableHeatmap };
20
+
21
+ exports.default = heatmap;
22
+ exports.enableHeatmap = enableHeatmap;