@atlaskit/link-create 0.2.1 → 0.3.1

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 (68) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/analytics.spec.yaml +85 -0
  3. package/dist/cjs/common/constants.js +10 -0
  4. package/dist/cjs/common/utils/analytics/analytics.codegen.js +27 -0
  5. package/dist/cjs/common/utils/analytics/context.js +103 -0
  6. package/dist/cjs/common/utils/analytics/index.js +18 -0
  7. package/dist/cjs/controllers/callback-context/main.js +17 -3
  8. package/dist/cjs/ui/create-form/main.js +29 -14
  9. package/dist/cjs/ui/create-form/styled.js +13 -0
  10. package/dist/cjs/ui/error-boundary/error-boundary-base/index.js +56 -0
  11. package/dist/cjs/ui/error-boundary/error-boundary-ui/error-svg/index.js +62 -0
  12. package/dist/cjs/ui/error-boundary/error-boundary-ui/error-svg/styled.js +13 -0
  13. package/dist/cjs/ui/error-boundary/error-boundary-ui/index.js +41 -0
  14. package/dist/cjs/ui/error-boundary/error-boundary-ui/messages.js +20 -0
  15. package/dist/cjs/ui/error-boundary/index.js +38 -0
  16. package/dist/cjs/ui/main.js +58 -14
  17. package/dist/cjs/version.json +1 -1
  18. package/dist/es2019/common/constants.js +2 -0
  19. package/dist/es2019/common/utils/analytics/analytics.codegen.js +20 -0
  20. package/dist/es2019/common/utils/analytics/context.js +86 -0
  21. package/dist/es2019/common/utils/analytics/index.js +1 -0
  22. package/dist/es2019/controllers/callback-context/main.js +18 -2
  23. package/dist/es2019/ui/create-form/main.js +26 -9
  24. package/dist/es2019/ui/create-form/styled.js +7 -0
  25. package/dist/es2019/ui/error-boundary/error-boundary-base/index.js +32 -0
  26. package/dist/es2019/ui/error-boundary/error-boundary-ui/error-svg/index.js +52 -0
  27. package/dist/es2019/ui/error-boundary/error-boundary-ui/error-svg/styled.js +7 -0
  28. package/dist/es2019/ui/error-boundary/error-boundary-ui/index.js +28 -0
  29. package/dist/es2019/ui/error-boundary/error-boundary-ui/messages.js +13 -0
  30. package/dist/es2019/ui/error-boundary/index.js +29 -0
  31. package/dist/es2019/ui/main.js +57 -13
  32. package/dist/es2019/version.json +1 -1
  33. package/dist/esm/common/constants.js +2 -0
  34. package/dist/esm/common/utils/analytics/analytics.codegen.js +20 -0
  35. package/dist/esm/common/utils/analytics/context.js +91 -0
  36. package/dist/esm/common/utils/analytics/index.js +1 -0
  37. package/dist/esm/controllers/callback-context/main.js +16 -3
  38. package/dist/esm/ui/create-form/main.js +29 -13
  39. package/dist/esm/ui/create-form/styled.js +5 -0
  40. package/dist/esm/ui/error-boundary/error-boundary-base/index.js +45 -0
  41. package/dist/esm/ui/error-boundary/error-boundary-ui/error-svg/index.js +54 -0
  42. package/dist/esm/ui/error-boundary/error-boundary-ui/error-svg/styled.js +5 -0
  43. package/dist/esm/ui/error-boundary/error-boundary-ui/index.js +32 -0
  44. package/dist/esm/ui/error-boundary/error-boundary-ui/messages.js +13 -0
  45. package/dist/esm/ui/error-boundary/index.js +27 -0
  46. package/dist/esm/ui/main.js +53 -12
  47. package/dist/esm/version.json +1 -1
  48. package/dist/types/common/constants.d.ts +2 -0
  49. package/dist/types/common/types.d.ts +80 -0
  50. package/dist/types/common/utils/analytics/analytics.codegen.d.ts +48 -0
  51. package/dist/types/common/utils/analytics/context.d.ts +29 -0
  52. package/dist/types/common/utils/analytics/index.d.ts +1 -0
  53. package/dist/types/controllers/callback-context/main.d.ts +5 -1
  54. package/dist/types/index.d.ts +2 -2
  55. package/dist/types/ui/create-form/main.d.ts +3 -1
  56. package/dist/types/ui/create-form/styled.d.ts +1 -0
  57. package/dist/types/ui/error-boundary/error-boundary-base/index.d.ts +18 -0
  58. package/dist/types/ui/error-boundary/error-boundary-ui/error-svg/index.d.ts +4 -0
  59. package/dist/types/ui/error-boundary/error-boundary-ui/error-svg/styled.d.ts +1 -0
  60. package/dist/types/ui/error-boundary/error-boundary-ui/index.d.ts +3 -0
  61. package/dist/types/ui/error-boundary/error-boundary-ui/messages.d.ts +13 -0
  62. package/dist/types/ui/error-boundary/index.d.ts +2 -0
  63. package/dist/types/ui/group-selection/types.d.ts +1 -14
  64. package/dist/types/ui/main.d.ts +6 -3
  65. package/dist/types/ui/types.d.ts +0 -61
  66. package/package.json +12 -5
  67. package/report.api.md +16 -15
  68. package/tmp/api-report-tmp.d.ts +14 -6
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.ErrorBoundaryUI = exports.CONTACT_SUPPORT_LINK = void 0;
8
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
+ var _react = _interopRequireDefault(require("react"));
10
+ var _reactIntlNext = require("react-intl-next");
11
+ var _button = _interopRequireDefault(require("@atlaskit/button"));
12
+ var _emptyState = _interopRequireDefault(require("@atlaskit/empty-state"));
13
+ var _errorSvg = _interopRequireDefault(require("./error-svg"));
14
+ var _messages = _interopRequireDefault(require("./messages"));
15
+ var CONTACT_SUPPORT_LINK = 'https://support.atlassian.com/contact/';
16
+ exports.CONTACT_SUPPORT_LINK = CONTACT_SUPPORT_LINK;
17
+ var ErrorBoundaryUI = function ErrorBoundaryUI() {
18
+ var intl = (0, _reactIntlNext.useIntl)();
19
+ return /*#__PURE__*/_react.default.createElement(_emptyState.default, {
20
+ maxImageWidth: 82,
21
+ testId: 'link-create-error-boundary-ui',
22
+ header: intl.formatMessage(_messages.default.heading),
23
+ description: /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage, (0, _extends2.default)({}, _messages.default.description, {
24
+ values: {
25
+ a: function a(label) {
26
+ return /*#__PURE__*/_react.default.createElement(_button.default, {
27
+ appearance: "link",
28
+ spacing: "none",
29
+ href: CONTACT_SUPPORT_LINK,
30
+ target: "_blank",
31
+ rel: "noopener noreferrer"
32
+ }, label);
33
+ }
34
+ }
35
+ })),
36
+ renderImage: function renderImage() {
37
+ return /*#__PURE__*/_react.default.createElement(_errorSvg.default, null);
38
+ }
39
+ });
40
+ };
41
+ exports.ErrorBoundaryUI = ErrorBoundaryUI;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _reactIntlNext = require("react-intl-next");
8
+ var _default = (0, _reactIntlNext.defineMessages)({
9
+ heading: {
10
+ id: 'link-create.unknown-error.heading',
11
+ defaultMessage: 'Something went wrong',
12
+ description: 'Heading when an unknown error occurs'
13
+ },
14
+ description: {
15
+ id: 'link-create.unknown-error.description',
16
+ defaultMessage: '<a>Contact Support</a> if refreshing doesn’t fix things.',
17
+ description: 'Description when an unknown error occurs'
18
+ }
19
+ });
20
+ exports.default = _default;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _typeof = require("@babel/runtime/helpers/typeof");
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.ErrorBoundary = void 0;
9
+ var _react = _interopRequireWildcard(require("react"));
10
+ var _analyticsNext = require("@atlaskit/analytics-next");
11
+ var _constants = require("../../common/constants");
12
+ var _analytics = _interopRequireDefault(require("../../common/utils/analytics/analytics.codegen"));
13
+ var _errorBoundaryBase = require("./error-boundary-base");
14
+ var _errorBoundaryUi = require("./error-boundary-ui");
15
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
16
+ 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; }
17
+ var ErrorBoundary = function ErrorBoundary(_ref) {
18
+ var children = _ref.children;
19
+ var _useAnalyticsEvents = (0, _analyticsNext.useAnalyticsEvents)(),
20
+ createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
21
+ var handleError = (0, _react.useCallback)(function (error, info) {
22
+ var _window, _window$navigator, _info$componentStack;
23
+ // Fire Analytics event
24
+ createAnalyticsEvent((0, _analytics.default)('operational.linkCreate.unhandledErrorCaught', {
25
+ browserInfo: ((_window = window) === null || _window === void 0 ? void 0 : (_window$navigator = _window.navigator) === null || _window$navigator === void 0 ? void 0 : _window$navigator.userAgent) || 'unknown',
26
+ error: error.toString(),
27
+ componentStack: (_info$componentStack = info === null || info === void 0 ? void 0 : info.componentStack) !== null && _info$componentStack !== void 0 ? _info$componentStack : ''
28
+ })).fire(_constants.ANALYTICS_CHANNEL);
29
+
30
+ // Fire UFO failed experience
31
+ // failUfoExperience(ufoExperience.mounted);
32
+ }, [createAnalyticsEvent]);
33
+ return /*#__PURE__*/_react.default.createElement(_errorBoundaryBase.BaseErrorBoundary, {
34
+ onError: handleError,
35
+ ErrorComponent: _errorBoundaryUi.ErrorBoundaryUI
36
+ }, children);
37
+ };
38
+ exports.ErrorBoundary = ErrorBoundary;
@@ -1,38 +1,82 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
3
4
  var _typeof = require("@babel/runtime/helpers/typeof");
4
5
  Object.defineProperty(exports, "__esModule", {
5
6
  value: true
6
7
  });
7
- exports.default = LinkCreate;
8
- var _react = require("@emotion/react");
8
+ exports.default = exports.PACKAGE_DATA = void 0;
9
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
10
+ var _react = require("react");
11
+ var _react2 = require("@emotion/react");
12
+ var _analyticsNext = require("@atlaskit/analytics-next");
9
13
  var _modalDialog = _interopRequireWildcard(require("@atlaskit/modal-dialog"));
14
+ var _constants = require("../common/constants");
15
+ var _analytics = require("../common/utils/analytics");
16
+ var _analytics2 = _interopRequireDefault(require("../common/utils/analytics/analytics.codegen"));
10
17
  var _callbackContext = require("../controllers/callback-context");
18
+ var _version = require("../version.json");
19
+ var _errorBoundary = require("./error-boundary");
11
20
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
12
21
  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; }
13
22
  /** @jsx jsx */
14
23
 
15
- function LinkCreate(_ref) {
24
+ var LinkCreate = function LinkCreate(_ref) {
16
25
  var plugins = _ref.plugins,
17
- testId = _ref.testId,
18
- groupKey = _ref.groupKey,
19
26
  entityKey = _ref.entityKey,
20
27
  onCreate = _ref.onCreate,
21
28
  onFailure = _ref.onFailure,
22
- onCancel = _ref.onCancel,
23
- active = _ref.active;
29
+ onCancel = _ref.onCancel;
24
30
  var chosenOne = plugins.find(function (plugin) {
25
31
  return plugin.key === entityKey;
26
32
  });
27
33
  if (!chosenOne) {
28
34
  throw new Error('Make sure you specified a valid entityKey');
29
35
  }
30
- return (0, _react.jsx)(_modalDialog.ModalTransition, null, !!active && (0, _react.jsx)(_modalDialog.default, {
31
- onClose: onCancel,
32
- testId: testId
33
- }, (0, _react.jsx)(_modalDialog.ModalHeader, null, (0, _react.jsx)(_modalDialog.ModalTitle, null, "Create New")), (0, _react.jsx)(_modalDialog.ModalBody, null, (0, _react.jsx)(_callbackContext.LinkCreateCallbackProvider, {
34
- onCreate: onCreate,
36
+ var handleCreate = (0, _react.useCallback)(function (result) {
37
+ onCreate && onCreate(result.url);
38
+ }, [onCreate]);
39
+ return (0, _react2.jsx)(_callbackContext.LinkCreateCallbackProvider, {
40
+ onCreate: handleCreate,
35
41
  onFailure: onFailure,
36
42
  onCancel: onCancel
37
- }, chosenOne.form))));
38
- }
43
+ }, chosenOne.form);
44
+ };
45
+ var LinkCreateWithModal = function LinkCreateWithModal(props) {
46
+ var testId = props.testId,
47
+ onCancel = props.onCancel,
48
+ active = props.active;
49
+ var _useAnalyticsEvents = (0, _analyticsNext.useAnalyticsEvents)(),
50
+ createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
51
+ var handleOpenComplete = (0, _react.useCallback)(function () {
52
+ createAnalyticsEvent((0, _analytics2.default)('screen.linkCreateScreen.viewed', {})).fire(_constants.ANALYTICS_CHANNEL);
53
+ }, [createAnalyticsEvent]);
54
+ var handleCloseComplete = (0, _react.useCallback)(function () {
55
+ createAnalyticsEvent((0, _analytics2.default)('screen.linkCreateScreen.closed', {})).fire(_constants.ANALYTICS_CHANNEL);
56
+ }, [createAnalyticsEvent]);
57
+ return (0, _react2.jsx)(_modalDialog.ModalTransition, null, !!active && (0, _react2.jsx)(_modalDialog.default, {
58
+ onClose: onCancel,
59
+ testId: testId,
60
+ shouldScrollInViewport: true,
61
+ onOpenComplete: handleOpenComplete,
62
+ onCloseComplete: handleCloseComplete
63
+ }, (0, _react2.jsx)(_modalDialog.ModalHeader, null, (0, _react2.jsx)(_modalDialog.ModalTitle, null, "Create New")), (0, _react2.jsx)(_modalDialog.ModalBody, null, (0, _react2.jsx)(_errorBoundary.ErrorBoundary, null, (0, _react2.jsx)(LinkCreate, props)))));
64
+ };
65
+ var LinkCreateWithAnalyticsContext = (0, _analytics.withLinkCreateAnalyticsContext)( /*#__PURE__*/(0, _react.memo)(function (_ref2) {
66
+ var props = (0, _extends2.default)({}, _ref2);
67
+ return (0, _react2.jsx)(LinkCreateWithModal, props);
68
+ }));
69
+ var PACKAGE_DATA = {
70
+ packageName: _version.name,
71
+ packageVersion: _version.version,
72
+ componentName: _constants.COMPONENT_NAME,
73
+ source: _constants.COMPONENT_NAME
74
+ };
75
+ exports.PACKAGE_DATA = PACKAGE_DATA;
76
+ var ComposedLinkCreate = /*#__PURE__*/(0, _react.memo)(function (props) {
77
+ return (0, _react2.jsx)(_analyticsNext.AnalyticsContext, {
78
+ data: PACKAGE_DATA
79
+ }, (0, _react2.jsx)(LinkCreateWithAnalyticsContext, props));
80
+ });
81
+ var _default = ComposedLinkCreate;
82
+ exports.default = _default;
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/link-create",
3
- "version": "0.2.1",
3
+ "version": "0.3.1",
4
4
  "sideEffects": false
5
5
  }
@@ -0,0 +1,2 @@
1
+ export const ANALYTICS_CHANNEL = 'media';
2
+ export const COMPONENT_NAME = 'linkCreate';
@@ -0,0 +1,20 @@
1
+ /**
2
+ * THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
3
+ *
4
+ * Generates Typescript types for analytics events from analytics.spec.yaml
5
+ *
6
+ * @codegen <<SignedSource::6d7803f5c035dc3cde1be03caa91eb04>>
7
+ * @codegenCommand yarn workspace @atlaskit/link-create run codegen-analytics
8
+ */
9
+
10
+ function createEventPayload(eventKey, attributes) {
11
+ const event = eventKey.split('.');
12
+ return {
13
+ eventType: event[0],
14
+ actionSubject: event[1],
15
+ action: event[2],
16
+ actionSubjectId: event[3],
17
+ attributes: attributes
18
+ };
19
+ }
20
+ export default createEventPayload;
@@ -0,0 +1,86 @@
1
+ import React, { useCallback, useContext, useMemo, useRef, useState } from 'react';
2
+ import { AnalyticsListener } from '@atlaskit/analytics-next';
3
+ import { ANALYTICS_CHANNEL } from '../../constants';
4
+ const UNKNOWN = 'unknown';
5
+ const DEFAULT_CONTEXT_ATTRIBUTES = {
6
+ triggeredFrom: UNKNOWN,
7
+ objectName: UNKNOWN,
8
+ appearance: 'modal'
9
+ };
10
+ const LinkCreateAnalyticsContext = /*#__PURE__*/React.createContext({
11
+ trackAttribute: () => {},
12
+ trackAttributes: () => {},
13
+ getAttributes: () => DEFAULT_CONTEXT_ATTRIBUTES
14
+ });
15
+ const LinkCreateAnalytics = ({
16
+ initialContext,
17
+ children
18
+ }) => {
19
+ const dataRef = useRef({
20
+ ...DEFAULT_CONTEXT_ATTRIBUTES,
21
+ ...initialContext
22
+ });
23
+ const methods = useMemo(() => ({
24
+ trackAttribute: (key, value) => {
25
+ dataRef.current[key] = value;
26
+ },
27
+ trackAttributes: attributes => {
28
+ dataRef.current = {
29
+ ...dataRef.current,
30
+ ...attributes
31
+ };
32
+ },
33
+ getAttributes: () => dataRef.current
34
+ }), []);
35
+ return /*#__PURE__*/React.createElement(LinkCreateAnalyticsContext.Provider, {
36
+ value: methods
37
+ }, children);
38
+ };
39
+ const contextAttributesFromInitialProps = props => {
40
+ return {
41
+ objectName: props.entityKey,
42
+ triggeredFrom: props.triggeredFrom
43
+ };
44
+ };
45
+
46
+ /**
47
+ * Hook that exposes the context-level attribute getters and setters.
48
+ */
49
+ export const useLinkCreateAnalytics = () => useContext(LinkCreateAnalyticsContext);
50
+
51
+ /**
52
+ * Wrap component in "attributes" context store and initialise the initial context attributes from props.
53
+ */
54
+ function withLinkCreateAnalytics(WrappedComponent) {
55
+ return props => {
56
+ const [initialContext] = useState(() => contextAttributesFromInitialProps(props));
57
+ return /*#__PURE__*/React.createElement(LinkCreateAnalytics, {
58
+ initialContext: initialContext
59
+ }, /*#__PURE__*/React.createElement(WrappedComponent, props));
60
+ };
61
+ }
62
+
63
+ /**
64
+ * Wraps a component with the analytics context + listener to update events with contextual-level attributes.
65
+ * Should be implemented once at the root of the link create.
66
+ */
67
+ export function withLinkCreateAnalyticsContext(WrappedComponent) {
68
+ return withLinkCreateAnalytics(props => {
69
+ const {
70
+ getAttributes
71
+ } = useLinkCreateAnalytics();
72
+ const onEvent = useCallback(event => {
73
+ var _event$payload$attrib;
74
+ event.update({
75
+ attributes: {
76
+ ...getAttributes(),
77
+ ...((_event$payload$attrib = event.payload.attributes) !== null && _event$payload$attrib !== void 0 ? _event$payload$attrib : {})
78
+ }
79
+ });
80
+ }, [getAttributes]);
81
+ return /*#__PURE__*/React.createElement(AnalyticsListener, {
82
+ channel: ANALYTICS_CHANNEL,
83
+ onEvent: onEvent
84
+ }, /*#__PURE__*/React.createElement(WrappedComponent, props));
85
+ });
86
+ }
@@ -0,0 +1 @@
1
+ export { useLinkCreateAnalytics, withLinkCreateAnalyticsContext } from './context';
@@ -1,4 +1,7 @@
1
1
  import React, { useContext, useMemo } from 'react';
2
+ import { useAnalyticsEvents } from '@atlaskit/analytics-next';
3
+ import { ANALYTICS_CHANNEL } from '../../common/constants';
4
+ import createEventPayload from '../../common/utils/analytics/analytics.codegen';
2
5
  const LinkCreateCallbackContext = /*#__PURE__*/React.createContext({});
3
6
  const LinkCreateCallbackProvider = ({
4
7
  children,
@@ -6,11 +9,24 @@ const LinkCreateCallbackProvider = ({
6
9
  onFailure,
7
10
  onCancel
8
11
  }) => {
12
+ const {
13
+ createAnalyticsEvent
14
+ } = useAnalyticsEvents();
9
15
  const value = useMemo(() => ({
10
- onCreate,
16
+ onCreate: result => {
17
+ const {
18
+ objectId,
19
+ objectType
20
+ } = result;
21
+ createAnalyticsEvent(createEventPayload('track.object.created.linkCreate', {
22
+ objectId,
23
+ objectType
24
+ })).fire(ANALYTICS_CHANNEL);
25
+ onCreate && onCreate(result);
26
+ },
11
27
  onFailure,
12
28
  onCancel
13
- }), [onCreate, onFailure, onCancel]);
29
+ }), [onFailure, onCancel, createAnalyticsEvent, onCreate]);
14
30
  return /*#__PURE__*/React.createElement(LinkCreateCallbackContext.Provider, {
15
31
  value: value
16
32
  }, children);
@@ -1,21 +1,31 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
- import React from 'react';
2
+ /** @jsx jsx */
3
+ import React, { useCallback } from 'react';
4
+ import { jsx } from '@emotion/react';
5
+ import { useAnalyticsEvents } from '@atlaskit/analytics-next';
3
6
  import LoadingButton from '@atlaskit/button/loading-button';
4
7
  import Button from '@atlaskit/button/standard-button';
5
8
  import Form, { FormFooter, FormSection } from '@atlaskit/form';
9
+ import { ANALYTICS_CHANNEL } from '../../common/constants';
10
+ import createEventPayload from '../../common/utils/analytics/analytics.codegen';
6
11
  import { FormContextProvider, useFormContext } from '../../controllers/form-context';
12
+ import { formStyles } from './styled';
7
13
  import { validateFormData } from './utils';
8
- const withFormContext = Component => props => /*#__PURE__*/React.createElement(FormContextProvider, null, /*#__PURE__*/React.createElement(Component, props));
14
+ const withFormContext = Component => props => jsx(FormContextProvider, null, jsx(Component, props));
9
15
  const CreateFormWithoutContext = ({
10
16
  children,
11
17
  testId,
12
18
  onCancel,
13
19
  onSubmit
14
20
  }) => {
21
+ const {
22
+ createAnalyticsEvent
23
+ } = useAnalyticsEvents();
15
24
  const {
16
25
  getValidators
17
26
  } = useFormContext();
18
- const handleSubmit = async data => {
27
+ const handleSubmit = useCallback(async data => {
28
+ createAnalyticsEvent(createEventPayload('ui.button.clicked.create', {})).fire(ANALYTICS_CHANNEL);
19
29
  const validators = getValidators();
20
30
  const errors = validateFormData({
21
31
  data,
@@ -25,20 +35,27 @@ const CreateFormWithoutContext = ({
25
35
  return errors;
26
36
  }
27
37
  onSubmit(data);
28
- };
29
- return /*#__PURE__*/React.createElement(Form, {
38
+ }, [createAnalyticsEvent, getValidators, onSubmit]);
39
+ const handleCancel = useCallback(() => {
40
+ createAnalyticsEvent(createEventPayload('ui.button.clicked.cancel', {})).fire(ANALYTICS_CHANNEL);
41
+ onCancel && onCancel();
42
+ }, [createAnalyticsEvent, onCancel]);
43
+ return jsx(Form, {
30
44
  onSubmit: handleSubmit
31
45
  }, ({
32
46
  submitting,
33
47
  formProps
34
- }) => /*#__PURE__*/React.createElement("form", _extends({}, formProps, {
48
+ }) => jsx("form", _extends({}, formProps, {
35
49
  name: "confluence-creation-form",
36
50
  "data-testid": testId
37
- }), /*#__PURE__*/React.createElement(FormSection, null, children), /*#__PURE__*/React.createElement(FormFooter, null, /*#__PURE__*/React.createElement(Button, {
51
+ // eslint-disable-next-line @repo/internal/react/consistent-css-prop-usage
52
+ ,
53
+ css: formStyles
54
+ }), jsx(FormSection, null, children), jsx(FormFooter, null, jsx(Button, {
38
55
  appearance: "subtle",
39
- onClick: onCancel,
56
+ onClick: handleCancel,
40
57
  testId: 'cancel-button'
41
- }, "Cancel"), /*#__PURE__*/React.createElement(LoadingButton, {
58
+ }, "Cancel"), jsx(LoadingButton, {
42
59
  appearance: "primary",
43
60
  type: "submit",
44
61
  isLoading: submitting,
@@ -0,0 +1,7 @@
1
+ import { css } from '@emotion/react';
2
+ const CREATE_FORM_MAX_WIDTH_IN_PX = '600';
3
+ export const formStyles = css`
4
+ margin: 0 auto;
5
+ max-width: ${CREATE_FORM_MAX_WIDTH_IN_PX}px;
6
+ padding: 0 0 ${"var(--ds-space-300, 24px)"} 0;
7
+ `;
@@ -0,0 +1,32 @@
1
+ import React, { Component } from 'react';
2
+ // eslint-disable-next-line @repo/internal/react/no-class-components
3
+ export class BaseErrorBoundary extends Component {
4
+ constructor(props) {
5
+ super(props);
6
+ this.state = {
7
+ hasError: false
8
+ };
9
+ }
10
+ componentDidCatch(error, info) {
11
+ const {
12
+ onError
13
+ } = this.props;
14
+ onError && onError(error, info);
15
+ this.setState({
16
+ hasError: true
17
+ });
18
+ }
19
+ render() {
20
+ const {
21
+ children,
22
+ ErrorComponent
23
+ } = this.props;
24
+ const {
25
+ hasError
26
+ } = this.state;
27
+ if (hasError && ErrorComponent) {
28
+ return /*#__PURE__*/React.createElement(ErrorComponent, null);
29
+ }
30
+ return children;
31
+ }
32
+ }
@@ -0,0 +1,52 @@
1
+ /** @jsx jsx */
2
+ import { jsx } from '@emotion/react';
3
+ import { errorStyles } from './styled';
4
+ const ErrorSVG = () => jsx("svg", {
5
+ xmlns: "http://www.w3.org/2000/svg",
6
+ viewBox: "0 0 82 110"
7
+ // eslint-disable-next-line @repo/internal/react/consistent-css-prop-usage
8
+ ,
9
+ css: errorStyles
10
+ }, jsx("defs", null, jsx("linearGradient", {
11
+ id: "a",
12
+ x1: "81.992%",
13
+ x2: "-1.724%",
14
+ y1: "43.911%",
15
+ y2: "87.726%"
16
+ }, jsx("stop", {
17
+ offset: "0%",
18
+ stopColor: "#FFD740"
19
+ }), jsx("stop", {
20
+ offset: "100%",
21
+ stopColor: "#FFAB00"
22
+ }))), jsx("g", {
23
+ fill: "none",
24
+ fillRule: "evenodd"
25
+ }, jsx("path", {
26
+ fill: "url(#a)",
27
+ fillRule: "nonzero",
28
+ d: "M47.39 40.58l33.22 57.54a7.585 7.585 0 0 1-6.57 11.38H7.6a7.585 7.585 0 0 1-6.57-11.38l33.22-57.54a7.585 7.585 0 0 1 13.14 0z"
29
+ }), jsx("path", {
30
+ fill: "#253858",
31
+ fillRule: "nonzero",
32
+ d: "M43.61 82.355l1.44-22.175a4.59 4.59 0 0 0-4.58-4.89 4.59 4.59 0 0 0-4.58 4.89l1.44 22.175a3.15 3.15 0 0 0 3.14 2.945 3.15 3.15 0 0 0 3.14-2.945zM35.69 94.125a4.765 4.765 0 0 0 5.195 4.79 4.84 4.84 0 0 0-.45-9.66 4.82 4.82 0 0 0-4.745 4.87z"
33
+ }), jsx("path", {
34
+ fill: "#FFC400",
35
+ fillRule: "nonzero",
36
+ d: "M45.85 14.085L42.145.725a.305.305 0 0 0-.595.025L39.22 13.3l-2.9-.54a.305.305 0 0 0-.35.38l3.705 13.36a.305.305 0 0 0 .595 0l2.33-12.55 2.9.515a.305.305 0 0 0 .35-.38z"
37
+ }), jsx("path", {
38
+ fill: "#FFAB00",
39
+ fillRule: "nonzero",
40
+ d: "M32.56 21.405l-5.44-4.275a.135.135 0 0 0-.205.165L29.68 23l-1.33.655a.135.135 0 0 0 0 .225l5.435 4.275a.135.135 0 0 0 .205-.165l-2.785-5.715 1.33-.645a.135.135 0 0 0 .025-.225z"
41
+ }), jsx("path", {
42
+ stroke: "#344563",
43
+ strokeLinecap: "round",
44
+ strokeWidth: "2",
45
+ d: "M57.575 18.8c-.585.795-5.5-2.8-6.08-2-.58.8 4.33 4.395 3.75 5.195-.58.8-5.5-2.8-6.085-2-.585.8 4.33 4.395 3.745 5.195-.585.8-5.5-2.8-6.085-2-.585.8 4.33 4.395 3.745 5.195"
46
+ }), jsx("path", {
47
+ stroke: "#5E6C84",
48
+ strokeLinecap: "round",
49
+ strokeWidth: "2",
50
+ d: "M59.96 32.595c-.73.665-3.525-2.39-4.255-1.72-.73.67 2.065 3.725 1.335 4.39-.73.665-3.525-2.39-4.255-1.72-.34.31.08 1.135.555 2M22.4 32.5c.91.385 2.5-3.435 3.43-3.05.93.385-.695 4.2.215 4.585.91.385 2.5-3.435 3.43-3.05.425.18.305 1.095.145 2.065"
51
+ })));
52
+ export default ErrorSVG;
@@ -0,0 +1,7 @@
1
+ import { css } from '@emotion/react';
2
+ const WIDTH = 82;
3
+ export const errorStyles = css`
4
+ width: ${WIDTH}px;
5
+ margin: 0 auto ${"var(--ds-space-300, 24px)"};
6
+ display: block;
7
+ `;
@@ -0,0 +1,28 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ import React from 'react';
3
+ import { FormattedMessage, useIntl } from 'react-intl-next';
4
+ import Button from '@atlaskit/button';
5
+ import EmptyState from '@atlaskit/empty-state';
6
+ import ErrorSVG from './error-svg';
7
+ import messages from './messages';
8
+ export const CONTACT_SUPPORT_LINK = 'https://support.atlassian.com/contact/';
9
+ export const ErrorBoundaryUI = () => {
10
+ const intl = useIntl();
11
+ return /*#__PURE__*/React.createElement(EmptyState, {
12
+ maxImageWidth: 82,
13
+ testId: 'link-create-error-boundary-ui',
14
+ header: intl.formatMessage(messages.heading),
15
+ description: /*#__PURE__*/React.createElement(FormattedMessage, _extends({}, messages.description, {
16
+ values: {
17
+ a: label => /*#__PURE__*/React.createElement(Button, {
18
+ appearance: "link",
19
+ spacing: "none",
20
+ href: CONTACT_SUPPORT_LINK,
21
+ target: "_blank",
22
+ rel: "noopener noreferrer"
23
+ }, label)
24
+ }
25
+ })),
26
+ renderImage: () => /*#__PURE__*/React.createElement(ErrorSVG, null)
27
+ });
28
+ };
@@ -0,0 +1,13 @@
1
+ import { defineMessages } from 'react-intl-next';
2
+ export default defineMessages({
3
+ heading: {
4
+ id: 'link-create.unknown-error.heading',
5
+ defaultMessage: 'Something went wrong',
6
+ description: 'Heading when an unknown error occurs'
7
+ },
8
+ description: {
9
+ id: 'link-create.unknown-error.description',
10
+ defaultMessage: '<a>Contact Support</a> if refreshing doesn’t fix things.',
11
+ description: 'Description when an unknown error occurs'
12
+ }
13
+ });
@@ -0,0 +1,29 @@
1
+ import React, { useCallback } from 'react';
2
+ import { useAnalyticsEvents } from '@atlaskit/analytics-next';
3
+ import { ANALYTICS_CHANNEL } from '../../common/constants';
4
+ import createEventPayload from '../../common/utils/analytics/analytics.codegen';
5
+ import { BaseErrorBoundary } from './error-boundary-base';
6
+ import { ErrorBoundaryUI } from './error-boundary-ui';
7
+ export const ErrorBoundary = ({
8
+ children
9
+ }) => {
10
+ const {
11
+ createAnalyticsEvent
12
+ } = useAnalyticsEvents();
13
+ const handleError = useCallback((error, info) => {
14
+ var _window, _window$navigator, _info$componentStack;
15
+ // Fire Analytics event
16
+ createAnalyticsEvent(createEventPayload('operational.linkCreate.unhandledErrorCaught', {
17
+ browserInfo: ((_window = window) === null || _window === void 0 ? void 0 : (_window$navigator = _window.navigator) === null || _window$navigator === void 0 ? void 0 : _window$navigator.userAgent) || 'unknown',
18
+ error: error.toString(),
19
+ componentStack: (_info$componentStack = info === null || info === void 0 ? void 0 : info.componentStack) !== null && _info$componentStack !== void 0 ? _info$componentStack : ''
20
+ })).fire(ANALYTICS_CHANNEL);
21
+
22
+ // Fire UFO failed experience
23
+ // failUfoExperience(ufoExperience.mounted);
24
+ }, [createAnalyticsEvent]);
25
+ return /*#__PURE__*/React.createElement(BaseErrorBoundary, {
26
+ onError: handleError,
27
+ ErrorComponent: ErrorBoundaryUI
28
+ }, children);
29
+ };