@atlaskit/teams-public 0.70.6 → 0.70.7

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 (67) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/cjs/common/ui/container-icon/index.js +1 -1
  3. package/dist/cjs/common/ui/loom-avatar/main.js +1 -1
  4. package/dist/cjs/common/ui/separator/index.js +1 -1
  5. package/dist/cjs/common/ui/team-containers-skeleton/index.js +1 -1
  6. package/dist/cjs/common/ui/team-containers-skeleton/linked-container-card-skeleton/index.js +1 -1
  7. package/dist/cjs/common/ui/team-link-card-actions/index.js +1 -1
  8. package/dist/cjs/common/utils/get-container-properties.js +1 -1
  9. package/dist/cjs/next/common/ui/team-container-skeleton/index.js +1 -1
  10. package/dist/cjs/next/ui/team-containers/add-container-card/index.js +1 -1
  11. package/dist/cjs/next/ui/team-containers/team-link-card/index.js +1 -1
  12. package/dist/cjs/ui/team-containers/add-container-card/index.js +1 -1
  13. package/dist/cjs/ui/team-containers/linked-container-card/index.js +1 -1
  14. package/dist/cjs/ui/team-containers/main.js +7 -16
  15. package/dist/cjs/ui/team-containers/no-product-access-empty-state/index.js +1 -1
  16. package/dist/cjs/ui/team-containers/no-product-access-empty-state/no-product-access-icon/index.js +1 -1
  17. package/dist/cjs/ui/team-containers/team-link-card/index.js +1 -1
  18. package/dist/cjs/ui/team-containers/team-link-card/team-link-card-title.js +1 -1
  19. package/dist/es2019/common/ui/container-icon/index.js +1 -1
  20. package/dist/es2019/common/ui/loom-avatar/main.js +1 -1
  21. package/dist/es2019/common/ui/separator/index.js +1 -1
  22. package/dist/es2019/common/ui/team-containers-skeleton/index.js +1 -1
  23. package/dist/es2019/common/ui/team-containers-skeleton/linked-container-card-skeleton/index.js +1 -1
  24. package/dist/es2019/common/ui/team-link-card-actions/index.js +1 -1
  25. package/dist/es2019/common/utils/get-container-properties.js +1 -1
  26. package/dist/es2019/next/common/ui/team-container-skeleton/index.js +1 -1
  27. package/dist/es2019/next/ui/team-containers/add-container-card/index.js +1 -1
  28. package/dist/es2019/next/ui/team-containers/team-link-card/index.js +1 -1
  29. package/dist/es2019/ui/team-containers/add-container-card/index.js +1 -1
  30. package/dist/es2019/ui/team-containers/linked-container-card/index.js +1 -1
  31. package/dist/es2019/ui/team-containers/main.js +7 -16
  32. package/dist/es2019/ui/team-containers/no-product-access-empty-state/index.js +1 -1
  33. package/dist/es2019/ui/team-containers/no-product-access-empty-state/no-product-access-icon/index.js +1 -1
  34. package/dist/es2019/ui/team-containers/team-link-card/index.js +1 -1
  35. package/dist/es2019/ui/team-containers/team-link-card/team-link-card-title.js +1 -1
  36. package/dist/esm/common/ui/container-icon/index.js +1 -1
  37. package/dist/esm/common/ui/loom-avatar/main.js +1 -1
  38. package/dist/esm/common/ui/separator/index.js +1 -1
  39. package/dist/esm/common/ui/team-containers-skeleton/index.js +1 -1
  40. package/dist/esm/common/ui/team-containers-skeleton/linked-container-card-skeleton/index.js +1 -1
  41. package/dist/esm/common/ui/team-link-card-actions/index.js +1 -1
  42. package/dist/esm/common/utils/get-container-properties.js +1 -1
  43. package/dist/esm/next/common/ui/team-container-skeleton/index.js +1 -1
  44. package/dist/esm/next/ui/team-containers/add-container-card/index.js +1 -1
  45. package/dist/esm/next/ui/team-containers/team-link-card/index.js +1 -1
  46. package/dist/esm/ui/team-containers/add-container-card/index.js +1 -1
  47. package/dist/esm/ui/team-containers/linked-container-card/index.js +1 -1
  48. package/dist/esm/ui/team-containers/main.js +7 -16
  49. package/dist/esm/ui/team-containers/no-product-access-empty-state/index.js +1 -1
  50. package/dist/esm/ui/team-containers/no-product-access-empty-state/no-product-access-icon/index.js +1 -1
  51. package/dist/esm/ui/team-containers/team-link-card/index.js +1 -1
  52. package/dist/esm/ui/team-containers/team-link-card/team-link-card-title.js +1 -1
  53. package/dist/types/ui/team-containers/main.d.ts +1 -1
  54. package/dist/types/ui/team-containers/types.d.ts +0 -5
  55. package/dist/types-ts4.5/ui/team-containers/main.d.ts +1 -1
  56. package/dist/types-ts4.5/ui/team-containers/types.d.ts +0 -5
  57. package/package.json +1 -3
  58. package/dist/cjs/controllers/hooks/use-requested-container/index.js +0 -358
  59. package/dist/cjs/controllers/hooks/use-requested-container/utils.js +0 -165
  60. package/dist/es2019/controllers/hooks/use-requested-container/index.js +0 -288
  61. package/dist/es2019/controllers/hooks/use-requested-container/utils.js +0 -126
  62. package/dist/esm/controllers/hooks/use-requested-container/index.js +0 -350
  63. package/dist/esm/controllers/hooks/use-requested-container/utils.js +0 -153
  64. package/dist/types/controllers/hooks/use-requested-container/index.d.ts +0 -25
  65. package/dist/types/controllers/hooks/use-requested-container/utils.d.ts +0 -34
  66. package/dist/types-ts4.5/controllers/hooks/use-requested-container/index.d.ts +0 -25
  67. package/dist/types-ts4.5/controllers/hooks/use-requested-container/utils.d.ts +0 -34
@@ -1,288 +0,0 @@
1
- import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
- import { defineMessages, useIntl } from 'react-intl-next';
3
- import { useAnalyticsEvents as useAnalyticsEventsDEPRECATED } from '@atlaskit/analytics-next';
4
- import LinkExternalIcon from '@atlaskit/icon/core/link-external';
5
- import { fg } from '@atlaskit/platform-feature-flags';
6
- import { Flex } from '@atlaskit/primitives/compiled';
7
- import { useAnalyticsEvents } from '@atlaskit/teams-app-internal-analytics';
8
- import { HttpError, teamsClient } from '@atlaskit/teams-client';
9
- import { usePeopleAndTeamAnalytics } from '../../../common/utils/analytics';
10
- import { useTeamContainers } from '../use-team-containers';
11
- import { containerDisplayName, containersEqual, convertContainerToType, getRequestedContainersFromUrl, POLLING_INTERVAL, removeRequestedContainersFromUrl, useAsyncPolling } from './utils';
12
- /**
13
- * Hook to track and poll for requested product containers (such as a Jira Project).
14
- * The initial list of requested containers is derived from the URL parameters, however it can be updated based on user interactions.
15
- *
16
- * Manages a list of requested containers, polls for updates, and removes found containers from the list.
17
- *
18
- * Supported container types: CONFLUENCE_SPACE, JIRA_PROJECT, LOOM_SPACE.
19
- *
20
- * @param teamId - The ID of the team whose containers are being tracked.
21
- * @param onRequestedContainerTimeout - Optional callback to handle timeout events for requested containers.
22
- * @returns The current list of requested containers and a function to add a container.
23
- */
24
- function useRequestedContainers({
25
- teamId,
26
- cloudId,
27
- onRequestedContainerTimeout
28
- }) {
29
- const {
30
- formatMessage
31
- } = useIntl();
32
- const {
33
- refetchTeamContainers,
34
- teamContainers
35
- } = useTeamContainers(teamId);
36
- const [isTryingAgain, setIsTryingAgain] = useState(false);
37
- const tryAgainCountRef = useRef(0);
38
- const [refetchErrorCount, setRefetchErrorCount] = useState(0);
39
- const {
40
- fireTrackEvent
41
- } = usePeopleAndTeamAnalytics();
42
- const {
43
- createAnalyticsEvent
44
- } = useAnalyticsEventsDEPRECATED();
45
- const {
46
- fireEvent
47
- } = useAnalyticsEvents();
48
- const [requestedContainers, setRequestedContainers] = useState([]);
49
- const requestedContainersRef = useRef([]);
50
- const checkContainers = useCallback(async () => {
51
- try {
52
- await refetchTeamContainers();
53
- } catch (error) {
54
- setRefetchErrorCount(prev => prev + 1);
55
- }
56
- }, [refetchTeamContainers]);
57
- const onTimeout = useCallback(({
58
- startPolling,
59
- reset
60
- }) => {
61
- if (!onRequestedContainerTimeout) {
62
- return;
63
- }
64
- const reqContainers = requestedContainersRef.current;
65
- const flagId = `requested-container-timeout-${reqContainers.join('-')}-${tryAgainCountRef.current}`;
66
- const createTryAgainFlag = ({
67
- onAction
68
- }) => ({
69
- id: flagId,
70
- title: reqContainers.length === 1 ? formatMessage(messages.timeoutTitle, {
71
- container: containerDisplayName(reqContainers[0])
72
- }) : formatMessage(messages.timeoutTitleMultiple),
73
- description: formatMessage(messages.timeoutDescription),
74
- appearance: 'error',
75
- type: 'error',
76
- actions: [{
77
- content: formatMessage(messages.timeoutAction),
78
- onClick: () => {
79
- onAction(flagId);
80
- tryAgainAction();
81
- }
82
- }]
83
- });
84
- const createContactSupportFlag = ({
85
- onAction
86
- }) => ({
87
- id: flagId,
88
- title: formatMessage(messages.noConnectionTitle),
89
- description: formatMessage(messages.noConnectionDescription),
90
- appearance: 'error',
91
- type: 'error',
92
- actions: [{
93
- content: /*#__PURE__*/React.createElement(Flex, {
94
- alignItems: "center",
95
- columnGap: "space.100"
96
- }, formatMessage(messages.noConnectionAction), /*#__PURE__*/React.createElement(LinkExternalIcon, {
97
- label: ""
98
- })),
99
- onClick: () => {
100
- onAction(flagId);
101
- },
102
- href: 'https://support.atlassian.com/contact/#/&support_type=customer'
103
- }]
104
- });
105
- const tryAgainAction = async () => {
106
- setIsTryingAgain(true);
107
- tryAgainCountRef.current = tryAgainCountRef.current + 1;
108
- const containers = reqContainers.map(container => {
109
- return {
110
- type: convertContainerToType(container),
111
- containerSiteId: cloudId
112
- };
113
- }).filter(({
114
- type
115
- }) => Boolean(type));
116
- if (fg('ptc-missed-analytics-migration-events')) {
117
- fireEvent('track.requestedContainers.tryAgain', {
118
- containers: reqContainers,
119
- teamId
120
- });
121
- } else {
122
- fireTrackEvent(createAnalyticsEvent, {
123
- action: 'tryAgain',
124
- actionSubject: 'requestedContainers',
125
- // @ts-ignore
126
- attributes: {
127
- containers: reqContainers,
128
- teamId
129
- }
130
- });
131
- }
132
- try {
133
- const response = await teamsClient.createTeamContainers({
134
- teamId,
135
- containers
136
- });
137
- const containersNotCreated = reqContainers.filter(containerType => {
138
- var _response$containersC;
139
- return !((_response$containersC = response.containersCreated) !== null && _response$containersC !== void 0 && _response$containersC.some(container => container.containerType === convertContainerToType(containerType)));
140
- });
141
-
142
- //containers are still being created
143
- if (containersNotCreated.length > 0) {
144
- startPolling();
145
- } else {
146
- //all containers created so reset and update state
147
- reset();
148
- await refetchTeamContainers();
149
- }
150
- } catch (error) {
151
- if (error instanceof HttpError) {
152
- if (error.status === 500) {
153
- //only allow for 2 retries
154
- if (tryAgainCountRef.current <= 2) {
155
- return setTimeout(() => {
156
- //bug: this can cause two flags to be shown
157
- tryAgainAction();
158
- }, POLLING_INTERVAL);
159
- }
160
- }
161
- }
162
- onRequestedContainerTimeout(createContactSupportFlag);
163
- } finally {
164
- setIsTryingAgain(false);
165
- }
166
- };
167
- if (fg('ptc-missed-analytics-migration-events')) {
168
- fireEvent('track.requestedContainers.failed', {
169
- containers: reqContainers,
170
- teamId,
171
- tryAgainCount: tryAgainCountRef.current
172
- });
173
- } else {
174
- fireTrackEvent(createAnalyticsEvent, {
175
- action: 'failed',
176
- actionSubject: 'requestedContainers',
177
- attributes: {
178
- // @ts-ignore
179
- containers: reqContainers,
180
- teamId,
181
- tryAgainCount: tryAgainCountRef.current
182
- }
183
- });
184
- }
185
- removeRequestedContainersFromUrl();
186
- onRequestedContainerTimeout(tryAgainCountRef.current === 0 ? createTryAgainFlag : createContactSupportFlag);
187
- }, [cloudId, formatMessage, onRequestedContainerTimeout, refetchTeamContainers, teamId, createAnalyticsEvent, fireTrackEvent, fireEvent]);
188
- const {
189
- startPolling,
190
- stopPolling,
191
- isPolling,
192
- hasTimedOut
193
- } = useAsyncPolling(checkContainers, {
194
- onTimeout
195
- });
196
- useEffect(() => {
197
- const containers = getRequestedContainersFromUrl();
198
- if (containers.length > 0 && isPolling === false) {
199
- setRequestedContainers(containers);
200
- startPolling();
201
- }
202
- // eslint-disable-next-line react-hooks/exhaustive-deps
203
- }, []);
204
- useEffect(() => {
205
- requestedContainersRef.current = requestedContainers;
206
- }, [requestedContainers]);
207
- useEffect(() => {
208
- //stop gap to prevent sending too many failed errors
209
- if (refetchErrorCount > 3) {
210
- stopPolling();
211
- if (fg('ptc-missed-analytics-migration-events')) {
212
- fireEvent('track.requestedContainers.failed', {
213
- containers: requestedContainers,
214
- teamId,
215
- tryAgainCount: null
216
- });
217
- } else {
218
- fireTrackEvent(createAnalyticsEvent, {
219
- action: 'failed',
220
- actionSubject: 'requestedContainers',
221
- attributes: {
222
- // @ts-ignore
223
- containers: requestedContainers,
224
- teamId
225
- }
226
- });
227
- }
228
- return;
229
- }
230
- if (hasTimedOut || isTryingAgain) {
231
- return;
232
- }
233
- const containerCount = requestedContainers.length;
234
- if (isPolling && containerCount === 0) {
235
- removeRequestedContainersFromUrl();
236
- stopPolling();
237
- return;
238
- }
239
- }, [isPolling, refetchErrorCount, requestedContainers, hasTimedOut, startPolling, stopPolling, isTryingAgain, teamId, createAnalyticsEvent, fireTrackEvent, fireEvent]);
240
- useEffect(() => {
241
- const containersNotFound = requestedContainers.filter(containerType => !teamContainers.some(teamContainer => teamContainer.type === containerType));
242
- if (!containersEqual(containersNotFound, requestedContainers)) {
243
- setRequestedContainers(containersNotFound);
244
- }
245
- }, [requestedContainers, checkContainers, teamContainers, isPolling]);
246
- const containersLoading = useMemo(() => hasTimedOut && !isTryingAgain || refetchErrorCount > 3 ? [] : requestedContainers, [hasTimedOut, requestedContainers, isTryingAgain, refetchErrorCount]);
247
- return {
248
- requestedContainers: containersLoading
249
- };
250
- }
251
- const messages = defineMessages({
252
- timeoutTitle: {
253
- id: 'teams-public.team-containers.timeout-title',
254
- defaultMessage: 'We’re couldn’t connect your {container}',
255
- description: 'Title for the timeout flag'
256
- },
257
- timeoutTitleMultiple: {
258
- id: 'teams-public.team-containers.timeout-title',
259
- defaultMessage: 'We’re couldn’t connect your spaces',
260
- description: 'Title for the timeout flag'
261
- },
262
- timeoutDescription: {
263
- id: 'teams-public.team-containers.timeout-description',
264
- defaultMessage: 'Something went wrong. Verify your connection and retry.',
265
- description: 'Description for the timeout flag'
266
- },
267
- timeoutAction: {
268
- id: 'teams-public.team-containers.timeout-action',
269
- defaultMessage: 'Try again',
270
- description: 'Action text for the timeout flag'
271
- },
272
- noConnectionTitle: {
273
- id: 'teams-public.team-containers.timeout-no-connection-title',
274
- defaultMessage: 'Connection failed',
275
- description: 'Title for the no connection flag'
276
- },
277
- noConnectionDescription: {
278
- id: 'teams-public.team-containers.timeout-no-connection-description',
279
- defaultMessage: 'Try manually creating the space yourself.',
280
- description: 'Description for the no connection flag'
281
- },
282
- noConnectionAction: {
283
- id: 'teams-public.team-containers.timeout-no-connection-action',
284
- defaultMessage: 'Contact support',
285
- description: 'Action text for the no connection flag'
286
- }
287
- });
288
- export { useRequestedContainers };
@@ -1,126 +0,0 @@
1
- import { useCallback, useRef, useState } from 'react';
2
- import { useInterval } from '@atlaskit/frontend-utilities';
3
- import { ContainerType } from '@atlaskit/teams-client/types';
4
- const CONTAINER_MAP = {
5
- [ContainerType.CONFLUENCE_SPACE]: 'ConfluenceSpace',
6
- [ContainerType.JIRA_PROJECT]: 'JiraProject',
7
- [ContainerType.LOOM_SPACE]: 'LoomSpace'
8
- };
9
- const CONTAINER_HUMAN_NAMES = {
10
- ConfluenceSpace: 'Confluence space',
11
- JiraProject: 'Jira project',
12
- LoomSpace: 'Loom space'
13
- };
14
- const SEARCH_PARAM_NAME = 'requestedContainers';
15
- function containersEqual(arr1, arr2) {
16
- return JSON.stringify([...arr1].sort()) === JSON.stringify([...arr2].sort());
17
- }
18
- function getRequestedContainersFromUrl() {
19
- var _searchParams$get;
20
- const searchParams = new URLSearchParams(window.location.search);
21
- const values = ((_searchParams$get = searchParams.get(SEARCH_PARAM_NAME)) === null || _searchParams$get === void 0 ? void 0 : _searchParams$get.split(',').filter(Boolean)) || [];
22
- const containers = values.filter(value => Object.values(ContainerType).includes(value)).map(value => CONTAINER_MAP[value]);
23
- if (containers.length === 0) {
24
- return [];
25
- }
26
- return containers || [];
27
- }
28
- function removeRequestedContainersFromUrl() {
29
- const searchParams = new URLSearchParams(window.location.search);
30
- searchParams.delete(SEARCH_PARAM_NAME);
31
- window.history.replaceState({}, '', `${window.location.pathname}?${searchParams.toString()}`);
32
- }
33
- function containerDisplayName(container) {
34
- return CONTAINER_HUMAN_NAMES[container];
35
- }
36
- function convertContainerToType(container) {
37
- switch (container) {
38
- case 'ConfluenceSpace':
39
- return ContainerType.CONFLUENCE_SPACE;
40
- case 'JiraProject':
41
- return ContainerType.JIRA_PROJECT;
42
- case 'LoomSpace':
43
- return ContainerType.LOOM_SPACE;
44
- default:
45
- return null;
46
- }
47
- }
48
- let POLLING_INTERVAL = 1000;
49
- let POLLING_DURATION = 15000;
50
-
51
- /**
52
- * Hook for polling an async callback at a fixed interval, with timeout and pending state management.
53
- *
54
- * Starts polling the provided callback and stops after a set duration or when stopped manually.
55
- * Ensures only one callback is pending at a time.
56
- *
57
- * @param callback - The async function to poll.
58
- * @param onTimeout - Optional callback to execute when polling times out.
59
- * @returns An object with polling controls and state: startPolling, stopPolling, isPolling, hasTimedOut.
60
- */
61
- function useAsyncPolling(callback, {
62
- onTimeout
63
- } = {}) {
64
- const [hasTimedOut, setHasTimedOut] = useState(false);
65
- const timeoutRef = useRef(null);
66
- const [isPolling, setIsPolling] = useState(false);
67
- const [isPending, setIsPending] = useState(false);
68
- const stopPolling = useCallback(() => {
69
- if (timeoutRef.current) {
70
- clearTimeout(timeoutRef.current);
71
- timeoutRef.current = null;
72
- }
73
- setIsPolling(false);
74
- setHasTimedOut(false);
75
- setIsPending(false);
76
- }, []);
77
- const reset = useCallback(() => {
78
- if (timeoutRef.current) {
79
- clearTimeout(timeoutRef.current);
80
- timeoutRef.current = null;
81
- }
82
- setHasTimedOut(false);
83
- setIsPolling(false);
84
- setIsPending(false);
85
- }, []);
86
- const startPolling = useCallback(() => {
87
- if (timeoutRef.current) {
88
- clearTimeout(timeoutRef.current);
89
- timeoutRef.current = null;
90
- }
91
- setHasTimedOut(false);
92
- setIsPolling(true);
93
- setIsPending(false);
94
- timeoutRef.current = setTimeout(() => {
95
- stopPolling();
96
- setHasTimedOut(true);
97
- if (onTimeout) {
98
- onTimeout({
99
- startPolling,
100
- stopPolling,
101
- reset
102
- });
103
- }
104
- }, POLLING_DURATION);
105
- }, [stopPolling, onTimeout, reset]);
106
- const wrappedCallback = useCallback(async () => {
107
- if (isPending) {
108
- return;
109
- }
110
- setIsPending(true);
111
- try {
112
- await callback();
113
- } finally {
114
- setIsPending(false);
115
- }
116
- }, [callback, isPending]);
117
- useInterval(isPolling ? wrappedCallback : () => {}, isPolling ? POLLING_INTERVAL : null);
118
- return {
119
- reset,
120
- startPolling,
121
- stopPolling,
122
- isPolling,
123
- hasTimedOut
124
- };
125
- }
126
- export { useAsyncPolling, POLLING_INTERVAL, POLLING_DURATION, containersEqual, getRequestedContainersFromUrl, containerDisplayName, CONTAINER_MAP, convertContainerToType, removeRequestedContainersFromUrl };