@atlaskit/feedback-collector 7.1.1 → 7.1.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # @atlaskit/feedback-collector
2
2
 
3
+ ## 7.1.2
4
+
5
+ ### Major Changes
6
+
7
+ - [`be25f4abde4`](https://bitbucket.org/atlassian/atlassian-frontend/commits/be25f4abde4) - ## Breaking Changes
8
+
9
+ The new `cookie` property is **required**. This is property is a simple string of the user's cloud session token. Please pass in the entire key/value pair of the cookie. Like:
10
+
11
+ ```html
12
+ <FeedbackCollector cookie={"cloud.session.token=...."} >
13
+ ```
14
+
15
+ This is used for getting Entitlement information about the user (used in feedback analysis) and for validating identities (see [VULN-229258](https://asecurityteam.atlassian.net/browse/VULN-229258))
16
+
17
+ ## Other changes
18
+
19
+ - Uses new Feedback Collector API for data analysis
20
+ - Data encoding
21
+
22
+ ### Patch Changes
23
+
24
+ - [`f460cc7c411`](https://bitbucket.org/atlassian/atlassian-frontend/commits/f460cc7c411) - Builds for this package now pass through a tokens babel plugin, removing runtime invocations of the tokens() function and improving bundle size.
25
+ - Updated dependencies
26
+
3
27
  ## 7.1.1
4
28
 
5
29
  ### Patch Changes
@@ -11,6 +11,10 @@ exports.default = void 0;
11
11
 
12
12
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
13
13
 
14
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
15
+
16
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
17
+
14
18
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
15
19
 
16
20
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
@@ -35,6 +39,10 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
35
39
 
36
40
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
37
41
 
42
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
43
+
44
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
45
+
38
46
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
39
47
 
40
48
  function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
@@ -64,36 +72,171 @@ var FeedbackCollector = /*#__PURE__*/function (_Component) {
64
72
  }
65
73
 
66
74
  _this = _super.call.apply(_super, [this].concat(args));
67
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "postFeedback", function (formValues) {
68
- var body = _this.mapFormToJSD(formValues); // Don't dispatch unless we have suitable props (allows tests to pass through empty strings and avoid redundant network calls)
69
-
70
-
71
- if (_this.props.embeddableKey && _this.props.requestTypeId) {
72
- fetch("https://jsd-widget.atlassian.com/api/embeddable/".concat(_this.props.embeddableKey, "/request?requestTypeId=").concat(_this.props.requestTypeId), {
73
- method: 'POST',
74
- headers: {
75
- 'Content-Type': 'application/json'
76
- },
77
- body: JSON.stringify(body)
78
- });
79
- }
80
-
81
- _this.props.onClose(); // slightly delay confirming submit since we don't wait for the REST call to succeed
82
- //
83
- // Because `onClose` is invoked prior to this timeout triggering, the `componentWillUnmount`
84
- // may occur before the `onSubmit` is called. To prevent prematurely cancelling the
85
- // network request, we deliberately don't clear this timeout inside `componentWillUnmount`.
86
- //
87
-
88
-
89
- setTimeout(function () {
90
- return _this.props.onSubmit(formValues);
91
- }, _this.props.timeoutOnSubmit);
92
- });
75
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "postFeedback", /*#__PURE__*/function () {
76
+ var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(formValues) {
77
+ var requestType, embedKey, formData, body, postData;
78
+ return _regenerator.default.wrap(function _callee$(_context) {
79
+ while (1) {
80
+ switch (_context.prev = _context.next) {
81
+ case 0:
82
+ requestType = _this.props.requestTypeId;
83
+ embedKey = _this.props.embeddableKey; // Don't dispatch unless we have suitable props (allows tests to pass through empty strings and avoid redundant network calls)
84
+
85
+ if (!(embedKey && requestType)) {
86
+ _context.next = 9;
87
+ break;
88
+ }
89
+
90
+ _context.next = 5;
91
+ return _this.mapFormToJSD(formValues);
92
+
93
+ case 5:
94
+ formData = _context.sent;
95
+ body = {
96
+ feedback: _objectSpread({
97
+ requestType: _this.props.requestTypeId,
98
+ embedKey: _this.props.embeddableKey
99
+ }, formData)
100
+ };
101
+ postData = Buffer.from(JSON.stringify(body)).toString('base64');
102
+ fetch('https://feedback-collector-api.services.atlassian.com/feedback', {
103
+ method: 'POST',
104
+ headers: _objectSpread({
105
+ 'Content-Type': 'application/json'
106
+ }, _this.props.cookie ? {
107
+ Cookie: _this.props.cookie
108
+ } : {}),
109
+ body: JSON.stringify({
110
+ data: postData
111
+ })
112
+ });
113
+
114
+ case 9:
115
+ _this.props.onClose(); // slightly delay confirming submit since we don't wait for the REST call to succeed
116
+ //
117
+ // Because `onClose` is invoked prior to this timeout triggering, the `componentWillUnmount`
118
+ // may occur before the `onSubmit` is called. To prevent prematurely cancelling the
119
+ // network request, we deliberately don't clear this timeout inside `componentWillUnmount`.
120
+ //
121
+
122
+
123
+ setTimeout(function () {
124
+ return _this.props.onSubmit(formValues);
125
+ }, _this.props.timeoutOnSubmit);
126
+
127
+ case 11:
128
+ case "end":
129
+ return _context.stop();
130
+ }
131
+ }
132
+ }, _callee);
133
+ }));
134
+
135
+ return function (_x) {
136
+ return _ref.apply(this, arguments);
137
+ };
138
+ }());
93
139
  return _this;
94
140
  }
95
141
 
96
142
  (0, _createClass2.default)(FeedbackCollector, [{
143
+ key: "getEntitlementInformation",
144
+ value: function () {
145
+ var _getEntitlementInformation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(cookie) {
146
+ var _productName, url, productName, productEntitlement, entitlementDetails, productKey, _document$querySelect, hasPremium, entitlement, entitlementInformation;
147
+
148
+ return _regenerator.default.wrap(function _callee2$(_context2) {
149
+ while (1) {
150
+ switch (_context2.prev = _context2.next) {
151
+ case 0:
152
+ if (!(cookie && cookie.length)) {
153
+ _context2.next = 24;
154
+ break;
155
+ }
156
+
157
+ url = cookie.includes('cloud.session.token.stg') ? 'https://api-private.stg.atlassian.com' : 'https://api-private.atlassian.com'; // jira / connie / bb
158
+
159
+ if (!window.location.host.includes('bitbucket.org')) {
160
+ _context2.next = 10;
161
+ break;
162
+ }
163
+
164
+ productName = 'Bitbucket';
165
+ productKey = 'bitbucket';
166
+ entitlementDetails = JSON.parse(JSON.stringify((_document$querySelect = document.querySelector('meta[name="bb-bootstrap"]')) === null || _document$querySelect === void 0 ? void 0 : _document$querySelect.getAttribute('data-current-user')));
167
+ hasPremium = entitlementDetails['hasPremium'];
168
+ productEntitlement = hasPremium ? 'PREMIUM' : 'STANDARD';
169
+ _context2.next = 20;
170
+ break;
171
+
172
+ case 10:
173
+ if (document.querySelector('meta[id="confluence-context-path"]')) {
174
+ productName = 'Confluence';
175
+ productKey = 'pricingplan.confluence.ondemand';
176
+ } else {
177
+ productName = 'Jira';
178
+ productKey = 'jira-software.ondemand';
179
+ }
180
+
181
+ _context2.prev = 11;
182
+ _context2.next = 14;
183
+ return fetch("".concat(url, "/customer-context/entitlements/").concat(window.location.host), {
184
+ method: 'GET',
185
+ headers: {
186
+ 'Content-Type': 'application/json',
187
+ Cookie: cookie
188
+ },
189
+ credentials: 'include'
190
+ });
191
+
192
+ case 14:
193
+ entitlementDetails = _context2.sent;
194
+ _context2.next = 20;
195
+ break;
196
+
197
+ case 17:
198
+ _context2.prev = 17;
199
+ _context2.t0 = _context2["catch"](11);
200
+ entitlementDetails = undefined;
201
+
202
+ case 20:
203
+ if (entitlementDetails && entitlementDetails.children) {
204
+ entitlement = entitlementDetails.children.find(function (entitlement) {
205
+ return entitlement.key === productKey;
206
+ });
207
+ }
208
+
209
+ entitlementInformation = [];
210
+ entitlementInformation.push({
211
+ id: 'product',
212
+ value: productName ? (_productName = productName) === null || _productName === void 0 ? void 0 : _productName.toLowerCase() : ''
213
+ }, {
214
+ id: 'hostingType',
215
+ value: entitlement && entitlement.product ? entitlement.product.hostingType : 'CLOUD'
216
+ }, {
217
+ id: 'entitlementEdition',
218
+ value: productEntitlement || ''
219
+ });
220
+ return _context2.abrupt("return", entitlementInformation);
221
+
222
+ case 24:
223
+ return _context2.abrupt("return", []);
224
+
225
+ case 25:
226
+ case "end":
227
+ return _context2.stop();
228
+ }
229
+ }
230
+ }, _callee2, null, [[11, 17]]);
231
+ }));
232
+
233
+ function getEntitlementInformation(_x2) {
234
+ return _getEntitlementInformation.apply(this, arguments);
235
+ }
236
+
237
+ return getEntitlementInformation;
238
+ }()
239
+ }, {
97
240
  key: "getTypeFieldValue",
98
241
  value: function getTypeFieldValue(dtype) {
99
242
  switch (dtype) {
@@ -136,32 +279,70 @@ var FeedbackCollector = /*#__PURE__*/function (_Component) {
136
279
  }
137
280
  }, {
138
281
  key: "mapFormToJSD",
139
- value: function mapFormToJSD(formValues) {
140
- return {
141
- fields: [this.props.showTypeField ? {
142
- id: this.props.typeFieldId,
143
- value: this.getTypeFieldValue(formValues.type)
144
- } : undefined, {
145
- id: this.props.summaryFieldId,
146
- value: this.getSummary(formValues)
147
- }, {
148
- id: this.props.descriptionFieldId,
149
- value: this.getDescription(formValues)
150
- }, {
151
- id: this.props.emailFieldId,
152
- value: this.getEmail(formValues)
153
- }, {
154
- id: this.props.customerNameFieldId,
155
- value: this.getCustomerName()
156
- }, formValues.canBeContacted ? {
157
- id: this.props.canBeContactedFieldId,
158
- value: this.props.canBeContactedDefaultValue
159
- } : undefined, formValues.enrollInResearchGroup ? {
160
- id: this.props.enrollInResearchFieldId,
161
- value: this.props.enrollInResearchDefaultValue
162
- } : undefined].concat((0, _toConsumableArray2.default)(this.props.additionalFields)).filter(Boolean)
163
- };
164
- }
282
+ value: function () {
283
+ var _mapFormToJSD = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(formValues) {
284
+ var entitlementInformation;
285
+ return _regenerator.default.wrap(function _callee3$(_context3) {
286
+ while (1) {
287
+ switch (_context3.prev = _context3.next) {
288
+ case 0:
289
+ if (!this.props.cookie) {
290
+ _context3.next = 6;
291
+ break;
292
+ }
293
+
294
+ _context3.next = 3;
295
+ return this.getEntitlementInformation(this.props.cookie);
296
+
297
+ case 3:
298
+ _context3.t0 = _context3.sent;
299
+ _context3.next = 7;
300
+ break;
301
+
302
+ case 6:
303
+ _context3.t0 = [];
304
+
305
+ case 7:
306
+ entitlementInformation = _context3.t0;
307
+ return _context3.abrupt("return", {
308
+ fields: [].concat((0, _toConsumableArray2.default)(entitlementInformation), [this.props.showTypeField ? {
309
+ id: this.props.typeFieldId,
310
+ value: this.getTypeFieldValue(formValues.type)
311
+ } : undefined, {
312
+ id: this.props.summaryFieldId,
313
+ value: this.getSummary(formValues)
314
+ }, {
315
+ id: this.props.descriptionFieldId,
316
+ value: this.getDescription(formValues)
317
+ }, {
318
+ id: this.props.emailFieldId,
319
+ value: this.getEmail(formValues)
320
+ }, {
321
+ id: this.props.customerNameFieldId,
322
+ value: this.getCustomerName()
323
+ }, formValues.canBeContacted ? {
324
+ id: this.props.canBeContactedFieldId,
325
+ value: this.props.canBeContactedDefaultValue
326
+ } : undefined, formValues.enrollInResearchGroup ? {
327
+ id: this.props.enrollInResearchFieldId,
328
+ value: this.props.enrollInResearchDefaultValue
329
+ } : undefined], (0, _toConsumableArray2.default)(this.props.additionalFields)).filter(Boolean)
330
+ });
331
+
332
+ case 9:
333
+ case "end":
334
+ return _context3.stop();
335
+ }
336
+ }
337
+ }, _callee3, this);
338
+ }));
339
+
340
+ function mapFormToJSD(_x3) {
341
+ return _mapFormToJSD.apply(this, arguments);
342
+ }
343
+
344
+ return mapFormToJSD;
345
+ }()
165
346
  }, {
166
347
  key: "render",
167
348
  value: function render() {
@@ -185,6 +366,7 @@ var FeedbackCollector = /*#__PURE__*/function (_Component) {
185
366
 
186
367
  exports.default = FeedbackCollector;
187
368
  (0, _defineProperty2.default)(FeedbackCollector, "defaultProps", {
369
+ cookie: '',
188
370
  canBeContactedFieldId: 'customfield_10043',
189
371
  canBeContactedDefaultValue: [{
190
372
  id: '10109'
@@ -17,12 +17,10 @@ var _checkCircle = _interopRequireDefault(require("@atlaskit/icon/glyph/check-ci
17
17
 
18
18
  var _colors = require("@atlaskit/theme/colors");
19
19
 
20
- var _tokens = require("@atlaskit/tokens");
21
-
22
20
  var FeedbackFlag = function FeedbackFlag(props) {
23
21
  return /*#__PURE__*/_react.default.createElement(_flag.AutoDismissFlag, (0, _extends2.default)({
24
22
  icon: /*#__PURE__*/_react.default.createElement(_checkCircle.default, {
25
- primaryColor: (0, _tokens.token)('color.iconBorder.success', _colors.G300),
23
+ primaryColor: "var(--ds-iconBorder-success, ".concat(_colors.G300, ")"),
26
24
  label: "Success"
27
25
  }),
28
26
  id: "feedbackSent",
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/feedback-collector",
3
- "version": "7.1.1",
3
+ "version": "7.1.2",
4
4
  "sideEffects": false
5
5
  }
@@ -15,16 +15,31 @@ export default class FeedbackCollector extends Component {
15
15
  constructor(...args) {
16
16
  super(...args);
17
17
 
18
- _defineProperty(this, "postFeedback", formValues => {
19
- const body = this.mapFormToJSD(formValues); // Don't dispatch unless we have suitable props (allows tests to pass through empty strings and avoid redundant network calls)
20
-
21
- if (this.props.embeddableKey && this.props.requestTypeId) {
22
- fetch(`https://jsd-widget.atlassian.com/api/embeddable/${this.props.embeddableKey}/request?requestTypeId=${this.props.requestTypeId}`, {
18
+ _defineProperty(this, "postFeedback", async formValues => {
19
+ const requestType = this.props.requestTypeId;
20
+ const embedKey = this.props.embeddableKey; // Don't dispatch unless we have suitable props (allows tests to pass through empty strings and avoid redundant network calls)
21
+
22
+ if (embedKey && requestType) {
23
+ const formData = await this.mapFormToJSD(formValues);
24
+ const body = {
25
+ feedback: {
26
+ requestType: this.props.requestTypeId,
27
+ embedKey: this.props.embeddableKey,
28
+ ...formData
29
+ }
30
+ };
31
+ const postData = Buffer.from(JSON.stringify(body)).toString('base64');
32
+ fetch('https://feedback-collector-api.services.atlassian.com/feedback', {
23
33
  method: 'POST',
24
34
  headers: {
25
- 'Content-Type': 'application/json'
35
+ 'Content-Type': 'application/json',
36
+ ...(this.props.cookie ? {
37
+ Cookie: this.props.cookie
38
+ } : {})
26
39
  },
27
- body: JSON.stringify(body)
40
+ body: JSON.stringify({
41
+ data: postData
42
+ })
28
43
  });
29
44
  }
30
45
 
@@ -39,6 +54,73 @@ export default class FeedbackCollector extends Component {
39
54
  });
40
55
  }
41
56
 
57
+ async getEntitlementInformation(cookie) {
58
+ if (cookie && cookie.length) {
59
+ var _productName;
60
+
61
+ const url = cookie.includes('cloud.session.token.stg') ? 'https://api-private.stg.atlassian.com' : 'https://api-private.atlassian.com'; // jira / connie / bb
62
+
63
+ let productName;
64
+ let productEntitlement;
65
+ let entitlementDetails;
66
+ let productKey;
67
+
68
+ if (window.location.host.includes('bitbucket.org')) {
69
+ var _document$querySelect;
70
+
71
+ productName = 'Bitbucket';
72
+ productKey = 'bitbucket';
73
+ entitlementDetails = JSON.parse(JSON.stringify((_document$querySelect = document.querySelector('meta[name="bb-bootstrap"]')) === null || _document$querySelect === void 0 ? void 0 : _document$querySelect.getAttribute('data-current-user')));
74
+ const hasPremium = entitlementDetails['hasPremium'];
75
+ productEntitlement = hasPremium ? 'PREMIUM' : 'STANDARD';
76
+ } else {
77
+ if (document.querySelector('meta[id="confluence-context-path"]')) {
78
+ productName = 'Confluence';
79
+ productKey = 'pricingplan.confluence.ondemand';
80
+ } else {
81
+ productName = 'Jira';
82
+ productKey = 'jira-software.ondemand';
83
+ }
84
+
85
+ try {
86
+ entitlementDetails = await fetch(`${url}/customer-context/entitlements/${window.location.host}`, {
87
+ method: 'GET',
88
+ headers: {
89
+ 'Content-Type': 'application/json',
90
+ Cookie: cookie
91
+ },
92
+ credentials: 'include'
93
+ });
94
+ } catch (e) {
95
+ entitlementDetails = undefined;
96
+ }
97
+ }
98
+
99
+ let entitlement;
100
+
101
+ if (entitlementDetails && entitlementDetails.children) {
102
+ entitlement = entitlementDetails.children.find(entitlement => {
103
+ return entitlement.key === productKey;
104
+ });
105
+ }
106
+
107
+ const entitlementInformation = [];
108
+ entitlementInformation.push({
109
+ id: 'product',
110
+ value: productName ? (_productName = productName) === null || _productName === void 0 ? void 0 : _productName.toLowerCase() : ''
111
+ }, {
112
+ id: 'hostingType',
113
+ value: entitlement && entitlement.product ? entitlement.product.hostingType : 'CLOUD'
114
+ }, {
115
+ id: 'entitlementEdition',
116
+ value: productEntitlement || ''
117
+ });
118
+ return entitlementInformation;
119
+ }
120
+
121
+ return [];
122
+ }
123
+
42
124
  getTypeFieldValue(dtype) {
43
125
  switch (dtype) {
44
126
  case 'bug':
@@ -75,9 +157,10 @@ export default class FeedbackCollector extends Component {
75
157
  return this.props.name || this.props.customerNameDefaultValue;
76
158
  }
77
159
 
78
- mapFormToJSD(formValues) {
160
+ async mapFormToJSD(formValues) {
161
+ const entitlementInformation = this.props.cookie ? await this.getEntitlementInformation(this.props.cookie) : [];
79
162
  return {
80
- fields: [this.props.showTypeField ? {
163
+ fields: [...entitlementInformation, this.props.showTypeField ? {
81
164
  id: this.props.typeFieldId,
82
165
  value: this.getTypeFieldValue(formValues.type)
83
166
  } : undefined, {
@@ -121,6 +204,7 @@ export default class FeedbackCollector extends Component {
121
204
  }
122
205
 
123
206
  _defineProperty(FeedbackCollector, "defaultProps", {
207
+ cookie: '',
124
208
  canBeContactedFieldId: 'customfield_10043',
125
209
  canBeContactedDefaultValue: [{
126
210
  id: '10109'
@@ -3,11 +3,10 @@ import React from 'react';
3
3
  import { AutoDismissFlag } from '@atlaskit/flag';
4
4
  import SuccessIcon from '@atlaskit/icon/glyph/check-circle';
5
5
  import { G300 } from '@atlaskit/theme/colors';
6
- import { token } from '@atlaskit/tokens';
7
6
 
8
7
  const FeedbackFlag = props => /*#__PURE__*/React.createElement(AutoDismissFlag, _extends({
9
8
  icon: /*#__PURE__*/React.createElement(SuccessIcon, {
10
- primaryColor: token('color.iconBorder.success', G300),
9
+ primaryColor: `var(--ds-iconBorder-success, ${G300})`,
11
10
  label: "Success"
12
11
  }),
13
12
  id: "feedbackSent",
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/feedback-collector",
3
- "version": "7.1.1",
3
+ "version": "7.1.2",
4
4
  "sideEffects": false
5
5
  }
@@ -1,4 +1,6 @@
1
1
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
3
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
4
  import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
3
5
  import _createClass from "@babel/runtime/helpers/createClass";
4
6
  import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
@@ -7,6 +9,10 @@ import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstruct
7
9
  import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
8
10
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
9
11
 
12
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
13
+
14
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
15
+
10
16
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
11
17
 
12
18
  function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
@@ -40,37 +46,172 @@ var FeedbackCollector = /*#__PURE__*/function (_Component) {
40
46
 
41
47
  _this = _super.call.apply(_super, [this].concat(args));
42
48
 
43
- _defineProperty(_assertThisInitialized(_this), "postFeedback", function (formValues) {
44
- var body = _this.mapFormToJSD(formValues); // Don't dispatch unless we have suitable props (allows tests to pass through empty strings and avoid redundant network calls)
49
+ _defineProperty(_assertThisInitialized(_this), "postFeedback", /*#__PURE__*/function () {
50
+ var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(formValues) {
51
+ var requestType, embedKey, formData, body, postData;
52
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
53
+ while (1) {
54
+ switch (_context.prev = _context.next) {
55
+ case 0:
56
+ requestType = _this.props.requestTypeId;
57
+ embedKey = _this.props.embeddableKey; // Don't dispatch unless we have suitable props (allows tests to pass through empty strings and avoid redundant network calls)
45
58
 
59
+ if (!(embedKey && requestType)) {
60
+ _context.next = 9;
61
+ break;
62
+ }
46
63
 
47
- if (_this.props.embeddableKey && _this.props.requestTypeId) {
48
- fetch("https://jsd-widget.atlassian.com/api/embeddable/".concat(_this.props.embeddableKey, "/request?requestTypeId=").concat(_this.props.requestTypeId), {
49
- method: 'POST',
50
- headers: {
51
- 'Content-Type': 'application/json'
52
- },
53
- body: JSON.stringify(body)
54
- });
55
- }
64
+ _context.next = 5;
65
+ return _this.mapFormToJSD(formValues);
66
+
67
+ case 5:
68
+ formData = _context.sent;
69
+ body = {
70
+ feedback: _objectSpread({
71
+ requestType: _this.props.requestTypeId,
72
+ embedKey: _this.props.embeddableKey
73
+ }, formData)
74
+ };
75
+ postData = Buffer.from(JSON.stringify(body)).toString('base64');
76
+ fetch('https://feedback-collector-api.services.atlassian.com/feedback', {
77
+ method: 'POST',
78
+ headers: _objectSpread({
79
+ 'Content-Type': 'application/json'
80
+ }, _this.props.cookie ? {
81
+ Cookie: _this.props.cookie
82
+ } : {}),
83
+ body: JSON.stringify({
84
+ data: postData
85
+ })
86
+ });
87
+
88
+ case 9:
89
+ _this.props.onClose(); // slightly delay confirming submit since we don't wait for the REST call to succeed
90
+ //
91
+ // Because `onClose` is invoked prior to this timeout triggering, the `componentWillUnmount`
92
+ // may occur before the `onSubmit` is called. To prevent prematurely cancelling the
93
+ // network request, we deliberately don't clear this timeout inside `componentWillUnmount`.
94
+ //
56
95
 
57
- _this.props.onClose(); // slightly delay confirming submit since we don't wait for the REST call to succeed
58
- //
59
- // Because `onClose` is invoked prior to this timeout triggering, the `componentWillUnmount`
60
- // may occur before the `onSubmit` is called. To prevent prematurely cancelling the
61
- // network request, we deliberately don't clear this timeout inside `componentWillUnmount`.
62
- //
63
96
 
97
+ setTimeout(function () {
98
+ return _this.props.onSubmit(formValues);
99
+ }, _this.props.timeoutOnSubmit);
64
100
 
65
- setTimeout(function () {
66
- return _this.props.onSubmit(formValues);
67
- }, _this.props.timeoutOnSubmit);
68
- });
101
+ case 11:
102
+ case "end":
103
+ return _context.stop();
104
+ }
105
+ }
106
+ }, _callee);
107
+ }));
108
+
109
+ return function (_x) {
110
+ return _ref.apply(this, arguments);
111
+ };
112
+ }());
69
113
 
70
114
  return _this;
71
115
  }
72
116
 
73
117
  _createClass(FeedbackCollector, [{
118
+ key: "getEntitlementInformation",
119
+ value: function () {
120
+ var _getEntitlementInformation = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(cookie) {
121
+ var _productName, url, productName, productEntitlement, entitlementDetails, productKey, _document$querySelect, hasPremium, entitlement, entitlementInformation;
122
+
123
+ return _regeneratorRuntime.wrap(function _callee2$(_context2) {
124
+ while (1) {
125
+ switch (_context2.prev = _context2.next) {
126
+ case 0:
127
+ if (!(cookie && cookie.length)) {
128
+ _context2.next = 24;
129
+ break;
130
+ }
131
+
132
+ url = cookie.includes('cloud.session.token.stg') ? 'https://api-private.stg.atlassian.com' : 'https://api-private.atlassian.com'; // jira / connie / bb
133
+
134
+ if (!window.location.host.includes('bitbucket.org')) {
135
+ _context2.next = 10;
136
+ break;
137
+ }
138
+
139
+ productName = 'Bitbucket';
140
+ productKey = 'bitbucket';
141
+ entitlementDetails = JSON.parse(JSON.stringify((_document$querySelect = document.querySelector('meta[name="bb-bootstrap"]')) === null || _document$querySelect === void 0 ? void 0 : _document$querySelect.getAttribute('data-current-user')));
142
+ hasPremium = entitlementDetails['hasPremium'];
143
+ productEntitlement = hasPremium ? 'PREMIUM' : 'STANDARD';
144
+ _context2.next = 20;
145
+ break;
146
+
147
+ case 10:
148
+ if (document.querySelector('meta[id="confluence-context-path"]')) {
149
+ productName = 'Confluence';
150
+ productKey = 'pricingplan.confluence.ondemand';
151
+ } else {
152
+ productName = 'Jira';
153
+ productKey = 'jira-software.ondemand';
154
+ }
155
+
156
+ _context2.prev = 11;
157
+ _context2.next = 14;
158
+ return fetch("".concat(url, "/customer-context/entitlements/").concat(window.location.host), {
159
+ method: 'GET',
160
+ headers: {
161
+ 'Content-Type': 'application/json',
162
+ Cookie: cookie
163
+ },
164
+ credentials: 'include'
165
+ });
166
+
167
+ case 14:
168
+ entitlementDetails = _context2.sent;
169
+ _context2.next = 20;
170
+ break;
171
+
172
+ case 17:
173
+ _context2.prev = 17;
174
+ _context2.t0 = _context2["catch"](11);
175
+ entitlementDetails = undefined;
176
+
177
+ case 20:
178
+ if (entitlementDetails && entitlementDetails.children) {
179
+ entitlement = entitlementDetails.children.find(function (entitlement) {
180
+ return entitlement.key === productKey;
181
+ });
182
+ }
183
+
184
+ entitlementInformation = [];
185
+ entitlementInformation.push({
186
+ id: 'product',
187
+ value: productName ? (_productName = productName) === null || _productName === void 0 ? void 0 : _productName.toLowerCase() : ''
188
+ }, {
189
+ id: 'hostingType',
190
+ value: entitlement && entitlement.product ? entitlement.product.hostingType : 'CLOUD'
191
+ }, {
192
+ id: 'entitlementEdition',
193
+ value: productEntitlement || ''
194
+ });
195
+ return _context2.abrupt("return", entitlementInformation);
196
+
197
+ case 24:
198
+ return _context2.abrupt("return", []);
199
+
200
+ case 25:
201
+ case "end":
202
+ return _context2.stop();
203
+ }
204
+ }
205
+ }, _callee2, null, [[11, 17]]);
206
+ }));
207
+
208
+ function getEntitlementInformation(_x2) {
209
+ return _getEntitlementInformation.apply(this, arguments);
210
+ }
211
+
212
+ return getEntitlementInformation;
213
+ }()
214
+ }, {
74
215
  key: "getTypeFieldValue",
75
216
  value: function getTypeFieldValue(dtype) {
76
217
  switch (dtype) {
@@ -113,32 +254,70 @@ var FeedbackCollector = /*#__PURE__*/function (_Component) {
113
254
  }
114
255
  }, {
115
256
  key: "mapFormToJSD",
116
- value: function mapFormToJSD(formValues) {
117
- return {
118
- fields: [this.props.showTypeField ? {
119
- id: this.props.typeFieldId,
120
- value: this.getTypeFieldValue(formValues.type)
121
- } : undefined, {
122
- id: this.props.summaryFieldId,
123
- value: this.getSummary(formValues)
124
- }, {
125
- id: this.props.descriptionFieldId,
126
- value: this.getDescription(formValues)
127
- }, {
128
- id: this.props.emailFieldId,
129
- value: this.getEmail(formValues)
130
- }, {
131
- id: this.props.customerNameFieldId,
132
- value: this.getCustomerName()
133
- }, formValues.canBeContacted ? {
134
- id: this.props.canBeContactedFieldId,
135
- value: this.props.canBeContactedDefaultValue
136
- } : undefined, formValues.enrollInResearchGroup ? {
137
- id: this.props.enrollInResearchFieldId,
138
- value: this.props.enrollInResearchDefaultValue
139
- } : undefined].concat(_toConsumableArray(this.props.additionalFields)).filter(Boolean)
140
- };
141
- }
257
+ value: function () {
258
+ var _mapFormToJSD = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(formValues) {
259
+ var entitlementInformation;
260
+ return _regeneratorRuntime.wrap(function _callee3$(_context3) {
261
+ while (1) {
262
+ switch (_context3.prev = _context3.next) {
263
+ case 0:
264
+ if (!this.props.cookie) {
265
+ _context3.next = 6;
266
+ break;
267
+ }
268
+
269
+ _context3.next = 3;
270
+ return this.getEntitlementInformation(this.props.cookie);
271
+
272
+ case 3:
273
+ _context3.t0 = _context3.sent;
274
+ _context3.next = 7;
275
+ break;
276
+
277
+ case 6:
278
+ _context3.t0 = [];
279
+
280
+ case 7:
281
+ entitlementInformation = _context3.t0;
282
+ return _context3.abrupt("return", {
283
+ fields: [].concat(_toConsumableArray(entitlementInformation), [this.props.showTypeField ? {
284
+ id: this.props.typeFieldId,
285
+ value: this.getTypeFieldValue(formValues.type)
286
+ } : undefined, {
287
+ id: this.props.summaryFieldId,
288
+ value: this.getSummary(formValues)
289
+ }, {
290
+ id: this.props.descriptionFieldId,
291
+ value: this.getDescription(formValues)
292
+ }, {
293
+ id: this.props.emailFieldId,
294
+ value: this.getEmail(formValues)
295
+ }, {
296
+ id: this.props.customerNameFieldId,
297
+ value: this.getCustomerName()
298
+ }, formValues.canBeContacted ? {
299
+ id: this.props.canBeContactedFieldId,
300
+ value: this.props.canBeContactedDefaultValue
301
+ } : undefined, formValues.enrollInResearchGroup ? {
302
+ id: this.props.enrollInResearchFieldId,
303
+ value: this.props.enrollInResearchDefaultValue
304
+ } : undefined], _toConsumableArray(this.props.additionalFields)).filter(Boolean)
305
+ });
306
+
307
+ case 9:
308
+ case "end":
309
+ return _context3.stop();
310
+ }
311
+ }
312
+ }, _callee3, this);
313
+ }));
314
+
315
+ function mapFormToJSD(_x3) {
316
+ return _mapFormToJSD.apply(this, arguments);
317
+ }
318
+
319
+ return mapFormToJSD;
320
+ }()
142
321
  }, {
143
322
  key: "render",
144
323
  value: function render() {
@@ -162,6 +341,7 @@ var FeedbackCollector = /*#__PURE__*/function (_Component) {
162
341
  }(Component);
163
342
 
164
343
  _defineProperty(FeedbackCollector, "defaultProps", {
344
+ cookie: '',
165
345
  canBeContactedFieldId: 'customfield_10043',
166
346
  canBeContactedDefaultValue: [{
167
347
  id: '10109'
@@ -3,12 +3,11 @@ import React from 'react';
3
3
  import { AutoDismissFlag } from '@atlaskit/flag';
4
4
  import SuccessIcon from '@atlaskit/icon/glyph/check-circle';
5
5
  import { G300 } from '@atlaskit/theme/colors';
6
- import { token } from '@atlaskit/tokens';
7
6
 
8
7
  var FeedbackFlag = function FeedbackFlag(props) {
9
8
  return /*#__PURE__*/React.createElement(AutoDismissFlag, _extends({
10
9
  icon: /*#__PURE__*/React.createElement(SuccessIcon, {
11
- primaryColor: token('color.iconBorder.success', G300),
10
+ primaryColor: "var(--ds-iconBorder-success, ".concat(G300, ")"),
12
11
  label: "Success"
13
12
  }),
14
13
  id: "feedbackSent",
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/feedback-collector",
3
- "version": "7.1.1",
3
+ "version": "7.1.2",
4
4
  "sideEffects": false
5
5
  }
@@ -9,13 +9,15 @@ declare type FeedbackType = {
9
9
  fields: FieldType[];
10
10
  };
11
11
  export interface Props {
12
+ /** Required. The customer session token. Usage: `cookie={"cloud.session.token=<session-token>"}` */
13
+ cookie: string;
12
14
  /** The customer email */
13
15
  email?: string;
14
16
  /** The customer name */
15
17
  name?: string;
16
18
  /** The request id to access the widget service */
17
19
  requestTypeId: string;
18
- /** The embeddable key to access the widget service */
20
+ /** The embeddable key to access the widget service. Accessible from the corresponding Jira project */
19
21
  embeddableKey: string;
20
22
  /** Additional fields to send to the widget service **/
21
23
  additionalFields: FieldType[];
@@ -84,6 +86,7 @@ export interface Props {
84
86
  }
85
87
  export default class FeedbackCollector extends Component<Props> {
86
88
  static defaultProps: {
89
+ cookie: string;
87
90
  canBeContactedFieldId: string;
88
91
  canBeContactedDefaultValue: {
89
92
  id: string;
@@ -123,13 +126,14 @@ export default class FeedbackCollector extends Component<Props> {
123
126
  onClose: () => void;
124
127
  onSubmit: () => void;
125
128
  };
129
+ getEntitlementInformation(cookie: string | undefined): Promise<FieldType[] | []>;
126
130
  getTypeFieldValue(dtype: SelectValue): FieldValueType;
127
131
  getEmail(formValues: FormFields): Object;
128
132
  getDescription(formValues: FormFields): Object;
129
133
  getSummary(formValues: FormFields): Object;
130
134
  getCustomerName(): Object;
131
- mapFormToJSD(formValues: FormFields): FeedbackType;
132
- postFeedback: (formValues: FormFields) => void;
135
+ mapFormToJSD(formValues: FormFields): Promise<FeedbackType>;
136
+ postFeedback: (formValues: FormFields) => Promise<void>;
133
137
  render(): JSX.Element;
134
138
  }
135
139
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/feedback-collector",
3
- "version": "7.1.1",
3
+ "version": "7.1.2",
4
4
  "description": "A component that collects feedback across Atlassian products.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -32,11 +32,11 @@
32
32
  "@atlaskit/flag": "^14.4.0",
33
33
  "@atlaskit/form": "^8.4.0",
34
34
  "@atlaskit/icon": "^21.9.0",
35
- "@atlaskit/modal-dialog": "^12.1.0",
35
+ "@atlaskit/modal-dialog": "^12.2.0",
36
36
  "@atlaskit/select": "^15.2.0",
37
37
  "@atlaskit/textarea": "^4.2.0",
38
38
  "@atlaskit/theme": "^12.0.0",
39
- "@atlaskit/tokens": "^0.3.0",
39
+ "@atlaskit/tokens": "^0.4.0",
40
40
  "@babel/runtime": "^7.0.0",
41
41
  "lodash": "^4.17.15"
42
42
  },
@@ -64,8 +64,12 @@
64
64
  "import-structure": "atlassian-conventions"
65
65
  },
66
66
  "@repo/internal": {
67
- "theming": "tokens"
67
+ "theming": "tokens",
68
+ "deprecation": "no-deprecated-imports",
69
+ "styling": [
70
+ "emotion"
71
+ ]
68
72
  }
69
73
  },
70
74
  "prettier": "@atlassian/atlassian-frontend-prettier-config-1.0.1"
71
- }
75
+ }