@atlaskit/reactions 21.1.0 → 21.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/cjs/analytics/index.js +11 -1
  3. package/dist/cjs/analytics/ufo.js +71 -0
  4. package/dist/cjs/components/ReactionPicker.js +17 -4
  5. package/dist/cjs/components/UfoErrorBoundary.js +68 -0
  6. package/dist/cjs/components/index.js +9 -1
  7. package/dist/cjs/containers/ConnectedReactionPicker.js +44 -0
  8. package/dist/cjs/containers/ConnectedReactionsView.js +131 -0
  9. package/dist/cjs/containers/index.js +4 -6
  10. package/dist/cjs/index.js +11 -3
  11. package/dist/cjs/{reaction-store → store}/ReactionConsumer.js +0 -0
  12. package/dist/cjs/{reaction-store → store}/ReactionsStore.js +63 -14
  13. package/dist/cjs/{reaction-store → store}/batched.js +0 -0
  14. package/dist/cjs/{reaction-store → store}/index.js +0 -0
  15. package/dist/cjs/{reaction-store → store}/utils.js +0 -0
  16. package/dist/cjs/version.json +1 -1
  17. package/dist/es2019/analytics/index.js +2 -0
  18. package/dist/es2019/analytics/ufo.js +62 -0
  19. package/dist/es2019/components/ReactionPicker.js +13 -3
  20. package/dist/es2019/components/UfoErrorBoundary.js +13 -0
  21. package/dist/es2019/components/index.js +2 -1
  22. package/dist/es2019/containers/ConnectedReactionPicker.js +27 -0
  23. package/dist/es2019/containers/ConnectedReactionsView.js +112 -0
  24. package/dist/es2019/containers/index.js +2 -2
  25. package/dist/es2019/index.js +2 -1
  26. package/dist/es2019/{reaction-store → store}/ReactionConsumer.js +0 -0
  27. package/dist/es2019/{reaction-store → store}/ReactionsStore.js +59 -13
  28. package/dist/es2019/{reaction-store → store}/batched.js +0 -0
  29. package/dist/es2019/{reaction-store → store}/index.js +0 -0
  30. package/dist/es2019/{reaction-store → store}/utils.js +0 -0
  31. package/dist/es2019/version.json +1 -1
  32. package/dist/esm/analytics/index.js +2 -0
  33. package/dist/esm/analytics/ufo.js +62 -0
  34. package/dist/esm/components/ReactionPicker.js +13 -3
  35. package/dist/esm/components/UfoErrorBoundary.js +54 -0
  36. package/dist/esm/components/index.js +2 -1
  37. package/dist/esm/containers/ConnectedReactionPicker.js +29 -0
  38. package/dist/esm/containers/ConnectedReactionsView.js +108 -0
  39. package/dist/esm/containers/index.js +2 -2
  40. package/dist/esm/index.js +2 -1
  41. package/dist/esm/{reaction-store → store}/ReactionConsumer.js +0 -0
  42. package/dist/esm/{reaction-store → store}/ReactionsStore.js +61 -13
  43. package/dist/esm/{reaction-store → store}/batched.js +0 -0
  44. package/dist/esm/{reaction-store → store}/index.js +0 -0
  45. package/dist/esm/{reaction-store → store}/utils.js +0 -0
  46. package/dist/esm/version.json +1 -1
  47. package/dist/types/analytics/index.d.ts +1 -0
  48. package/dist/types/analytics/ufo.d.ts +26 -0
  49. package/dist/types/components/ReactionPicker.d.ts +2 -1
  50. package/dist/types/components/Reactions.d.ts +7 -5
  51. package/dist/types/components/UfoErrorBoundary.d.ts +8 -0
  52. package/dist/types/components/index.d.ts +2 -0
  53. package/dist/types/containers/ConnectedReactionPicker.d.ts +10 -0
  54. package/dist/types/containers/ConnectedReactionsView.d.ts +19 -0
  55. package/dist/types/containers/index.d.ts +2 -2
  56. package/dist/types/index.d.ts +3 -2
  57. package/dist/types/store/ReactionConsumer.d.ts +29 -0
  58. package/dist/types/{reaction-store → store}/ReactionsStore.d.ts +11 -7
  59. package/dist/types/{reaction-store → store}/batched.d.ts +0 -0
  60. package/dist/types/{reaction-store → store}/index.d.ts +0 -0
  61. package/dist/types/{reaction-store → store}/utils.d.ts +0 -0
  62. package/dist/types/types/Actions.d.ts +6 -0
  63. package/dist/types/types/index.d.ts +1 -1
  64. package/docs/0-intro.tsx +1 -1
  65. package/package.json +3 -1
  66. package/dist/cjs/containers/ReactionsContainer.js +0 -142
  67. package/dist/cjs/containers/ReactionsPickerContainer.js +0 -76
  68. package/dist/es2019/containers/ReactionsContainer.js +0 -96
  69. package/dist/es2019/containers/ReactionsPickerContainer.js +0 -26
  70. package/dist/esm/containers/ReactionsContainer.js +0 -125
  71. package/dist/esm/containers/ReactionsPickerContainer.js +0 -62
  72. package/dist/types/containers/ReactionsContainer.d.ts +0 -22
  73. package/dist/types/containers/ReactionsPickerContainer.d.ts +0 -18
  74. package/dist/types/reaction-store/ReactionConsumer.d.ts +0 -32
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "name": "@atlaskit/reactions",
3
- "version": "21.1.0"
3
+ "version": "21.2.0"
4
4
  }
@@ -1,6 +1,8 @@
1
1
  import { createAndFireEvent } from '@atlaskit/analytics-next';
2
2
  import { UI_EVENT_TYPE, OPERATIONAL_EVENT_TYPE } from '@atlaskit/analytics-gas-types';
3
3
  import { name as packageName, version as packageVersion } from '../version.json';
4
+ import * as _UFO from './ufo';
5
+ export { _UFO as UFO };
4
6
  export const createAndFireEventInElementsChannel = createAndFireEvent('fabric-elements');
5
7
  export const createAndFireSafe = (createAnalyticsEvent, creator, ...args) => {
6
8
  if (createAnalyticsEvent) {
@@ -0,0 +1,62 @@
1
+ import { ConcurrentExperience, UFOExperience, ExperiencePerformanceTypes, ExperienceTypes } from '@atlaskit/ufo';
2
+ /**
3
+ * Initial experience config object (deferred from @atlaskit/ufo inner types)
4
+ * TODO: Check if possible to add this to exported types from @atlaskit/ufo
5
+ */
6
+
7
+ /**
8
+ * Helper method for create the config type for an individual/Concurrent experience
9
+ * @param componentName
10
+ */
11
+ const createExperienceConfig = (componentName, type, performanceType) => {
12
+ return {
13
+ platform: {
14
+ component: componentName
15
+ },
16
+ type,
17
+ performanceType
18
+ };
19
+ };
20
+ /**
21
+ * Types of experiences
22
+ */
23
+
24
+
25
+ export let ExperienceName;
26
+ /**
27
+ * UFO types of components been instrumented
28
+ */
29
+
30
+ (function (ExperienceName) {
31
+ ExperienceName["REACTIONS_RENDERED"] = "reactions-rendered";
32
+ ExperienceName["PICKER_OPENED"] = "reactions-picker-opened";
33
+ ExperienceName["REACTION_ADDED"] = "reaction-added";
34
+ ExperienceName["REACTION_REMOVED"] = "reaction-removed";
35
+ })(ExperienceName || (ExperienceName = {}));
36
+
37
+ var ComponentName;
38
+ /**
39
+ * Experience when the emoji picker is opened
40
+ */
41
+
42
+ (function (ComponentName) {
43
+ ComponentName["PICKER_RENDERED"] = "reactions-picker";
44
+ ComponentName["REACTIONS"] = "reactions-list";
45
+ })(ComponentName || (ComponentName = {}));
46
+
47
+ export const PickerRender = new UFOExperience(ExperienceName.PICKER_OPENED, createExperienceConfig(ComponentName.PICKER_RENDERED, ExperienceTypes.Experience, ExperiencePerformanceTypes.InlineResult));
48
+ /**
49
+ * Experience when the list of reactions gets rendered
50
+ */
51
+
52
+ export const ReactionsRendered = new ConcurrentExperience(ExperienceName.REACTIONS_RENDERED, createExperienceConfig(ComponentName.REACTIONS, ExperienceTypes.Experience, ExperiencePerformanceTypes.InlineResult));
53
+ /**
54
+ * Experience when a reaction emoji gets added
55
+ */
56
+
57
+ export const ReactionsAdd = new ConcurrentExperience(ExperienceName.REACTION_ADDED, createExperienceConfig(ComponentName.REACTIONS, ExperienceTypes.Experience, ExperiencePerformanceTypes.InlineResult));
58
+ /**
59
+ * Experience when a reaction emoji gets removed/decrement
60
+ */
61
+
62
+ export const ReactionsRemove = new ConcurrentExperience(ExperienceName.REACTION_REMOVED, createExperienceConfig(ComponentName.REACTIONS, ExperienceTypes.Experience, ExperiencePerformanceTypes.InlineResult));
@@ -1,17 +1,17 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
 
3
3
  /** @jsx jsx */
4
+ import React, { Fragment, PureComponent } from 'react';
5
+ import ReactDOM from 'react-dom';
4
6
  import { jsx, css } from '@emotion/core';
5
7
  import { EmojiPicker } from '@atlaskit/emoji/picker';
6
8
  import { Manager, Popper, Reference } from '@atlaskit/popper';
7
9
  import { borderRadius } from '@atlaskit/theme/constants';
8
10
  import { N0, N50A, N60A } from '@atlaskit/theme/colors';
9
11
  import { token } from '@atlaskit/tokens';
10
- import React, { Fragment } from 'react';
11
- import { PureComponent } from 'react';
12
- import ReactDOM from 'react-dom';
13
12
  import { Selector } from './Selector';
14
13
  import { Trigger } from './Trigger';
14
+ import { UFO } from '../analytics';
15
15
  import { layers } from '@atlaskit/theme/constants';
16
16
  const pickerStyle = css({
17
17
  verticalAlign: 'middle',
@@ -91,6 +91,9 @@ export class ReactionPicker extends PureComponent {
91
91
  });
92
92
 
93
93
  _defineProperty(this, "onTriggerClick", () => {
94
+ // ufo start reaction experience
95
+ UFO.PickerRender.start();
96
+
94
97
  if (this.props.onOpen) {
95
98
  this.props.onOpen();
96
99
  }
@@ -98,6 +101,9 @@ export class ReactionPicker extends PureComponent {
98
101
  this.setState({
99
102
  isOpen: !this.state.isOpen,
100
103
  showFullPicker: false
104
+ }, () => {
105
+ // ufo add reaction success
106
+ UFO.PickerRender.success();
101
107
  });
102
108
  });
103
109
 
@@ -137,12 +143,16 @@ export class ReactionPicker extends PureComponent {
137
143
 
138
144
  componentWillUnmount() {
139
145
  document.removeEventListener('click', this.handleClickOutside);
146
+ UFO.PickerRender.abort();
140
147
  }
141
148
 
142
149
  close(_emojiId) {
143
150
  this.setState({
144
151
  isOpen: false,
145
152
  showFullPicker: false
153
+ }, () => {
154
+ // ufo abort reaction experience
155
+ UFO.PickerRender.abort();
146
156
  });
147
157
  }
148
158
 
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ export class UfoErrorBoundary extends React.Component {
3
+ componentDidCatch() {
4
+ for (const e of this.props.experiences) {
5
+ e.failure();
6
+ }
7
+ }
8
+
9
+ render() {
10
+ return this.props.children;
11
+ }
12
+
13
+ }
@@ -1,3 +1,4 @@
1
1
  export { Reaction } from './Reaction';
2
2
  export { ReactionPicker } from './ReactionPicker';
3
- export { Reactions } from './Reactions';
3
+ export { Reactions } from './Reactions';
4
+ export { UfoErrorBoundary } from './UfoErrorBoundary';
@@ -0,0 +1,27 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ import React from 'react';
3
+ import { ReactionPicker, UfoErrorBoundary } from '../components';
4
+ import { ReactionConsumer } from '../store/ReactionConsumer';
5
+ import { UFO } from '../analytics';
6
+
7
+ /**
8
+ * UFO Instance for picker
9
+ */
10
+ export const ConnectedReactionPicker = props => {
11
+ const renderChild = innerProps => {
12
+ return /*#__PURE__*/React.createElement(ReactionPicker, _extends({}, props, innerProps));
13
+ };
14
+
15
+ const actionsMapper = actions => ({
16
+ onSelection: emojiId => {
17
+ actions.addReaction(props.containerAri, props.ari, emojiId);
18
+ }
19
+ });
20
+
21
+ return /*#__PURE__*/React.createElement(UfoErrorBoundary, {
22
+ experiences: [UFO.PickerRender]
23
+ }, /*#__PURE__*/React.createElement(ReactionConsumer, {
24
+ store: props.store,
25
+ actionsMapper: actionsMapper
26
+ }, renderChild));
27
+ };
@@ -0,0 +1,112 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ import React, { useEffect, useRef } from 'react';
3
+ import { FabricElementsAnalyticsContext } from '@atlaskit/analytics-namespaced-context';
4
+ import { withAnalyticsEvents } from '@atlaskit/analytics-next';
5
+ import { Reactions, UfoErrorBoundary } from '../components';
6
+ import { ReactionConsumer } from '../store/ReactionConsumer';
7
+ import { ReactionStatus } from '../types/ReactionStatus';
8
+ import { ufoExperiences } from '../store/ReactionsStore';
9
+
10
+ const ReactionsView = props => {
11
+ // // compose a UFO experience object
12
+ let experienceInstance = useRef();
13
+ const {
14
+ ari,
15
+ createAnalyticsEvent,
16
+ store
17
+ } = props;
18
+ useEffect(() => {
19
+ experienceInstance.current = ufoExperiences.render.getInstance(ari);
20
+ }, [ari]);
21
+ useEffect(() => {
22
+ Promise.resolve(store).then(_store => {
23
+ if (_store.setCreateAnalyticsEvent && createAnalyticsEvent) {
24
+ _store.setCreateAnalyticsEvent(createAnalyticsEvent);
25
+ }
26
+ });
27
+ }, [createAnalyticsEvent, store]); // abort when component gets unmounted
28
+
29
+ useEffect(() => {
30
+ return () => {
31
+ var _experienceInstance$c;
32
+
33
+ (_experienceInstance$c = experienceInstance.current) === null || _experienceInstance$c === void 0 ? void 0 : _experienceInstance$c.abort();
34
+ };
35
+ }, [experienceInstance]);
36
+
37
+ const renderChildren = innerProps => {
38
+ const {
39
+ containerAri,
40
+ ari
41
+ } = props;
42
+ return /*#__PURE__*/React.createElement(FabricElementsAnalyticsContext, {
43
+ data: {
44
+ containerAri,
45
+ ari
46
+ }
47
+ }, /*#__PURE__*/React.createElement(Reactions, _extends({
48
+ key: `${props.containerAri}|${props.ari}`
49
+ }, props, innerProps)));
50
+ };
51
+
52
+ const stateMapper = state => {
53
+ const {
54
+ containerAri,
55
+ ari
56
+ } = props;
57
+ const reactionsState = state && state.reactions[`${containerAri}|${ari}`];
58
+
59
+ if (!state || !reactionsState) {
60
+ return {
61
+ status: ReactionStatus.notLoaded,
62
+ reactions: []
63
+ };
64
+ }
65
+
66
+ switch (reactionsState.status) {
67
+ case ReactionStatus.ready:
68
+ return {
69
+ reactions: reactionsState.reactions,
70
+ status: reactionsState.status,
71
+ flash: state.flash[`${containerAri}|${ari}`]
72
+ };
73
+
74
+ case ReactionStatus.error:
75
+ return {
76
+ status: ReactionStatus.error,
77
+ reactions: []
78
+ };
79
+
80
+ default:
81
+ return {
82
+ status: ReactionStatus.loading,
83
+ reactions: []
84
+ };
85
+ }
86
+ };
87
+
88
+ const actionsMapper = actions => ({
89
+ loadReaction: () => {
90
+ actions.getReactions(props.containerAri, props.ari);
91
+ },
92
+ onReactionClick: emojiId => {
93
+ actions.toggleReaction(props.containerAri, props.ari, emojiId);
94
+ },
95
+ onReactionHover: emojiId => {
96
+ actions.getDetailedReaction(props.containerAri, props.ari, emojiId);
97
+ },
98
+ onSelection: emojiId => {
99
+ actions.addReaction(props.containerAri, props.ari, emojiId);
100
+ }
101
+ });
102
+
103
+ return /*#__PURE__*/React.createElement(UfoErrorBoundary, {
104
+ experiences: experienceInstance.current ? [experienceInstance.current] : []
105
+ }, /*#__PURE__*/React.createElement(ReactionConsumer, {
106
+ store: props.store,
107
+ actionsMapper: actionsMapper,
108
+ stateMapper: stateMapper
109
+ }, renderChildren));
110
+ };
111
+
112
+ export const ConnectedReactionsView = withAnalyticsEvents()(ReactionsView);
@@ -1,2 +1,2 @@
1
- export { default as ConnectedReactionPicker } from './ReactionsPickerContainer';
2
- export { default as ConnectedReactionsView } from './ReactionsContainer';
1
+ export { ConnectedReactionPicker } from './ConnectedReactionPicker';
2
+ export { ConnectedReactionsView } from './ConnectedReactionsView';
@@ -1,4 +1,5 @@
1
+ export { UFO } from './analytics';
1
2
  export { ReactionServiceClient } from './client';
2
3
  export { Reaction, ReactionPicker, Reactions } from './components';
3
4
  export { ConnectedReactionPicker, ConnectedReactionsView } from './containers';
4
- export { MemoryReactionsStore, ReactionConsumer } from './reaction-store';
5
+ export { MemoryReactionsStore, ReactionConsumer } from './store';
@@ -1,9 +1,18 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
- import { createRestSucceededEvent, createRestFailedEvent, createAndFireSafe } from '../analytics';
3
- import { ReactionStatus } from '../types';
2
+ import * as Analytics from '../analytics';
3
+ import * as Types from '../types';
4
4
  import { batch, batchByKey } from './batched';
5
5
  import * as utils from './utils';
6
6
  import { isRealErrorFromService } from './utils';
7
+
8
+ /**
9
+ * Set of all available UFO experiences relating to reaction element
10
+ */
11
+ export const ufoExperiences = {
12
+ add: Analytics.UFO.ReactionsAdd,
13
+ remove: Analytics.UFO.ReactionsRemove,
14
+ render: Analytics.UFO.ReactionsRendered
15
+ };
7
16
  export class MemoryReactionsStore {
8
17
  constructor(client, state = {
9
18
  reactions: {},
@@ -90,13 +99,25 @@ export class MemoryReactionsStore {
90
99
  } = reaction;
91
100
  this.optmisticUpdate(containerAri, ari, emojiId)(utils.addOne);
92
101
  this.flash(reaction);
102
+ const exp = ufoExperiences.add.getInstance(`${ari}|${emojiId}`); // ufo start reaction experience
103
+
104
+ exp.start();
93
105
  this.client.addReaction(containerAri, ari, emojiId, this.metadata).then(_ => {
94
106
  if (this.createAnalyticsEvent) {
95
- createAndFireSafe(this.createAnalyticsEvent, createRestSucceededEvent, 'addReaction');
96
- }
107
+ Analytics.createAndFireSafe(this.createAnalyticsEvent, Analytics.createRestSucceededEvent, 'addReaction');
108
+ } // ufo add reaction success
109
+
110
+
111
+ exp.success();
97
112
  }).catch(error => {
98
113
  if (this.createAnalyticsEvent && isRealErrorFromService(error.code)) {
99
- createAndFireSafe(this.createAnalyticsEvent, createRestFailedEvent, 'addReaction', error.code);
114
+ this.createAnalyticsEvent && Analytics.createAndFireSafe(this.createAnalyticsEvent, Analytics.createRestFailedEvent, 'addReaction', error.code); // ufo add reaction failure
115
+
116
+ exp.failure({
117
+ metadata: {
118
+ error
119
+ }
120
+ });
100
121
  }
101
122
 
102
123
  return Promise.reject(error);
@@ -109,8 +130,21 @@ export class MemoryReactionsStore {
109
130
  ari,
110
131
  emojiId
111
132
  } = reaction;
133
+ const exp = ufoExperiences.remove.getInstance(`${ari}|${emojiId}`); // ufo start reaction experience
134
+
135
+ exp.start();
112
136
  this.optmisticUpdate(containerAri, ari, emojiId)(utils.removeOne);
113
- this.client.deleteReaction(containerAri, ari, emojiId, this.metadata);
137
+ this.client.deleteReaction(containerAri, ari, emojiId, this.metadata).then(_ => {
138
+ // ufo add reaction success
139
+ exp.success();
140
+ }).catch(error => {
141
+ // ufo add reaction failure
142
+ exp.failure({
143
+ metadata: {
144
+ error
145
+ }
146
+ });
147
+ });
114
148
  });
115
149
 
116
150
  _defineProperty(this, "setCreateAnalyticsEvent", createAnalyticsEvent => {
@@ -118,22 +152,34 @@ export class MemoryReactionsStore {
118
152
  });
119
153
 
120
154
  _defineProperty(this, "getReactions", batchByKey((containerAri, aris) => {
155
+ /**
156
+ * TODO:
157
+ * All reactions are usually fetched in a single call to reactions-service. Need to check why "getReactions" gets called randomly 1-2 times everytime on each fetch request despite using same containerAri.
158
+ */
159
+ const exp = ufoExperiences.render.getInstance(containerAri); // ufo start reaction experience
160
+
161
+ exp.start();
121
162
  this.client.getReactions(containerAri, aris.reduce(utils.flattenAris)).then(value => {
122
163
  Object.keys(value).map(ari => {
123
164
  const reactionsState = this.getReactionsState(containerAri, ari);
124
- const reactions = reactionsState && reactionsState.status === ReactionStatus.ready ? reactionsState.reactions : undefined;
165
+ const reactions = reactionsState && reactionsState.status === Types.ReactionStatus.ready ? reactionsState.reactions : undefined;
125
166
  this.setReactions(containerAri, ari, utils.readyState(value[ari].sort(utils.getReactionsSortFunction(reactions))));
126
167
  });
127
168
  }).then(() => {
128
169
  if (this.createAnalyticsEvent) {
129
- createAndFireSafe(this.createAnalyticsEvent, createRestSucceededEvent, 'getReactions');
170
+ Analytics.createAndFireSafe(this.createAnalyticsEvent, Analytics.createRestSucceededEvent, 'getReactions');
130
171
  }
172
+
173
+ exp.success();
131
174
  }).catch(error => {
132
- if (this.createAnalyticsEvent && isRealErrorFromService(error.code)) {
133
- createAndFireSafe(this.createAnalyticsEvent, createRestFailedEvent, 'getReactions', error.code);
134
- }
175
+ if (isRealErrorFromService(error.code)) {
176
+ if (this.createAnalyticsEvent) {
177
+ Analytics.createAndFireSafe(this.createAnalyticsEvent, Analytics.createRestFailedEvent, 'getReactions', error.code);
178
+ }
135
179
 
136
- return Promise.reject(error);
180
+ exp.failure();
181
+ return Promise.reject(error);
182
+ }
137
183
  });
138
184
  }));
139
185
 
@@ -189,7 +235,7 @@ export class MemoryReactionsStore {
189
235
  return updater => {
190
236
  const reactionsState = this.getReactionsState(containerAri, ari);
191
237
 
192
- if (reactionsState.status === ReactionStatus.ready) {
238
+ if (reactionsState.status === Types.ReactionStatus.ready) {
193
239
  const updated = updater(reactionsState);
194
240
 
195
241
  if (updated) {
File without changes
File without changes
File without changes
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "name": "@atlaskit/reactions",
3
- "version": "21.1.0"
3
+ "version": "21.2.0"
4
4
  }
@@ -7,6 +7,8 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
7
7
  import { createAndFireEvent } from '@atlaskit/analytics-next';
8
8
  import { UI_EVENT_TYPE, OPERATIONAL_EVENT_TYPE } from '@atlaskit/analytics-gas-types';
9
9
  import { name as packageName, version as packageVersion } from '../version.json';
10
+ import * as _UFO from './ufo';
11
+ export { _UFO as UFO };
10
12
  export var createAndFireEventInElementsChannel = createAndFireEvent('fabric-elements');
11
13
  export var createAndFireSafe = function createAndFireSafe(createAnalyticsEvent, creator) {
12
14
  if (createAnalyticsEvent) {
@@ -0,0 +1,62 @@
1
+ import { ConcurrentExperience, UFOExperience, ExperiencePerformanceTypes, ExperienceTypes } from '@atlaskit/ufo';
2
+ /**
3
+ * Initial experience config object (deferred from @atlaskit/ufo inner types)
4
+ * TODO: Check if possible to add this to exported types from @atlaskit/ufo
5
+ */
6
+
7
+ /**
8
+ * Helper method for create the config type for an individual/Concurrent experience
9
+ * @param componentName
10
+ */
11
+ var createExperienceConfig = function createExperienceConfig(componentName, type, performanceType) {
12
+ return {
13
+ platform: {
14
+ component: componentName
15
+ },
16
+ type: type,
17
+ performanceType: performanceType
18
+ };
19
+ };
20
+ /**
21
+ * Types of experiences
22
+ */
23
+
24
+
25
+ export var ExperienceName;
26
+ /**
27
+ * UFO types of components been instrumented
28
+ */
29
+
30
+ (function (ExperienceName) {
31
+ ExperienceName["REACTIONS_RENDERED"] = "reactions-rendered";
32
+ ExperienceName["PICKER_OPENED"] = "reactions-picker-opened";
33
+ ExperienceName["REACTION_ADDED"] = "reaction-added";
34
+ ExperienceName["REACTION_REMOVED"] = "reaction-removed";
35
+ })(ExperienceName || (ExperienceName = {}));
36
+
37
+ var ComponentName;
38
+ /**
39
+ * Experience when the emoji picker is opened
40
+ */
41
+
42
+ (function (ComponentName) {
43
+ ComponentName["PICKER_RENDERED"] = "reactions-picker";
44
+ ComponentName["REACTIONS"] = "reactions-list";
45
+ })(ComponentName || (ComponentName = {}));
46
+
47
+ export var PickerRender = new UFOExperience(ExperienceName.PICKER_OPENED, createExperienceConfig(ComponentName.PICKER_RENDERED, ExperienceTypes.Experience, ExperiencePerformanceTypes.InlineResult));
48
+ /**
49
+ * Experience when the list of reactions gets rendered
50
+ */
51
+
52
+ export var ReactionsRendered = new ConcurrentExperience(ExperienceName.REACTIONS_RENDERED, createExperienceConfig(ComponentName.REACTIONS, ExperienceTypes.Experience, ExperiencePerformanceTypes.InlineResult));
53
+ /**
54
+ * Experience when a reaction emoji gets added
55
+ */
56
+
57
+ export var ReactionsAdd = new ConcurrentExperience(ExperienceName.REACTION_ADDED, createExperienceConfig(ComponentName.REACTIONS, ExperienceTypes.Experience, ExperiencePerformanceTypes.InlineResult));
58
+ /**
59
+ * Experience when a reaction emoji gets removed/decrement
60
+ */
61
+
62
+ export var ReactionsRemove = new ConcurrentExperience(ExperienceName.REACTION_REMOVED, createExperienceConfig(ComponentName.REACTIONS, ExperienceTypes.Experience, ExperiencePerformanceTypes.InlineResult));
@@ -15,17 +15,17 @@ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflec
15
15
  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; } }
16
16
 
17
17
  /** @jsx jsx */
18
+ import React, { Fragment, PureComponent } from 'react';
19
+ import ReactDOM from 'react-dom';
18
20
  import { jsx, css } from '@emotion/core';
19
21
  import { EmojiPicker } from '@atlaskit/emoji/picker';
20
22
  import { Manager, Popper, Reference } from '@atlaskit/popper';
21
23
  import { borderRadius } from '@atlaskit/theme/constants';
22
24
  import { N0, N50A, N60A } from '@atlaskit/theme/colors';
23
25
  import { token } from '@atlaskit/tokens';
24
- import React, { Fragment } from 'react';
25
- import { PureComponent } from 'react';
26
- import ReactDOM from 'react-dom';
27
26
  import { Selector } from './Selector';
28
27
  import { Trigger } from './Trigger';
28
+ import { UFO } from '../analytics';
29
29
  import { layers } from '@atlaskit/theme/constants';
30
30
  var pickerStyle = css({
31
31
  verticalAlign: 'middle',
@@ -110,6 +110,9 @@ export var ReactionPicker = /*#__PURE__*/function (_PureComponent) {
110
110
  });
111
111
 
112
112
  _defineProperty(_assertThisInitialized(_this), "onTriggerClick", function () {
113
+ // ufo start reaction experience
114
+ UFO.PickerRender.start();
115
+
113
116
  if (_this.props.onOpen) {
114
117
  _this.props.onOpen();
115
118
  }
@@ -117,6 +120,9 @@ export var ReactionPicker = /*#__PURE__*/function (_PureComponent) {
117
120
  _this.setState({
118
121
  isOpen: !_this.state.isOpen,
119
122
  showFullPicker: false
123
+ }, function () {
124
+ // ufo add reaction success
125
+ UFO.PickerRender.success();
120
126
  });
121
127
  });
122
128
 
@@ -160,6 +166,7 @@ export var ReactionPicker = /*#__PURE__*/function (_PureComponent) {
160
166
  key: "componentWillUnmount",
161
167
  value: function componentWillUnmount() {
162
168
  document.removeEventListener('click', this.handleClickOutside);
169
+ UFO.PickerRender.abort();
163
170
  }
164
171
  }, {
165
172
  key: "close",
@@ -167,6 +174,9 @@ export var ReactionPicker = /*#__PURE__*/function (_PureComponent) {
167
174
  this.setState({
168
175
  isOpen: false,
169
176
  showFullPicker: false
177
+ }, function () {
178
+ // ufo abort reaction experience
179
+ UFO.PickerRender.abort();
170
180
  });
171
181
  }
172
182
  }, {
@@ -0,0 +1,54 @@
1
+ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
2
+ import _createClass from "@babel/runtime/helpers/createClass";
3
+ import _inherits from "@babel/runtime/helpers/inherits";
4
+ import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
5
+ import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
6
+
7
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
8
+
9
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
10
+
11
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
12
+
13
+ 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); }; }
14
+
15
+ 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; } }
16
+
17
+ import React from 'react';
18
+ export var UfoErrorBoundary = /*#__PURE__*/function (_React$Component) {
19
+ _inherits(UfoErrorBoundary, _React$Component);
20
+
21
+ var _super = _createSuper(UfoErrorBoundary);
22
+
23
+ function UfoErrorBoundary() {
24
+ _classCallCheck(this, UfoErrorBoundary);
25
+
26
+ return _super.apply(this, arguments);
27
+ }
28
+
29
+ _createClass(UfoErrorBoundary, [{
30
+ key: "componentDidCatch",
31
+ value: function componentDidCatch() {
32
+ var _iterator = _createForOfIteratorHelper(this.props.experiences),
33
+ _step;
34
+
35
+ try {
36
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
37
+ var e = _step.value;
38
+ e.failure();
39
+ }
40
+ } catch (err) {
41
+ _iterator.e(err);
42
+ } finally {
43
+ _iterator.f();
44
+ }
45
+ }
46
+ }, {
47
+ key: "render",
48
+ value: function render() {
49
+ return this.props.children;
50
+ }
51
+ }]);
52
+
53
+ return UfoErrorBoundary;
54
+ }(React.Component);
@@ -1,3 +1,4 @@
1
1
  export { Reaction } from './Reaction';
2
2
  export { ReactionPicker } from './ReactionPicker';
3
- export { Reactions } from './Reactions';
3
+ export { Reactions } from './Reactions';
4
+ export { UfoErrorBoundary } from './UfoErrorBoundary';