@atlaskit/give-kudos 0.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.
package/CHANGELOG.md ADDED
@@ -0,0 +1,19 @@
1
+ # @atlassian/give-kudos
2
+
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`dd476d8114a`](https://bitbucket.org/atlassian/atlassian-frontend/commits/dd476d8114a) - [ux] Move give kudos to a public package and rename to atlaskit/give-kudos
8
+
9
+ ## 0.1.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [`5bf301d7026`](https://bitbucket.org/atlassian/atlassian-frontend/commits/5bf301d7026) - [ux] Initial release
14
+
15
+ ## 0.0.1
16
+
17
+ ### Patch Changes
18
+
19
+ - [`650c976b33d`](https://bitbucket.org/atlassian/atlassian-frontend/commits/650c976b33d) - Initial version
package/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # GiveKudos
2
+
3
+ Give Kudos experience
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ Object.defineProperty(exports, "GiveKudosLauncher", {
9
+ enumerable: true,
10
+ get: function get() {
11
+ return _GiveKudosLauncher.default;
12
+ }
13
+ });
14
+
15
+ var _GiveKudosLauncher = _interopRequireDefault(require("./ui/GiveKudosLauncher"));
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _reactIntlNext = require("react-intl-next");
9
+
10
+ var messages = (0, _reactIntlNext.defineMessages)({
11
+ giveKudosButton: {
12
+ id: 'team-central.give-kudos.button',
13
+ defaultMessage: 'Give kudos',
14
+ description: 'Title for the button to give a kudos'
15
+ },
16
+ kudosCreatedFlag: {
17
+ id: 'team-central.give-kudos.created.title.flag',
18
+ defaultMessage: 'Kudos created',
19
+ description: 'Title text for kudos creation flag.'
20
+ },
21
+ kudosCreatedDescriptionFlag: {
22
+ id: 'team-central.give-kudos.created.description.flag',
23
+ defaultMessage: 'Your kudos has been sent. <a>View kudos</a>',
24
+ description: 'Description text for the kudos created flag. This includes a link to view the newly created kudos.'
25
+ },
26
+ unsavedKudosWarning: {
27
+ id: 'team-central.give-kudos.unsaved.warning',
28
+ defaultMessage: 'Changes that you made will not be saved.',
29
+ description: 'Shown when the user tries to navigate away from the kudos creation screen with unsaved changes.'
30
+ },
31
+ unsavedKudosWarningCancelButton: {
32
+ id: 'team-central.give-kudos.unsaved.warning.cancel',
33
+ defaultMessage: 'Cancel',
34
+ description: 'Button that cancels closing the create kudos drawer.'
35
+ },
36
+ unsavedKudosWarningCloseButton: {
37
+ id: 'team-central.give-kudos.unsaved.warning.close',
38
+ defaultMessage: 'Close',
39
+ description: 'Button that closes the warning modal and closes the drawer.'
40
+ }
41
+ });
42
+ var _default = messages;
43
+ exports.default = _default;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.KudosType = void 0;
7
+ var KudosType;
8
+ exports.KudosType = KudosType;
9
+
10
+ (function (KudosType) {
11
+ KudosType["INDIVIDUAL"] = "individual";
12
+ KudosType["TEAM"] = "team";
13
+ })(KudosType || (exports.KudosType = KudosType = {}));
@@ -0,0 +1,223 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ var _typeof = require("@babel/runtime/helpers/typeof");
6
+
7
+ Object.defineProperty(exports, "__esModule", {
8
+ value: true
9
+ });
10
+ exports.default = exports.GiveKudosLauncher = void 0;
11
+
12
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
13
+
14
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
15
+
16
+ var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral"));
17
+
18
+ var _react = _interopRequireWildcard(require("react"));
19
+
20
+ var _reactIntlNext = require("react-intl-next");
21
+
22
+ var _styledComponents = _interopRequireDefault(require("styled-components"));
23
+
24
+ var _standardButton = _interopRequireDefault(require("@atlaskit/button/standard-button"));
25
+
26
+ var _drawer = _interopRequireDefault(require("@atlaskit/drawer"));
27
+
28
+ var _arrowLeft = _interopRequireDefault(require("@atlaskit/icon/glyph/arrow-left"));
29
+
30
+ var _modalDialog = _interopRequireWildcard(require("@atlaskit/modal-dialog"));
31
+
32
+ var _messages = _interopRequireDefault(require("../../messages"));
33
+
34
+ var _styled = require("./styled");
35
+
36
+ var _templateObject;
37
+
38
+ 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); }
39
+
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; }
41
+
42
+ var GiveKudosDrawerWrapper = _styledComponents.default.span(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2.default)(["\n > Drawer > iframe {\n border: 0;\n }\n"])));
43
+
44
+ var GiveKudosLauncher = function GiveKudosLauncher(props) {
45
+ var _props$recipient;
46
+
47
+ var _useState = (0, _react.useState)(false),
48
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
49
+ isCloseConfirmModalOpen = _useState2[0],
50
+ setIsCloseConfirmModalOpen = _useState2[1];
51
+
52
+ var _useState3 = (0, _react.useState)(false),
53
+ _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
54
+ isDirty = _useState4[0],
55
+ setIsDirty = _useState4[1];
56
+
57
+ var iframeEl = (0, _react.useRef)(null);
58
+ var messageListenerEventHandler = (0, _react.useRef)(function (e) {});
59
+ var unloadEventHandler = (0, _react.useRef)(function (e) {});
60
+ var intl = (0, _reactIntlNext.useIntl)();
61
+ var addFlag = props.addFlag,
62
+ teamCentralBaseUrl = props.teamCentralBaseUrl,
63
+ analytics = props.analytics,
64
+ analyticsSource = props.analyticsSource,
65
+ onClose = props.onClose,
66
+ testId = props.testId;
67
+ var shouldBlockTransition = (0, _react.useCallback)(function (e) {
68
+ e.preventDefault();
69
+ e.returnValue = intl.formatMessage(_messages.default.unsavedKudosWarning);
70
+ }, [intl]);
71
+ var sendAnalytic = (0, _react.useCallback)(function (action, options) {
72
+ if (analytics && analyticsSource) {// TODO analytics(`${analyticsSource}.${action}`, options);
73
+ }
74
+ }, [analytics, analyticsSource]);
75
+ var closeDrawer = (0, _react.useCallback)(function () {
76
+ setIsDirty(false);
77
+ setIsCloseConfirmModalOpen(false);
78
+ onClose();
79
+ }, [onClose]);
80
+
81
+ var closeWarningModal = function closeWarningModal() {
82
+ setIsCloseConfirmModalOpen(false);
83
+ };
84
+
85
+ var messageListener = (0, _react.useCallback)(function (event) {
86
+ if (!props.isOpen) {
87
+ return;
88
+ }
89
+
90
+ if (String(event.data).startsWith('kudos-created-')) {
91
+ var uuid = String(event.data).replace(/^(kudos-created-)/, '');
92
+ closeDrawer();
93
+ sendAnalytic('created', {
94
+ id: 'createKudos'
95
+ });
96
+ addFlag && addFlag({
97
+ title: /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage, _messages.default.kudosCreatedFlag),
98
+ id: "kudosCreatedFlag-".concat(uuid),
99
+ description: /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage, (0, _extends2.default)({}, _messages.default.kudosCreatedDescriptionFlag, {
100
+ values: {
101
+ a: function a(s) {
102
+ return /*#__PURE__*/_react.default.createElement("a", {
103
+ href: "".concat(teamCentralBaseUrl, "/people/kudos/").concat(uuid)
104
+ }, s);
105
+ }
106
+ }
107
+ })),
108
+ icon: /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null)
109
+ });
110
+ } else if (event.data === 'dirty') {
111
+ setIsDirty(true);
112
+ } else if (event.data === 'close') {
113
+ closeDrawer();
114
+ }
115
+ }, [props.isOpen, addFlag, teamCentralBaseUrl, sendAnalytic, closeDrawer]);
116
+ (0, _react.useEffect)(function () {
117
+ window.removeEventListener('message', messageListenerEventHandler.current);
118
+ messageListenerEventHandler.current = messageListener;
119
+ window.addEventListener('message', messageListenerEventHandler.current, false);
120
+ return function () {
121
+ window.removeEventListener('message', messageListenerEventHandler.current);
122
+ };
123
+ }, [messageListener]);
124
+ (0, _react.useEffect)(function () {
125
+ window.removeEventListener('beforeunload', unloadEventHandler.current);
126
+
127
+ if (isDirty) {
128
+ unloadEventHandler.current = shouldBlockTransition;
129
+ window.addEventListener('beforeunload', unloadEventHandler.current, false);
130
+ }
131
+
132
+ return function () {
133
+ window.removeEventListener('beforeunload', unloadEventHandler.current);
134
+ };
135
+ }, [isDirty, shouldBlockTransition]);
136
+
137
+ var sendCancelAnalytic = function sendCancelAnalytic() {
138
+ sendAnalytic('cancelled', {
139
+ id: 'createKudos'
140
+ }); // props.analytics.pushTrackEvent({
141
+ // source: props.analyticsSource,
142
+ // actionSubject: 'createKudos',
143
+ // action: 'cancelled',
144
+ // });
145
+ };
146
+
147
+ var handleCloseDrawerClickedFunc = function handleCloseDrawerClickedFunc() {
148
+ if (!isDirty) {
149
+ sendCancelAnalytic();
150
+ closeDrawer();
151
+ return;
152
+ }
153
+
154
+ setIsCloseConfirmModalOpen(true);
155
+ };
156
+
157
+ var handleCloseDrawerClickedFuncRef = (0, _react.useRef)(handleCloseDrawerClickedFunc);
158
+ (0, _react.useEffect)(function () {
159
+ handleCloseDrawerClickedFuncRef.current = handleCloseDrawerClickedFunc; // eslint-disable-next-line react-hooks/exhaustive-deps
160
+ }, [isDirty]);
161
+
162
+ var renderIframe = function renderIframe() {
163
+ return /*#__PURE__*/_react.default.createElement("iframe", {
164
+ src: giveKudosUrl,
165
+ ref: iframeEl,
166
+ width: "100%",
167
+ height: "100%",
168
+ frameBorder: "0",
169
+ allow: "camera;microphone"
170
+ });
171
+ };
172
+
173
+ var handleCloseDrawerClicked = function handleCloseDrawerClicked() {
174
+ handleCloseDrawerClickedFuncRef.current();
175
+ };
176
+
177
+ var renderSidebar = function renderSidebar() {
178
+ return /*#__PURE__*/_react.default.createElement(_styled.SidebarContainer, null, /*#__PURE__*/_react.default.createElement(_standardButton.default, {
179
+ onClick: handleCloseDrawerClicked
180
+ }, /*#__PURE__*/_react.default.createElement(_arrowLeft.default, {
181
+ label: "Close drawer"
182
+ })));
183
+ };
184
+
185
+ var renderDrawer = (0, _react.useMemo)(function () {
186
+ return /*#__PURE__*/_react.default.createElement(_drawer.default, {
187
+ width: "full",
188
+ isOpen: props.isOpen,
189
+ onClose: handleCloseDrawerClicked // eslint-disable-next-line @atlaskit/design-system/no-deprecated-apis
190
+ ,
191
+ overrides: {
192
+ Content: {
193
+ component: renderIframe
194
+ },
195
+ Sidebar: {
196
+ component: renderSidebar
197
+ }
198
+ }
199
+ }); // eslint-disable-next-line react-hooks/exhaustive-deps
200
+ }, [(_props$recipient = props.recipient) === null || _props$recipient === void 0 ? void 0 : _props$recipient.recipientId, props.isOpen]);
201
+ var recipientParam = props.recipient ? "&type=".concat(props.recipient.type, "&recipientId=").concat(props.recipient.recipientId) : '';
202
+ var giveKudosUrl = "".concat(props.teamCentralBaseUrl, "/give-kudos?cloudId=").concat(props.cloudId).concat(recipientParam, "&unsavedMessage=").concat(intl.formatMessage(_messages.default.unsavedKudosWarning));
203
+ return /*#__PURE__*/_react.default.createElement(GiveKudosDrawerWrapper, {
204
+ "data-testid": testId
205
+ }, /*#__PURE__*/_react.default.createElement(_modalDialog.ModalTransition, null, isCloseConfirmModalOpen && /*#__PURE__*/_react.default.createElement(_modalDialog.default, {
206
+ onClose: closeWarningModal,
207
+ width: "small"
208
+ }, /*#__PURE__*/_react.default.createElement(_modalDialog.ModalHeader, null, /*#__PURE__*/_react.default.createElement(_modalDialog.ModalTitle, null, "Confirm Close")), /*#__PURE__*/_react.default.createElement(_modalDialog.ModalBody, null, /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage, _messages.default.unsavedKudosWarning)), /*#__PURE__*/_react.default.createElement(_modalDialog.ModalFooter, null, /*#__PURE__*/_react.default.createElement(_standardButton.default, {
209
+ appearance: "subtle",
210
+ onClick: closeWarningModal,
211
+ autoFocus: true
212
+ }, /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage, _messages.default.unsavedKudosWarningCancelButton)), /*#__PURE__*/_react.default.createElement(_standardButton.default, {
213
+ appearance: "primary",
214
+ onClick: function onClick() {
215
+ sendCancelAnalytic();
216
+ closeDrawer();
217
+ }
218
+ }, /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage, _messages.default.unsavedKudosWarningCloseButton))))), renderDrawer);
219
+ };
220
+
221
+ exports.GiveKudosLauncher = GiveKudosLauncher;
222
+ var _default = GiveKudosLauncher;
223
+ exports.default = _default;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.SidebarContainer = void 0;
9
+
10
+ var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral"));
11
+
12
+ var _styledComponents = _interopRequireDefault(require("styled-components"));
13
+
14
+ var _templateObject;
15
+
16
+ var SidebarContainer = _styledComponents.default.div(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2.default)(["\n position: absolute;\n margin: 16px 0 0 16px;\n display: flex;\n align-items: center;\n justify-content: center;\n > Button {\n padding: 0;\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n background: 0;\n border-radius: 50%;\n line-height: 1;\n }\n"])));
17
+
18
+ exports.SidebarContainer = SidebarContainer;
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "@atlaskit/give-kudos",
3
+ "version": "0.2.0",
4
+ "sideEffects": false
5
+ }
@@ -0,0 +1,2 @@
1
+ import GiveKudosLauncher from './ui/GiveKudosLauncher';
2
+ export { GiveKudosLauncher };
@@ -0,0 +1,34 @@
1
+ import { defineMessages } from 'react-intl-next';
2
+ const messages = defineMessages({
3
+ giveKudosButton: {
4
+ id: 'team-central.give-kudos.button',
5
+ defaultMessage: 'Give kudos',
6
+ description: 'Title for the button to give a kudos'
7
+ },
8
+ kudosCreatedFlag: {
9
+ id: 'team-central.give-kudos.created.title.flag',
10
+ defaultMessage: 'Kudos created',
11
+ description: 'Title text for kudos creation flag.'
12
+ },
13
+ kudosCreatedDescriptionFlag: {
14
+ id: 'team-central.give-kudos.created.description.flag',
15
+ defaultMessage: 'Your kudos has been sent. <a>View kudos</a>',
16
+ description: 'Description text for the kudos created flag. This includes a link to view the newly created kudos.'
17
+ },
18
+ unsavedKudosWarning: {
19
+ id: 'team-central.give-kudos.unsaved.warning',
20
+ defaultMessage: 'Changes that you made will not be saved.',
21
+ description: 'Shown when the user tries to navigate away from the kudos creation screen with unsaved changes.'
22
+ },
23
+ unsavedKudosWarningCancelButton: {
24
+ id: 'team-central.give-kudos.unsaved.warning.cancel',
25
+ defaultMessage: 'Cancel',
26
+ description: 'Button that cancels closing the create kudos drawer.'
27
+ },
28
+ unsavedKudosWarningCloseButton: {
29
+ id: 'team-central.give-kudos.unsaved.warning.close',
30
+ defaultMessage: 'Close',
31
+ description: 'Button that closes the warning modal and closes the drawer.'
32
+ }
33
+ });
34
+ export default messages;
@@ -0,0 +1,6 @@
1
+ export let KudosType;
2
+
3
+ (function (KudosType) {
4
+ KudosType["INDIVIDUAL"] = "individual";
5
+ KudosType["TEAM"] = "team";
6
+ })(KudosType || (KudosType = {}));
@@ -0,0 +1,184 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
+ import { FormattedMessage, useIntl } from 'react-intl-next';
4
+ import styled from 'styled-components';
5
+ import Button from '@atlaskit/button/standard-button';
6
+ import Drawer from '@atlaskit/drawer';
7
+ import ArrowLeft from '@atlaskit/icon/glyph/arrow-left';
8
+ import Modal, { ModalBody, ModalFooter, ModalHeader, ModalTitle, ModalTransition } from '@atlaskit/modal-dialog';
9
+ import messages from '../../messages';
10
+ import { SidebarContainer } from './styled';
11
+ const GiveKudosDrawerWrapper = styled.span`
12
+ > Drawer > iframe {
13
+ border: 0;
14
+ }
15
+ `;
16
+ export const GiveKudosLauncher = props => {
17
+ var _props$recipient;
18
+
19
+ const [isCloseConfirmModalOpen, setIsCloseConfirmModalOpen] = useState(false);
20
+ const [isDirty, setIsDirty] = useState(false);
21
+ const iframeEl = useRef(null);
22
+ const messageListenerEventHandler = useRef(e => {});
23
+ const unloadEventHandler = useRef(e => {});
24
+ const intl = useIntl();
25
+ const {
26
+ addFlag,
27
+ teamCentralBaseUrl,
28
+ analytics,
29
+ analyticsSource,
30
+ onClose,
31
+ testId
32
+ } = props;
33
+ const shouldBlockTransition = useCallback(e => {
34
+ e.preventDefault();
35
+ e.returnValue = intl.formatMessage(messages.unsavedKudosWarning);
36
+ }, [intl]);
37
+ const sendAnalytic = useCallback((action, options) => {
38
+ if (analytics && analyticsSource) {// TODO analytics(`${analyticsSource}.${action}`, options);
39
+ }
40
+ }, [analytics, analyticsSource]);
41
+ const closeDrawer = useCallback(() => {
42
+ setIsDirty(false);
43
+ setIsCloseConfirmModalOpen(false);
44
+ onClose();
45
+ }, [onClose]);
46
+
47
+ const closeWarningModal = () => {
48
+ setIsCloseConfirmModalOpen(false);
49
+ };
50
+
51
+ const messageListener = useCallback(event => {
52
+ if (!props.isOpen) {
53
+ return;
54
+ }
55
+
56
+ if (String(event.data).startsWith('kudos-created-')) {
57
+ const uuid = String(event.data).replace(/^(kudos-created-)/, '');
58
+ closeDrawer();
59
+ sendAnalytic('created', {
60
+ id: 'createKudos'
61
+ });
62
+ addFlag && addFlag({
63
+ title: /*#__PURE__*/React.createElement(FormattedMessage, messages.kudosCreatedFlag),
64
+ id: `kudosCreatedFlag-${uuid}`,
65
+ description: /*#__PURE__*/React.createElement(FormattedMessage, _extends({}, messages.kudosCreatedDescriptionFlag, {
66
+ values: {
67
+ a: s => /*#__PURE__*/React.createElement("a", {
68
+ href: `${teamCentralBaseUrl}/people/kudos/${uuid}`
69
+ }, s)
70
+ }
71
+ })),
72
+ icon: /*#__PURE__*/React.createElement(React.Fragment, null)
73
+ });
74
+ } else if (event.data === 'dirty') {
75
+ setIsDirty(true);
76
+ } else if (event.data === 'close') {
77
+ closeDrawer();
78
+ }
79
+ }, [props.isOpen, addFlag, teamCentralBaseUrl, sendAnalytic, closeDrawer]);
80
+ useEffect(() => {
81
+ window.removeEventListener('message', messageListenerEventHandler.current);
82
+ messageListenerEventHandler.current = messageListener;
83
+ window.addEventListener('message', messageListenerEventHandler.current, false);
84
+ return () => {
85
+ window.removeEventListener('message', messageListenerEventHandler.current);
86
+ };
87
+ }, [messageListener]);
88
+ useEffect(() => {
89
+ window.removeEventListener('beforeunload', unloadEventHandler.current);
90
+
91
+ if (isDirty) {
92
+ unloadEventHandler.current = shouldBlockTransition;
93
+ window.addEventListener('beforeunload', unloadEventHandler.current, false);
94
+ }
95
+
96
+ return () => {
97
+ window.removeEventListener('beforeunload', unloadEventHandler.current);
98
+ };
99
+ }, [isDirty, shouldBlockTransition]);
100
+
101
+ const sendCancelAnalytic = () => {
102
+ sendAnalytic('cancelled', {
103
+ id: 'createKudos'
104
+ }); // props.analytics.pushTrackEvent({
105
+ // source: props.analyticsSource,
106
+ // actionSubject: 'createKudos',
107
+ // action: 'cancelled',
108
+ // });
109
+ };
110
+
111
+ const handleCloseDrawerClickedFunc = () => {
112
+ if (!isDirty) {
113
+ sendCancelAnalytic();
114
+ closeDrawer();
115
+ return;
116
+ }
117
+
118
+ setIsCloseConfirmModalOpen(true);
119
+ };
120
+
121
+ const handleCloseDrawerClickedFuncRef = useRef(handleCloseDrawerClickedFunc);
122
+ useEffect(() => {
123
+ handleCloseDrawerClickedFuncRef.current = handleCloseDrawerClickedFunc; // eslint-disable-next-line react-hooks/exhaustive-deps
124
+ }, [isDirty]);
125
+
126
+ const renderIframe = () => {
127
+ return /*#__PURE__*/React.createElement("iframe", {
128
+ src: giveKudosUrl,
129
+ ref: iframeEl,
130
+ width: "100%",
131
+ height: "100%",
132
+ frameBorder: "0",
133
+ allow: "camera;microphone"
134
+ });
135
+ };
136
+
137
+ const handleCloseDrawerClicked = () => {
138
+ handleCloseDrawerClickedFuncRef.current();
139
+ };
140
+
141
+ const renderSidebar = () => {
142
+ return /*#__PURE__*/React.createElement(SidebarContainer, null, /*#__PURE__*/React.createElement(Button, {
143
+ onClick: handleCloseDrawerClicked
144
+ }, /*#__PURE__*/React.createElement(ArrowLeft, {
145
+ label: "Close drawer"
146
+ })));
147
+ };
148
+
149
+ const renderDrawer = useMemo(() => {
150
+ return /*#__PURE__*/React.createElement(Drawer, {
151
+ width: "full",
152
+ isOpen: props.isOpen,
153
+ onClose: handleCloseDrawerClicked // eslint-disable-next-line @atlaskit/design-system/no-deprecated-apis
154
+ ,
155
+ overrides: {
156
+ Content: {
157
+ component: renderIframe
158
+ },
159
+ Sidebar: {
160
+ component: renderSidebar
161
+ }
162
+ }
163
+ }); // eslint-disable-next-line react-hooks/exhaustive-deps
164
+ }, [(_props$recipient = props.recipient) === null || _props$recipient === void 0 ? void 0 : _props$recipient.recipientId, props.isOpen]);
165
+ const recipientParam = props.recipient ? `&type=${props.recipient.type}&recipientId=${props.recipient.recipientId}` : '';
166
+ const giveKudosUrl = `${props.teamCentralBaseUrl}/give-kudos?cloudId=${props.cloudId}${recipientParam}&unsavedMessage=${intl.formatMessage(messages.unsavedKudosWarning)}`;
167
+ return /*#__PURE__*/React.createElement(GiveKudosDrawerWrapper, {
168
+ "data-testid": testId
169
+ }, /*#__PURE__*/React.createElement(ModalTransition, null, isCloseConfirmModalOpen && /*#__PURE__*/React.createElement(Modal, {
170
+ onClose: closeWarningModal,
171
+ width: "small"
172
+ }, /*#__PURE__*/React.createElement(ModalHeader, null, /*#__PURE__*/React.createElement(ModalTitle, null, "Confirm Close")), /*#__PURE__*/React.createElement(ModalBody, null, /*#__PURE__*/React.createElement(FormattedMessage, messages.unsavedKudosWarning)), /*#__PURE__*/React.createElement(ModalFooter, null, /*#__PURE__*/React.createElement(Button, {
173
+ appearance: "subtle",
174
+ onClick: closeWarningModal,
175
+ autoFocus: true
176
+ }, /*#__PURE__*/React.createElement(FormattedMessage, messages.unsavedKudosWarningCancelButton)), /*#__PURE__*/React.createElement(Button, {
177
+ appearance: "primary",
178
+ onClick: () => {
179
+ sendCancelAnalytic();
180
+ closeDrawer();
181
+ }
182
+ }, /*#__PURE__*/React.createElement(FormattedMessage, messages.unsavedKudosWarningCloseButton))))), renderDrawer);
183
+ };
184
+ export default GiveKudosLauncher;
@@ -0,0 +1,18 @@
1
+ import styled from 'styled-components';
2
+ export const SidebarContainer = styled.div`
3
+ position: absolute;
4
+ margin: 16px 0 0 16px;
5
+ display: flex;
6
+ align-items: center;
7
+ justify-content: center;
8
+ > Button {
9
+ padding: 0;
10
+ width: 32px;
11
+ height: 32px;
12
+ display: flex;
13
+ align-items: center;
14
+ background: 0;
15
+ border-radius: 50%;
16
+ line-height: 1;
17
+ }
18
+ `;
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "@atlaskit/give-kudos",
3
+ "version": "0.2.0",
4
+ "sideEffects": false
5
+ }
@@ -0,0 +1,2 @@
1
+ import GiveKudosLauncher from './ui/GiveKudosLauncher';
2
+ export { GiveKudosLauncher };
@@ -0,0 +1,34 @@
1
+ import { defineMessages } from 'react-intl-next';
2
+ var messages = defineMessages({
3
+ giveKudosButton: {
4
+ id: 'team-central.give-kudos.button',
5
+ defaultMessage: 'Give kudos',
6
+ description: 'Title for the button to give a kudos'
7
+ },
8
+ kudosCreatedFlag: {
9
+ id: 'team-central.give-kudos.created.title.flag',
10
+ defaultMessage: 'Kudos created',
11
+ description: 'Title text for kudos creation flag.'
12
+ },
13
+ kudosCreatedDescriptionFlag: {
14
+ id: 'team-central.give-kudos.created.description.flag',
15
+ defaultMessage: 'Your kudos has been sent. <a>View kudos</a>',
16
+ description: 'Description text for the kudos created flag. This includes a link to view the newly created kudos.'
17
+ },
18
+ unsavedKudosWarning: {
19
+ id: 'team-central.give-kudos.unsaved.warning',
20
+ defaultMessage: 'Changes that you made will not be saved.',
21
+ description: 'Shown when the user tries to navigate away from the kudos creation screen with unsaved changes.'
22
+ },
23
+ unsavedKudosWarningCancelButton: {
24
+ id: 'team-central.give-kudos.unsaved.warning.cancel',
25
+ defaultMessage: 'Cancel',
26
+ description: 'Button that cancels closing the create kudos drawer.'
27
+ },
28
+ unsavedKudosWarningCloseButton: {
29
+ id: 'team-central.give-kudos.unsaved.warning.close',
30
+ defaultMessage: 'Close',
31
+ description: 'Button that closes the warning modal and closes the drawer.'
32
+ }
33
+ });
34
+ export default messages;
@@ -0,0 +1,6 @@
1
+ export var KudosType;
2
+
3
+ (function (KudosType) {
4
+ KudosType["INDIVIDUAL"] = "individual";
5
+ KudosType["TEAM"] = "team";
6
+ })(KudosType || (KudosType = {}));
@@ -0,0 +1,193 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
+ import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
4
+
5
+ var _templateObject;
6
+
7
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
8
+ import { FormattedMessage, useIntl } from 'react-intl-next';
9
+ import styled from 'styled-components';
10
+ import Button from '@atlaskit/button/standard-button';
11
+ import Drawer from '@atlaskit/drawer';
12
+ import ArrowLeft from '@atlaskit/icon/glyph/arrow-left';
13
+ import Modal, { ModalBody, ModalFooter, ModalHeader, ModalTitle, ModalTransition } from '@atlaskit/modal-dialog';
14
+ import messages from '../../messages';
15
+ import { SidebarContainer } from './styled';
16
+ var GiveKudosDrawerWrapper = styled.span(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n > Drawer > iframe {\n border: 0;\n }\n"])));
17
+ export var GiveKudosLauncher = function GiveKudosLauncher(props) {
18
+ var _props$recipient;
19
+
20
+ var _useState = useState(false),
21
+ _useState2 = _slicedToArray(_useState, 2),
22
+ isCloseConfirmModalOpen = _useState2[0],
23
+ setIsCloseConfirmModalOpen = _useState2[1];
24
+
25
+ var _useState3 = useState(false),
26
+ _useState4 = _slicedToArray(_useState3, 2),
27
+ isDirty = _useState4[0],
28
+ setIsDirty = _useState4[1];
29
+
30
+ var iframeEl = useRef(null);
31
+ var messageListenerEventHandler = useRef(function (e) {});
32
+ var unloadEventHandler = useRef(function (e) {});
33
+ var intl = useIntl();
34
+ var addFlag = props.addFlag,
35
+ teamCentralBaseUrl = props.teamCentralBaseUrl,
36
+ analytics = props.analytics,
37
+ analyticsSource = props.analyticsSource,
38
+ onClose = props.onClose,
39
+ testId = props.testId;
40
+ var shouldBlockTransition = useCallback(function (e) {
41
+ e.preventDefault();
42
+ e.returnValue = intl.formatMessage(messages.unsavedKudosWarning);
43
+ }, [intl]);
44
+ var sendAnalytic = useCallback(function (action, options) {
45
+ if (analytics && analyticsSource) {// TODO analytics(`${analyticsSource}.${action}`, options);
46
+ }
47
+ }, [analytics, analyticsSource]);
48
+ var closeDrawer = useCallback(function () {
49
+ setIsDirty(false);
50
+ setIsCloseConfirmModalOpen(false);
51
+ onClose();
52
+ }, [onClose]);
53
+
54
+ var closeWarningModal = function closeWarningModal() {
55
+ setIsCloseConfirmModalOpen(false);
56
+ };
57
+
58
+ var messageListener = useCallback(function (event) {
59
+ if (!props.isOpen) {
60
+ return;
61
+ }
62
+
63
+ if (String(event.data).startsWith('kudos-created-')) {
64
+ var uuid = String(event.data).replace(/^(kudos-created-)/, '');
65
+ closeDrawer();
66
+ sendAnalytic('created', {
67
+ id: 'createKudos'
68
+ });
69
+ addFlag && addFlag({
70
+ title: /*#__PURE__*/React.createElement(FormattedMessage, messages.kudosCreatedFlag),
71
+ id: "kudosCreatedFlag-".concat(uuid),
72
+ description: /*#__PURE__*/React.createElement(FormattedMessage, _extends({}, messages.kudosCreatedDescriptionFlag, {
73
+ values: {
74
+ a: function a(s) {
75
+ return /*#__PURE__*/React.createElement("a", {
76
+ href: "".concat(teamCentralBaseUrl, "/people/kudos/").concat(uuid)
77
+ }, s);
78
+ }
79
+ }
80
+ })),
81
+ icon: /*#__PURE__*/React.createElement(React.Fragment, null)
82
+ });
83
+ } else if (event.data === 'dirty') {
84
+ setIsDirty(true);
85
+ } else if (event.data === 'close') {
86
+ closeDrawer();
87
+ }
88
+ }, [props.isOpen, addFlag, teamCentralBaseUrl, sendAnalytic, closeDrawer]);
89
+ useEffect(function () {
90
+ window.removeEventListener('message', messageListenerEventHandler.current);
91
+ messageListenerEventHandler.current = messageListener;
92
+ window.addEventListener('message', messageListenerEventHandler.current, false);
93
+ return function () {
94
+ window.removeEventListener('message', messageListenerEventHandler.current);
95
+ };
96
+ }, [messageListener]);
97
+ useEffect(function () {
98
+ window.removeEventListener('beforeunload', unloadEventHandler.current);
99
+
100
+ if (isDirty) {
101
+ unloadEventHandler.current = shouldBlockTransition;
102
+ window.addEventListener('beforeunload', unloadEventHandler.current, false);
103
+ }
104
+
105
+ return function () {
106
+ window.removeEventListener('beforeunload', unloadEventHandler.current);
107
+ };
108
+ }, [isDirty, shouldBlockTransition]);
109
+
110
+ var sendCancelAnalytic = function sendCancelAnalytic() {
111
+ sendAnalytic('cancelled', {
112
+ id: 'createKudos'
113
+ }); // props.analytics.pushTrackEvent({
114
+ // source: props.analyticsSource,
115
+ // actionSubject: 'createKudos',
116
+ // action: 'cancelled',
117
+ // });
118
+ };
119
+
120
+ var handleCloseDrawerClickedFunc = function handleCloseDrawerClickedFunc() {
121
+ if (!isDirty) {
122
+ sendCancelAnalytic();
123
+ closeDrawer();
124
+ return;
125
+ }
126
+
127
+ setIsCloseConfirmModalOpen(true);
128
+ };
129
+
130
+ var handleCloseDrawerClickedFuncRef = useRef(handleCloseDrawerClickedFunc);
131
+ useEffect(function () {
132
+ handleCloseDrawerClickedFuncRef.current = handleCloseDrawerClickedFunc; // eslint-disable-next-line react-hooks/exhaustive-deps
133
+ }, [isDirty]);
134
+
135
+ var renderIframe = function renderIframe() {
136
+ return /*#__PURE__*/React.createElement("iframe", {
137
+ src: giveKudosUrl,
138
+ ref: iframeEl,
139
+ width: "100%",
140
+ height: "100%",
141
+ frameBorder: "0",
142
+ allow: "camera;microphone"
143
+ });
144
+ };
145
+
146
+ var handleCloseDrawerClicked = function handleCloseDrawerClicked() {
147
+ handleCloseDrawerClickedFuncRef.current();
148
+ };
149
+
150
+ var renderSidebar = function renderSidebar() {
151
+ return /*#__PURE__*/React.createElement(SidebarContainer, null, /*#__PURE__*/React.createElement(Button, {
152
+ onClick: handleCloseDrawerClicked
153
+ }, /*#__PURE__*/React.createElement(ArrowLeft, {
154
+ label: "Close drawer"
155
+ })));
156
+ };
157
+
158
+ var renderDrawer = useMemo(function () {
159
+ return /*#__PURE__*/React.createElement(Drawer, {
160
+ width: "full",
161
+ isOpen: props.isOpen,
162
+ onClose: handleCloseDrawerClicked // eslint-disable-next-line @atlaskit/design-system/no-deprecated-apis
163
+ ,
164
+ overrides: {
165
+ Content: {
166
+ component: renderIframe
167
+ },
168
+ Sidebar: {
169
+ component: renderSidebar
170
+ }
171
+ }
172
+ }); // eslint-disable-next-line react-hooks/exhaustive-deps
173
+ }, [(_props$recipient = props.recipient) === null || _props$recipient === void 0 ? void 0 : _props$recipient.recipientId, props.isOpen]);
174
+ var recipientParam = props.recipient ? "&type=".concat(props.recipient.type, "&recipientId=").concat(props.recipient.recipientId) : '';
175
+ var giveKudosUrl = "".concat(props.teamCentralBaseUrl, "/give-kudos?cloudId=").concat(props.cloudId).concat(recipientParam, "&unsavedMessage=").concat(intl.formatMessage(messages.unsavedKudosWarning));
176
+ return /*#__PURE__*/React.createElement(GiveKudosDrawerWrapper, {
177
+ "data-testid": testId
178
+ }, /*#__PURE__*/React.createElement(ModalTransition, null, isCloseConfirmModalOpen && /*#__PURE__*/React.createElement(Modal, {
179
+ onClose: closeWarningModal,
180
+ width: "small"
181
+ }, /*#__PURE__*/React.createElement(ModalHeader, null, /*#__PURE__*/React.createElement(ModalTitle, null, "Confirm Close")), /*#__PURE__*/React.createElement(ModalBody, null, /*#__PURE__*/React.createElement(FormattedMessage, messages.unsavedKudosWarning)), /*#__PURE__*/React.createElement(ModalFooter, null, /*#__PURE__*/React.createElement(Button, {
182
+ appearance: "subtle",
183
+ onClick: closeWarningModal,
184
+ autoFocus: true
185
+ }, /*#__PURE__*/React.createElement(FormattedMessage, messages.unsavedKudosWarningCancelButton)), /*#__PURE__*/React.createElement(Button, {
186
+ appearance: "primary",
187
+ onClick: function onClick() {
188
+ sendCancelAnalytic();
189
+ closeDrawer();
190
+ }
191
+ }, /*#__PURE__*/React.createElement(FormattedMessage, messages.unsavedKudosWarningCloseButton))))), renderDrawer);
192
+ };
193
+ export default GiveKudosLauncher;
@@ -0,0 +1,6 @@
1
+ import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
2
+
3
+ var _templateObject;
4
+
5
+ import styled from 'styled-components';
6
+ export var SidebarContainer = styled.div(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n position: absolute;\n margin: 16px 0 0 16px;\n display: flex;\n align-items: center;\n justify-content: center;\n > Button {\n padding: 0;\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n background: 0;\n border-radius: 50%;\n line-height: 1;\n }\n"])));
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "@atlaskit/give-kudos",
3
+ "version": "0.2.0",
4
+ "sideEffects": false
5
+ }
@@ -0,0 +1,3 @@
1
+ import GiveKudosLauncher from './ui/GiveKudosLauncher';
2
+ export type { KudosType, KudosRecipient, GiveKudosDrawerProps } from './types';
3
+ export { GiveKudosLauncher };
@@ -0,0 +1,33 @@
1
+ declare const messages: {
2
+ giveKudosButton: {
3
+ id: string;
4
+ defaultMessage: string;
5
+ description: string;
6
+ };
7
+ kudosCreatedFlag: {
8
+ id: string;
9
+ defaultMessage: string;
10
+ description: string;
11
+ };
12
+ kudosCreatedDescriptionFlag: {
13
+ id: string;
14
+ defaultMessage: string;
15
+ description: string;
16
+ };
17
+ unsavedKudosWarning: {
18
+ id: string;
19
+ defaultMessage: string;
20
+ description: string;
21
+ };
22
+ unsavedKudosWarningCancelButton: {
23
+ id: string;
24
+ defaultMessage: string;
25
+ description: string;
26
+ };
27
+ unsavedKudosWarningCloseButton: {
28
+ id: string;
29
+ defaultMessage: string;
30
+ description: string;
31
+ };
32
+ };
33
+ export default messages;
@@ -0,0 +1,19 @@
1
+ export declare enum KudosType {
2
+ INDIVIDUAL = "individual",
3
+ TEAM = "team"
4
+ }
5
+ export interface KudosRecipient {
6
+ type: KudosType;
7
+ recipientId: string;
8
+ }
9
+ export interface GiveKudosDrawerProps {
10
+ testId?: string;
11
+ isOpen: boolean;
12
+ onClose: () => void;
13
+ analytics?: any;
14
+ analyticsSource: string;
15
+ recipient?: KudosRecipient;
16
+ teamCentralBaseUrl: string;
17
+ cloudId: string;
18
+ addFlag?: (flag: any) => void;
19
+ }
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ import { GiveKudosDrawerProps } from '../../types';
3
+ export declare const GiveKudosLauncher: (props: GiveKudosDrawerProps) => JSX.Element;
4
+ export default GiveKudosLauncher;
@@ -0,0 +1,2 @@
1
+ /// <reference types="react" />
2
+ export declare const SidebarContainer: import("styled-components").StyledComponentClass<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement>, any, import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement>>;
package/package.json ADDED
@@ -0,0 +1,88 @@
1
+ {
2
+ "name": "@atlaskit/give-kudos",
3
+ "version": "0.2.0",
4
+ "description": "Give Kudos experience ",
5
+ "author": "Atlassian Pty Ltd",
6
+ "license": "Apache-2.0",
7
+ "publishConfig": {
8
+ "registry": "https://registry.npmjs.org/"
9
+ },
10
+ "atlassian": {
11
+ "team": "Team Central",
12
+ "inPublicMirror": false,
13
+ "releaseModel": "continuous",
14
+ "website": {
15
+ "name": "GiveKudos"
16
+ }
17
+ },
18
+ "repository": "https://bitbucket.org/atlassian/atlassian-frontend",
19
+ "main": "dist/cjs/index.js",
20
+ "module": "dist/esm/index.js",
21
+ "module:es2019": "dist/es2019/index.js",
22
+ "types": "dist/types/index.d.ts",
23
+ "sideEffects": false,
24
+ "atlaskit:src": "src/index.ts",
25
+ "af:exports": {
26
+ ".": "./src/index.ts"
27
+ },
28
+ "scripts": {
29
+ "lint": "(cd ../../.. && yarn eslint 'packages/team-central/give-kudos/**/*.{ts,tsx}')",
30
+ "test": "(cd ../../.. && yarn test 'packages/team-central/give-kudos')",
31
+ "typecheck": "NODE_OPTIONS=--max-old-space-size=4096 tsc --noEmit --project ./tsconfig.json"
32
+ },
33
+ "dependencies": {
34
+ "@atlaskit/button": "^16.3.1",
35
+ "@atlaskit/drawer": "^7.1.10",
36
+ "@atlaskit/icon": "^21.10.7",
37
+ "@atlaskit/modal-dialog": "^12.2.9",
38
+ "@babel/runtime": "^7.0.0",
39
+ "react-intl-next": "npm:react-intl@^5.18.1"
40
+ },
41
+ "peerDependencies": {
42
+ "react": "^16.8.0",
43
+ "styled-components": "^3.4.10"
44
+ },
45
+ "devDependencies": {
46
+ "@atlaskit/docs": "*",
47
+ "@atlaskit/flag": "^14.5.9",
48
+ "@atlaskit/ssr": "*",
49
+ "@atlaskit/theme": "^12.1.0",
50
+ "@atlaskit/tokens": "^0.10.0",
51
+ "@atlaskit/visual-regression": "*",
52
+ "@atlaskit/webdriver-runner": "*",
53
+ "@atlassian/atlassian-frontend-prettier-config-1.0.0": "npm:@atlassian/atlassian-frontend-prettier-config@1.0.0",
54
+ "@emotion/core": "^10.0.9",
55
+ "@testing-library/react": "^8.0.1",
56
+ "react-dom": "^16.8.0",
57
+ "wait-for-expect": "^1.2.0"
58
+ },
59
+ "techstack": {
60
+ "@atlassian/frontend": {
61
+ "code-structure": [
62
+ "tangerine-next"
63
+ ],
64
+ "import-structure": [
65
+ "atlassian-conventions"
66
+ ],
67
+ "circular-dependencies": [
68
+ "file-and-folder-level"
69
+ ]
70
+ },
71
+ "@repo/internal": {
72
+ "analytics": [
73
+ "analytics-next"
74
+ ],
75
+ "theming": [
76
+ "react-context",
77
+ "tokens"
78
+ ],
79
+ "ui-components": [
80
+ "lite-mode"
81
+ ],
82
+ "deprecation": [
83
+ "no-deprecated-imports"
84
+ ]
85
+ }
86
+ },
87
+ "prettier": "@atlassian/atlassian-frontend-prettier-config-1.0.0"
88
+ }