@robotical/webapp-types 3.16.16 → 3.16.18
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/dist-types/src/components/modals/DetailedFeedbackModal/index.js +9 -2
- package/dist-types/src/utils/feedback/feedbackConnectionEligibility.d.ts +22 -0
- package/dist-types/src/utils/feedback/feedbackConnectionEligibility.js +90 -0
- package/dist-types/src/utils/feedback/submitFeedback.js +37 -12
- package/package.json +1 -1
|
@@ -51,6 +51,7 @@ import { useTranslation } from "react-i18next";
|
|
|
51
51
|
import modalState from "../../../state-observables/modal/ModalState";
|
|
52
52
|
import { submitFeedback, } from "../../../utils/feedback/submitFeedback";
|
|
53
53
|
import { getFeedbackPromptPageFromContext, markFeedbackPromptSubmitted, } from "../../../utils/feedback/feedbackPromptPolicy";
|
|
54
|
+
import { FEEDBACK_REQUIRES_ROBOT_CONNECTION_MESSAGE } from "../../../utils/feedback/feedbackConnectionEligibility";
|
|
54
55
|
import styles from "./styles.module.css";
|
|
55
56
|
import SimpleButton from "../../disposables/buttons/SimpleButton";
|
|
56
57
|
export default function DetailedFeedbackModal(_a) {
|
|
@@ -89,7 +90,10 @@ export default function DetailedFeedbackModal(_a) {
|
|
|
89
90
|
return [2 /*return*/, true];
|
|
90
91
|
case 3:
|
|
91
92
|
error_1 = _c.sent();
|
|
92
|
-
(_b = (_a = window.applicationManager) === null || _a === void 0 ? void 0 : _a.toaster) === null || _b === void 0 ? void 0 : _b.error(
|
|
93
|
+
(_b = (_a = window.applicationManager) === null || _a === void 0 ? void 0 : _a.toaster) === null || _b === void 0 ? void 0 : _b.error(error_1 instanceof Error &&
|
|
94
|
+
error_1.message === FEEDBACK_REQUIRES_ROBOT_CONNECTION_MESSAGE
|
|
95
|
+
? FEEDBACK_REQUIRES_ROBOT_CONNECTION_MESSAGE
|
|
96
|
+
: "There was an error sending your feedback. Please try again later.");
|
|
93
97
|
return [2 /*return*/, false];
|
|
94
98
|
case 4: return [2 /*return*/];
|
|
95
99
|
}
|
|
@@ -156,7 +160,10 @@ export default function DetailedFeedbackModal(_a) {
|
|
|
156
160
|
return [3 /*break*/, 5];
|
|
157
161
|
case 3:
|
|
158
162
|
error_2 = _c.sent();
|
|
159
|
-
(_b = (_a = window.applicationManager) === null || _a === void 0 ? void 0 : _a.toaster) === null || _b === void 0 ? void 0 : _b.error(
|
|
163
|
+
(_b = (_a = window.applicationManager) === null || _a === void 0 ? void 0 : _a.toaster) === null || _b === void 0 ? void 0 : _b.error(error_2 instanceof Error &&
|
|
164
|
+
error_2.message === FEEDBACK_REQUIRES_ROBOT_CONNECTION_MESSAGE
|
|
165
|
+
? FEEDBACK_REQUIRES_ROBOT_CONNECTION_MESSAGE
|
|
166
|
+
: "There was an error sending your feedback. Please try again later.");
|
|
160
167
|
return [3 /*break*/, 5];
|
|
161
168
|
case 4:
|
|
162
169
|
setIsSubmitting(false);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { RaftTypeE } from "../../types/raft";
|
|
2
|
+
type ApplicationManagerWithConnections = {
|
|
3
|
+
connectedRafts?: Record<string, ConnectedRaftEntity | undefined>;
|
|
4
|
+
connectedRaftsContext?: Array<{
|
|
5
|
+
id?: string;
|
|
6
|
+
type?: RaftTypeE;
|
|
7
|
+
isSelected?: boolean;
|
|
8
|
+
}>;
|
|
9
|
+
};
|
|
10
|
+
type ConnectedRaftEntity = {
|
|
11
|
+
type?: RaftTypeE;
|
|
12
|
+
getSerialNumber?: () => string;
|
|
13
|
+
};
|
|
14
|
+
export type FeedbackRobotConnectionDetails = {
|
|
15
|
+
selectedRaftType: RaftTypeE.MARTY | RaftTypeE.COG;
|
|
16
|
+
selectedRaftSerialNumber: string | null;
|
|
17
|
+
};
|
|
18
|
+
export declare const FEEDBACK_REQUIRES_ROBOT_CONNECTION_MESSAGE = "Please connect to a robot before sending feedback.";
|
|
19
|
+
export declare function hasActiveRobotConnection(applicationManager?: ApplicationManagerWithConnections | undefined): boolean;
|
|
20
|
+
export declare function getActiveFeedbackRobotConnection(applicationManager?: ApplicationManagerWithConnections | undefined): FeedbackRobotConnectionDetails | null;
|
|
21
|
+
export declare function isRobotConnectionRequiredForFeedbackSource(source: string): boolean;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { RaftTypeE } from "../../types/raft";
|
|
2
|
+
export var FEEDBACK_REQUIRES_ROBOT_CONNECTION_MESSAGE = "Please connect to a robot before sending feedback.";
|
|
3
|
+
function getApplicationManager() {
|
|
4
|
+
if (typeof window === "undefined") {
|
|
5
|
+
return undefined;
|
|
6
|
+
}
|
|
7
|
+
return window.applicationManager;
|
|
8
|
+
}
|
|
9
|
+
export function hasActiveRobotConnection(applicationManager) {
|
|
10
|
+
if (applicationManager === void 0) { applicationManager = getApplicationManager(); }
|
|
11
|
+
return getActiveFeedbackRobotConnection(applicationManager) !== null;
|
|
12
|
+
}
|
|
13
|
+
function isFeedbackRobotType(raftType) {
|
|
14
|
+
return raftType === RaftTypeE.MARTY || raftType === RaftTypeE.COG;
|
|
15
|
+
}
|
|
16
|
+
function normalizeSerialNumber(serialNumber) {
|
|
17
|
+
return typeof serialNumber === "string" && serialNumber.trim()
|
|
18
|
+
? serialNumber.trim()
|
|
19
|
+
: null;
|
|
20
|
+
}
|
|
21
|
+
function getRaftSerialNumber(connectedRaft) {
|
|
22
|
+
var _a;
|
|
23
|
+
try {
|
|
24
|
+
return normalizeSerialNumber((_a = connectedRaft === null || connectedRaft === void 0 ? void 0 : connectedRaft.getSerialNumber) === null || _a === void 0 ? void 0 : _a.call(connectedRaft));
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function getConnectionDetails(raftType, connectedRaft) {
|
|
31
|
+
var selectedRaftType = isFeedbackRobotType(raftType)
|
|
32
|
+
? raftType
|
|
33
|
+
: connectedRaft === null || connectedRaft === void 0 ? void 0 : connectedRaft.type;
|
|
34
|
+
if (!isFeedbackRobotType(selectedRaftType)) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
selectedRaftType: selectedRaftType,
|
|
39
|
+
selectedRaftSerialNumber: getRaftSerialNumber(connectedRaft),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export function getActiveFeedbackRobotConnection(applicationManager) {
|
|
43
|
+
if (applicationManager === void 0) { applicationManager = getApplicationManager(); }
|
|
44
|
+
var connectedRafts = applicationManager === null || applicationManager === void 0 ? void 0 : applicationManager.connectedRafts;
|
|
45
|
+
if (!connectedRafts || typeof connectedRafts !== "object") {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
var connectedRaftEntries = Object.entries(connectedRafts).filter(function (_a) {
|
|
49
|
+
var connectedRaft = _a[1];
|
|
50
|
+
return Boolean(connectedRaft);
|
|
51
|
+
});
|
|
52
|
+
if (connectedRaftEntries.length === 0) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
var connectedRaftsContext = applicationManager === null || applicationManager === void 0 ? void 0 : applicationManager.connectedRaftsContext;
|
|
56
|
+
if (Array.isArray(connectedRaftsContext)) {
|
|
57
|
+
var selectedRaft = connectedRaftsContext.find(function (connectedRaft) {
|
|
58
|
+
return Boolean(connectedRaft.id &&
|
|
59
|
+
connectedRaft.isSelected &&
|
|
60
|
+
connectedRafts[connectedRaft.id]);
|
|
61
|
+
});
|
|
62
|
+
var selectedDetails = selectedRaft
|
|
63
|
+
? getConnectionDetails(selectedRaft.type, selectedRaft.id ? connectedRafts[selectedRaft.id] : undefined)
|
|
64
|
+
: null;
|
|
65
|
+
if (selectedDetails) {
|
|
66
|
+
return selectedDetails;
|
|
67
|
+
}
|
|
68
|
+
for (var _i = 0, connectedRaftsContext_1 = connectedRaftsContext; _i < connectedRaftsContext_1.length; _i++) {
|
|
69
|
+
var connectedRaft = connectedRaftsContext_1[_i];
|
|
70
|
+
if (!connectedRaft.id || !connectedRafts[connectedRaft.id]) {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
var details = getConnectionDetails(connectedRaft.type, connectedRafts[connectedRaft.id]);
|
|
74
|
+
if (details) {
|
|
75
|
+
return details;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
for (var _a = 0, connectedRaftEntries_1 = connectedRaftEntries; _a < connectedRaftEntries_1.length; _a++) {
|
|
80
|
+
var _b = connectedRaftEntries_1[_a], connectedRaft = _b[1];
|
|
81
|
+
var details = getConnectionDetails(connectedRaft === null || connectedRaft === void 0 ? void 0 : connectedRaft.type, connectedRaft);
|
|
82
|
+
if (details) {
|
|
83
|
+
return details;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
export function isRobotConnectionRequiredForFeedbackSource(source) {
|
|
89
|
+
return source === "emoji-modal" || source === "detailed-feedback";
|
|
90
|
+
}
|
|
@@ -46,6 +46,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
46
46
|
}
|
|
47
47
|
};
|
|
48
48
|
import Logger from "../../services/logger/Logger";
|
|
49
|
+
import { FEEDBACK_REQUIRES_ROBOT_CONNECTION_MESSAGE, getActiveFeedbackRobotConnection, isRobotConnectionRequiredForFeedbackSource, } from "./feedbackConnectionEligibility";
|
|
49
50
|
import randomHashGenerator from "../helpers/randomHashGenerator";
|
|
50
51
|
import isPhoneApp from "../phone-app-communication/is-phone-app";
|
|
51
52
|
var SHOW_LOGS = true;
|
|
@@ -171,13 +172,28 @@ export function buildFeedbackText(record) {
|
|
|
171
172
|
var page = record.context && typeof record.context.page === "string"
|
|
172
173
|
? record.context.page
|
|
173
174
|
: null;
|
|
175
|
+
var selectedRaftType = record.context && typeof record.context.selectedRaftType === "string"
|
|
176
|
+
? record.context.selectedRaftType
|
|
177
|
+
: null;
|
|
178
|
+
var selectedRaftSerialNumber = record.context &&
|
|
179
|
+
typeof record.context.selectedRaftSerialNumber === "string"
|
|
180
|
+
? record.context.selectedRaftSerialNumber
|
|
181
|
+
: null;
|
|
174
182
|
if (page) {
|
|
175
183
|
lines.push("Page: ".concat(page));
|
|
176
184
|
}
|
|
185
|
+
if (selectedRaftType) {
|
|
186
|
+
lines.push("Robot type: ".concat(selectedRaftType));
|
|
187
|
+
}
|
|
188
|
+
if (selectedRaftSerialNumber) {
|
|
189
|
+
lines.push("Robot serial number: ".concat(selectedRaftSerialNumber));
|
|
190
|
+
}
|
|
177
191
|
if (record.context) {
|
|
178
192
|
var contextWithoutPage = Object.fromEntries(Object.entries(record.context).filter(function (_a) {
|
|
179
193
|
var key = _a[0];
|
|
180
|
-
return key !== "page"
|
|
194
|
+
return key !== "page" &&
|
|
195
|
+
key !== "selectedRaftType" &&
|
|
196
|
+
key !== "selectedRaftSerialNumber";
|
|
181
197
|
}));
|
|
182
198
|
if (Object.keys(contextWithoutPage).length > 0) {
|
|
183
199
|
lines.push("Context: ".concat(JSON.stringify(contextWithoutPage)));
|
|
@@ -212,12 +228,21 @@ export function createFeedbackRecord(input) {
|
|
|
212
228
|
return record;
|
|
213
229
|
}
|
|
214
230
|
export function submitFeedback(input) {
|
|
231
|
+
var _a;
|
|
215
232
|
return __awaiter(this, void 0, void 0, function () {
|
|
216
|
-
var record, firebaseResponse, errorText, slackDelivered, slackResponse, errorText, error_1;
|
|
217
|
-
return __generator(this, function (
|
|
218
|
-
switch (
|
|
233
|
+
var requiresRobotConnection, robotConnection, record, firebaseResponse, errorText, slackDelivered, slackResponse, errorText, error_1;
|
|
234
|
+
return __generator(this, function (_b) {
|
|
235
|
+
switch (_b.label) {
|
|
219
236
|
case 0:
|
|
220
|
-
|
|
237
|
+
requiresRobotConnection = isRobotConnectionRequiredForFeedbackSource(input.source);
|
|
238
|
+
robotConnection = requiresRobotConnection
|
|
239
|
+
? getActiveFeedbackRobotConnection()
|
|
240
|
+
: null;
|
|
241
|
+
if (requiresRobotConnection && !robotConnection) {
|
|
242
|
+
throw new Error(FEEDBACK_REQUIRES_ROBOT_CONNECTION_MESSAGE);
|
|
243
|
+
}
|
|
244
|
+
record = createFeedbackRecord(__assign(__assign({}, input), { context: robotConnection
|
|
245
|
+
? __assign(__assign({}, ((_a = input.context) !== null && _a !== void 0 ? _a : {})), robotConnection) : input.context }));
|
|
221
246
|
return [4 /*yield*/, fetch("".concat(WEB_APP_FEEDBACK_DB_URL).concat(randomHashGenerator(), ".json"), {
|
|
222
247
|
method: "PATCH",
|
|
223
248
|
headers: {
|
|
@@ -227,18 +252,18 @@ export function submitFeedback(input) {
|
|
|
227
252
|
body: JSON.stringify(record),
|
|
228
253
|
})];
|
|
229
254
|
case 1:
|
|
230
|
-
firebaseResponse =
|
|
255
|
+
firebaseResponse = _b.sent();
|
|
231
256
|
if (!!firebaseResponse.ok) return [3 /*break*/, 3];
|
|
232
257
|
return [4 /*yield*/, firebaseResponse.text()];
|
|
233
258
|
case 2:
|
|
234
|
-
errorText =
|
|
259
|
+
errorText = _b.sent();
|
|
235
260
|
Logger.error(SHOW_LOGS, TAG, "Failed to submit feedback to Firebase: ".concat(firebaseResponse.status, " ").concat(errorText));
|
|
236
261
|
throw new Error("Failed to submit feedback");
|
|
237
262
|
case 3:
|
|
238
263
|
slackDelivered = true;
|
|
239
|
-
|
|
264
|
+
_b.label = 4;
|
|
240
265
|
case 4:
|
|
241
|
-
|
|
266
|
+
_b.trys.push([4, 8, , 9]);
|
|
242
267
|
return [4 /*yield*/, fetch(WEB_APP_FEEDBACK_SLACK_WEBHOOK_URL, {
|
|
243
268
|
method: "POST",
|
|
244
269
|
headers: {
|
|
@@ -247,15 +272,15 @@ export function submitFeedback(input) {
|
|
|
247
272
|
body: JSON.stringify({ text: record.text }),
|
|
248
273
|
})];
|
|
249
274
|
case 5:
|
|
250
|
-
slackResponse =
|
|
275
|
+
slackResponse = _b.sent();
|
|
251
276
|
if (!!slackResponse.ok) return [3 /*break*/, 7];
|
|
252
277
|
return [4 /*yield*/, slackResponse.text()];
|
|
253
278
|
case 6:
|
|
254
|
-
errorText =
|
|
279
|
+
errorText = _b.sent();
|
|
255
280
|
throw new Error("Failed Slack response: ".concat(slackResponse.status, " ").concat(errorText));
|
|
256
281
|
case 7: return [3 /*break*/, 9];
|
|
257
282
|
case 8:
|
|
258
|
-
error_1 =
|
|
283
|
+
error_1 = _b.sent();
|
|
259
284
|
slackDelivered = false;
|
|
260
285
|
Logger.error(SHOW_LOGS, TAG, "Failed to submit feedback to Slack", error_1);
|
|
261
286
|
return [3 /*break*/, 9];
|