@atlaskit/feedback-collector 6.2.0 → 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,61 @@
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
+
27
+ ## 7.1.1
28
+
29
+ ### Patch Changes
30
+
31
+ - Updated dependencies
32
+
33
+ ## 7.1.0
34
+
35
+ ### Minor Changes
36
+
37
+ - [`dc5c87fae7d`](https://bitbucket.org/atlassian/atlassian-frontend/commits/dc5c87fae7d) - Instrumented feedback-collector with the new theming package, `@atlaskit/tokens`.
38
+
39
+ New tokens will be visible only in applications configured to use the new Tokens API (currently in alpha). These changes are intended to be interoperable with the legacy theme implementation. Legacy dark mode users should expect no visual or breaking changes.
40
+
41
+ ### Patch Changes
42
+
43
+ - [`9e89e2d2731`](https://bitbucket.org/atlassian/atlassian-frontend/commits/9e89e2d2731) - atlaskit/button has been moved from devDependency to dependency since it is require by runtime code
44
+ - [`cf853e39278`](https://bitbucket.org/atlassian/atlassian-frontend/commits/cf853e39278) - Internal changes to remove `@atlaskit/theme/math` usage.
45
+ - Updated dependencies
46
+
47
+ ## 7.0.0
48
+
49
+ ### Major Changes
50
+
51
+ - [`b000daa6f08`](https://bitbucket.org/atlassian/atlassian-frontend/commits/b000daa6f08) - [ux] Refactor to use new modal dialog API. This includes button order being reversed so that the primary button is on the right.
52
+
53
+ ### Patch Changes
54
+
55
+ - [`5fe6e21a9a0`](https://bitbucket.org/atlassian/atlassian-frontend/commits/5fe6e21a9a0) - [ux] Upgrade to the latest version of @atlaskit/modal-dialog. This change includes shifting the primary button in the footer of the modal to be on the right instead of the left.
56
+ - [`b90c0237824`](https://bitbucket.org/atlassian/atlassian-frontend/commits/b90c0237824) - Update package.jsons to remove unused dependencies.
57
+ - Updated dependencies
58
+
3
59
  ## 6.2.0
4
60
 
5
61
  ### Minor 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'
@@ -20,7 +20,7 @@ var _colors = require("@atlaskit/theme/colors");
20
20
  var FeedbackFlag = function FeedbackFlag(props) {
21
21
  return /*#__PURE__*/_react.default.createElement(_flag.AutoDismissFlag, (0, _extends2.default)({
22
22
  icon: /*#__PURE__*/_react.default.createElement(_checkCircle.default, {
23
- primaryColor: _colors.G300,
23
+ primaryColor: "var(--ds-iconBorder-success, ".concat(_colors.G300, ")"),
24
24
  label: "Success"
25
25
  }),
26
26
  id: "feedbackSent",
@@ -27,11 +27,13 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/de
27
27
 
28
28
  var _react = _interopRequireWildcard(require("react"));
29
29
 
30
+ var _standardButton = _interopRequireDefault(require("@atlaskit/button/standard-button"));
31
+
30
32
  var _checkbox = require("@atlaskit/checkbox");
31
33
 
32
34
  var _form = _interopRequireWildcard(require("@atlaskit/form"));
33
35
 
34
- var _modalDialog = _interopRequireDefault(require("@atlaskit/modal-dialog"));
36
+ var _modalDialog = _interopRequireWildcard(require("@atlaskit/modal-dialog"));
35
37
 
36
38
  var _select = _interopRequireDefault(require("@atlaskit/select"));
37
39
 
@@ -132,26 +134,12 @@ var FeedbackForm = /*#__PURE__*/function (_Component) {
132
134
  var canShowTextField = this.isTypeSelected() || !showTypeField;
133
135
  var isDisabled = showTypeField ? !this.isTypeSelected() || !this.state.description : !this.state.description;
134
136
  return /*#__PURE__*/_react.default.createElement(_modalDialog.default, {
135
- actions: [{
136
- text: this.props.submitButtonLabel,
137
- appearance: 'primary',
138
- type: 'submit',
139
- isDisabled: isDisabled,
140
- onClick: this.onSubmit
141
- }, {
142
- text: this.props.cancelButtonLabel,
143
- onClick: this.props.onClose,
144
- appearance: 'subtle'
145
- }],
146
- heading: this.props.feedbackTitle,
147
137
  onClose: this.props.onClose
148
138
  }, /*#__PURE__*/_react.default.createElement(_form.default, {
149
- onSubmit: function onSubmit() {
150
- /* TODO: this is a NOOP until Modal can take a container prop */
151
- }
139
+ onSubmit: this.onSubmit
152
140
  }, function (_ref) {
153
141
  var formProps = _ref.formProps;
154
- return /*#__PURE__*/_react.default.createElement("form", formProps, _this2.props.feedbackTitleDetails, showTypeField ? /*#__PURE__*/_react.default.createElement(_select.default, {
142
+ return /*#__PURE__*/_react.default.createElement("form", formProps, /*#__PURE__*/_react.default.createElement(_modalDialog.ModalHeader, null, /*#__PURE__*/_react.default.createElement(_modalDialog.ModalTitle, null, _this2.props.feedbackTitle)), /*#__PURE__*/_react.default.createElement(_modalDialog.ModalBody, null, _this2.props.feedbackTitleDetails, showTypeField ? /*#__PURE__*/_react.default.createElement(_select.default, {
155
143
  onChange: function onChange(option) {
156
144
  if (!option || option instanceof Array) {
157
145
  return;
@@ -212,7 +200,14 @@ var FeedbackForm = /*#__PURE__*/function (_Component) {
212
200
  });
213
201
  }
214
202
  }));
215
- })) : /*#__PURE__*/_react.default.createElement(_react.Fragment, null));
203
+ })) : /*#__PURE__*/_react.default.createElement(_react.Fragment, null)), /*#__PURE__*/_react.default.createElement(_modalDialog.ModalFooter, null, /*#__PURE__*/_react.default.createElement(_standardButton.default, {
204
+ appearance: "subtle",
205
+ onClick: _this2.props.onClose
206
+ }, _this2.props.cancelButtonLabel), /*#__PURE__*/_react.default.createElement(_standardButton.default, {
207
+ appearance: "primary",
208
+ type: "submit",
209
+ isDisabled: isDisabled
210
+ }, _this2.props.submitButtonLabel)));
216
211
  }));
217
212
  }
218
213
  }]);
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/feedback-collector",
3
- "version": "6.2.0",
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'
@@ -6,7 +6,7 @@ import { G300 } from '@atlaskit/theme/colors';
6
6
 
7
7
  const FeedbackFlag = props => /*#__PURE__*/React.createElement(AutoDismissFlag, _extends({
8
8
  icon: /*#__PURE__*/React.createElement(SuccessIcon, {
9
- primaryColor: G300,
9
+ primaryColor: `var(--ds-iconBorder-success, ${G300})`,
10
10
  label: "Success"
11
11
  }),
12
12
  id: "feedbackSent",
@@ -1,9 +1,10 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
3
  import React, { Component, Fragment } from 'react';
4
+ import Button from '@atlaskit/button/standard-button';
4
5
  import { Checkbox } from '@atlaskit/checkbox';
5
6
  import Form, { Field } from '@atlaskit/form';
6
- import Modal from '@atlaskit/modal-dialog';
7
+ import Modal, { ModalBody, ModalFooter, ModalHeader, ModalTitle } from '@atlaskit/modal-dialog';
7
8
  import Select from '@atlaskit/select';
8
9
  import TextArea from '@atlaskit/textarea';
9
10
 
@@ -76,26 +77,12 @@ export default class FeedbackForm extends Component {
76
77
  const canShowTextField = this.isTypeSelected() || !showTypeField;
77
78
  const isDisabled = showTypeField ? !this.isTypeSelected() || !this.state.description : !this.state.description;
78
79
  return /*#__PURE__*/React.createElement(Modal, {
79
- actions: [{
80
- text: this.props.submitButtonLabel,
81
- appearance: 'primary',
82
- type: 'submit',
83
- isDisabled,
84
- onClick: this.onSubmit
85
- }, {
86
- text: this.props.cancelButtonLabel,
87
- onClick: this.props.onClose,
88
- appearance: 'subtle'
89
- }],
90
- heading: this.props.feedbackTitle,
91
80
  onClose: this.props.onClose
92
81
  }, /*#__PURE__*/React.createElement(Form, {
93
- onSubmit: () => {
94
- /* TODO: this is a NOOP until Modal can take a container prop */
95
- }
82
+ onSubmit: this.onSubmit
96
83
  }, ({
97
84
  formProps
98
- }) => /*#__PURE__*/React.createElement("form", formProps, this.props.feedbackTitleDetails, showTypeField ? /*#__PURE__*/React.createElement(Select, {
85
+ }) => /*#__PURE__*/React.createElement("form", formProps, /*#__PURE__*/React.createElement(ModalHeader, null, /*#__PURE__*/React.createElement(ModalTitle, null, this.props.feedbackTitle)), /*#__PURE__*/React.createElement(ModalBody, null, this.props.feedbackTitleDetails, showTypeField ? /*#__PURE__*/React.createElement(Select, {
99
86
  onChange: option => {
100
87
  if (!option || option instanceof Array) {
101
88
  return;
@@ -145,7 +132,14 @@ export default class FeedbackForm extends Component {
145
132
  onChange: event => this.setState({
146
133
  enrollInResearchGroup: event.target.checked
147
134
  })
148
- })))) : /*#__PURE__*/React.createElement(Fragment, null))));
135
+ })))) : /*#__PURE__*/React.createElement(Fragment, null)), /*#__PURE__*/React.createElement(ModalFooter, null, /*#__PURE__*/React.createElement(Button, {
136
+ appearance: "subtle",
137
+ onClick: this.props.onClose
138
+ }, this.props.cancelButtonLabel), /*#__PURE__*/React.createElement(Button, {
139
+ appearance: "primary",
140
+ type: "submit",
141
+ isDisabled: isDisabled
142
+ }, this.props.submitButtonLabel)))));
149
143
  }
150
144
 
151
145
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/feedback-collector",
3
- "version": "6.2.0",
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'
@@ -7,7 +7,7 @@ import { G300 } from '@atlaskit/theme/colors';
7
7
  var FeedbackFlag = function FeedbackFlag(props) {
8
8
  return /*#__PURE__*/React.createElement(AutoDismissFlag, _extends({
9
9
  icon: /*#__PURE__*/React.createElement(SuccessIcon, {
10
- primaryColor: G300,
10
+ primaryColor: "var(--ds-iconBorder-success, ".concat(G300, ")"),
11
11
  label: "Success"
12
12
  }),
13
13
  id: "feedbackSent",
@@ -16,9 +16,10 @@ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflec
16
16
  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; } }
17
17
 
18
18
  import React, { Component, Fragment } from 'react';
19
+ import Button from '@atlaskit/button/standard-button';
19
20
  import { Checkbox } from '@atlaskit/checkbox';
20
21
  import Form, { Field } from '@atlaskit/form';
21
- import Modal from '@atlaskit/modal-dialog';
22
+ import Modal, { ModalBody, ModalFooter, ModalHeader, ModalTitle } from '@atlaskit/modal-dialog';
22
23
  import Select from '@atlaskit/select';
23
24
  import TextArea from '@atlaskit/textarea';
24
25
 
@@ -109,26 +110,12 @@ var FeedbackForm = /*#__PURE__*/function (_Component) {
109
110
  var canShowTextField = this.isTypeSelected() || !showTypeField;
110
111
  var isDisabled = showTypeField ? !this.isTypeSelected() || !this.state.description : !this.state.description;
111
112
  return /*#__PURE__*/React.createElement(Modal, {
112
- actions: [{
113
- text: this.props.submitButtonLabel,
114
- appearance: 'primary',
115
- type: 'submit',
116
- isDisabled: isDisabled,
117
- onClick: this.onSubmit
118
- }, {
119
- text: this.props.cancelButtonLabel,
120
- onClick: this.props.onClose,
121
- appearance: 'subtle'
122
- }],
123
- heading: this.props.feedbackTitle,
124
113
  onClose: this.props.onClose
125
114
  }, /*#__PURE__*/React.createElement(Form, {
126
- onSubmit: function onSubmit() {
127
- /* TODO: this is a NOOP until Modal can take a container prop */
128
- }
115
+ onSubmit: this.onSubmit
129
116
  }, function (_ref) {
130
117
  var formProps = _ref.formProps;
131
- return /*#__PURE__*/React.createElement("form", formProps, _this2.props.feedbackTitleDetails, showTypeField ? /*#__PURE__*/React.createElement(Select, {
118
+ return /*#__PURE__*/React.createElement("form", formProps, /*#__PURE__*/React.createElement(ModalHeader, null, /*#__PURE__*/React.createElement(ModalTitle, null, _this2.props.feedbackTitle)), /*#__PURE__*/React.createElement(ModalBody, null, _this2.props.feedbackTitleDetails, showTypeField ? /*#__PURE__*/React.createElement(Select, {
132
119
  onChange: function onChange(option) {
133
120
  if (!option || option instanceof Array) {
134
121
  return;
@@ -189,7 +176,14 @@ var FeedbackForm = /*#__PURE__*/function (_Component) {
189
176
  });
190
177
  }
191
178
  }));
192
- })) : /*#__PURE__*/React.createElement(Fragment, null));
179
+ })) : /*#__PURE__*/React.createElement(Fragment, null)), /*#__PURE__*/React.createElement(ModalFooter, null, /*#__PURE__*/React.createElement(Button, {
180
+ appearance: "subtle",
181
+ onClick: _this2.props.onClose
182
+ }, _this2.props.cancelButtonLabel), /*#__PURE__*/React.createElement(Button, {
183
+ appearance: "primary",
184
+ type: "submit",
185
+ isDisabled: isDisabled
186
+ }, _this2.props.submitButtonLabel)));
193
187
  }));
194
188
  }
195
189
  }]);
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/feedback-collector",
3
- "version": "6.2.0",
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": "6.2.0",
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/"
@@ -30,12 +30,13 @@
30
30
  "@atlaskit/button": "^16.1.0",
31
31
  "@atlaskit/checkbox": "^12.3.0",
32
32
  "@atlaskit/flag": "^14.4.0",
33
- "@atlaskit/form": "^8.3.0",
34
- "@atlaskit/icon": "^21.7.0",
35
- "@atlaskit/modal-dialog": "^11.6.0",
36
- "@atlaskit/select": "^15.0.0",
33
+ "@atlaskit/form": "^8.4.0",
34
+ "@atlaskit/icon": "^21.9.0",
35
+ "@atlaskit/modal-dialog": "^12.2.0",
36
+ "@atlaskit/select": "^15.2.0",
37
37
  "@atlaskit/textarea": "^4.2.0",
38
- "@atlaskit/theme": "^11.4.0",
38
+ "@atlaskit/theme": "^12.0.0",
39
+ "@atlaskit/tokens": "^0.4.0",
39
40
  "@babel/runtime": "^7.0.0",
40
41
  "lodash": "^4.17.15"
41
42
  },
@@ -45,7 +46,6 @@
45
46
  "devDependencies": {
46
47
  "@atlaskit/build-utils": "*",
47
48
  "@atlaskit/docs": "*",
48
- "@atlaskit/global-navigation": "^11.0.0",
49
49
  "@atlaskit/logo": "^13.5.0",
50
50
  "@atlaskit/navigation-next": "^9.0.0",
51
51
  "@atlaskit/ssr": "*",
@@ -62,7 +62,14 @@
62
62
  "techstack": {
63
63
  "@atlassian/frontend": {
64
64
  "import-structure": "atlassian-conventions"
65
+ },
66
+ "@repo/internal": {
67
+ "theming": "tokens",
68
+ "deprecation": "no-deprecated-imports",
69
+ "styling": [
70
+ "emotion"
71
+ ]
65
72
  }
66
73
  },
67
74
  "prettier": "@atlassian/atlassian-frontend-prettier-config-1.0.1"
68
- }
75
+ }