@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.
- package/CHANGELOG.md +9 -0
- package/dist/cjs/common/ui/container-icon/index.js +1 -1
- package/dist/cjs/common/ui/loom-avatar/main.js +1 -1
- package/dist/cjs/common/ui/separator/index.js +1 -1
- package/dist/cjs/common/ui/team-containers-skeleton/index.js +1 -1
- package/dist/cjs/common/ui/team-containers-skeleton/linked-container-card-skeleton/index.js +1 -1
- package/dist/cjs/common/ui/team-link-card-actions/index.js +1 -1
- package/dist/cjs/common/utils/get-container-properties.js +1 -1
- package/dist/cjs/next/common/ui/team-container-skeleton/index.js +1 -1
- package/dist/cjs/next/ui/team-containers/add-container-card/index.js +1 -1
- package/dist/cjs/next/ui/team-containers/team-link-card/index.js +1 -1
- package/dist/cjs/ui/team-containers/add-container-card/index.js +1 -1
- package/dist/cjs/ui/team-containers/linked-container-card/index.js +1 -1
- package/dist/cjs/ui/team-containers/main.js +7 -16
- package/dist/cjs/ui/team-containers/no-product-access-empty-state/index.js +1 -1
- package/dist/cjs/ui/team-containers/no-product-access-empty-state/no-product-access-icon/index.js +1 -1
- package/dist/cjs/ui/team-containers/team-link-card/index.js +1 -1
- package/dist/cjs/ui/team-containers/team-link-card/team-link-card-title.js +1 -1
- package/dist/es2019/common/ui/container-icon/index.js +1 -1
- package/dist/es2019/common/ui/loom-avatar/main.js +1 -1
- package/dist/es2019/common/ui/separator/index.js +1 -1
- package/dist/es2019/common/ui/team-containers-skeleton/index.js +1 -1
- package/dist/es2019/common/ui/team-containers-skeleton/linked-container-card-skeleton/index.js +1 -1
- package/dist/es2019/common/ui/team-link-card-actions/index.js +1 -1
- package/dist/es2019/common/utils/get-container-properties.js +1 -1
- package/dist/es2019/next/common/ui/team-container-skeleton/index.js +1 -1
- package/dist/es2019/next/ui/team-containers/add-container-card/index.js +1 -1
- package/dist/es2019/next/ui/team-containers/team-link-card/index.js +1 -1
- package/dist/es2019/ui/team-containers/add-container-card/index.js +1 -1
- package/dist/es2019/ui/team-containers/linked-container-card/index.js +1 -1
- package/dist/es2019/ui/team-containers/main.js +7 -16
- package/dist/es2019/ui/team-containers/no-product-access-empty-state/index.js +1 -1
- package/dist/es2019/ui/team-containers/no-product-access-empty-state/no-product-access-icon/index.js +1 -1
- package/dist/es2019/ui/team-containers/team-link-card/index.js +1 -1
- package/dist/es2019/ui/team-containers/team-link-card/team-link-card-title.js +1 -1
- package/dist/esm/common/ui/container-icon/index.js +1 -1
- package/dist/esm/common/ui/loom-avatar/main.js +1 -1
- package/dist/esm/common/ui/separator/index.js +1 -1
- package/dist/esm/common/ui/team-containers-skeleton/index.js +1 -1
- package/dist/esm/common/ui/team-containers-skeleton/linked-container-card-skeleton/index.js +1 -1
- package/dist/esm/common/ui/team-link-card-actions/index.js +1 -1
- package/dist/esm/common/utils/get-container-properties.js +1 -1
- package/dist/esm/next/common/ui/team-container-skeleton/index.js +1 -1
- package/dist/esm/next/ui/team-containers/add-container-card/index.js +1 -1
- package/dist/esm/next/ui/team-containers/team-link-card/index.js +1 -1
- package/dist/esm/ui/team-containers/add-container-card/index.js +1 -1
- package/dist/esm/ui/team-containers/linked-container-card/index.js +1 -1
- package/dist/esm/ui/team-containers/main.js +7 -16
- package/dist/esm/ui/team-containers/no-product-access-empty-state/index.js +1 -1
- package/dist/esm/ui/team-containers/no-product-access-empty-state/no-product-access-icon/index.js +1 -1
- package/dist/esm/ui/team-containers/team-link-card/index.js +1 -1
- package/dist/esm/ui/team-containers/team-link-card/team-link-card-title.js +1 -1
- package/dist/types/ui/team-containers/main.d.ts +1 -1
- package/dist/types/ui/team-containers/types.d.ts +0 -5
- package/dist/types-ts4.5/ui/team-containers/main.d.ts +1 -1
- package/dist/types-ts4.5/ui/team-containers/types.d.ts +0 -5
- package/package.json +1 -3
- package/dist/cjs/controllers/hooks/use-requested-container/index.js +0 -358
- package/dist/cjs/controllers/hooks/use-requested-container/utils.js +0 -165
- package/dist/es2019/controllers/hooks/use-requested-container/index.js +0 -288
- package/dist/es2019/controllers/hooks/use-requested-container/utils.js +0 -126
- package/dist/esm/controllers/hooks/use-requested-container/index.js +0 -350
- package/dist/esm/controllers/hooks/use-requested-container/utils.js +0 -153
- package/dist/types/controllers/hooks/use-requested-container/index.d.ts +0 -25
- package/dist/types/controllers/hooks/use-requested-container/utils.d.ts +0 -34
- package/dist/types-ts4.5/controllers/hooks/use-requested-container/index.d.ts +0 -25
- 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 };
|