@forge/react 10.2.0-next.0 → 10.2.1-next.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 +14 -0
- package/out/__test__/hostConfig.test.js +6 -1
- package/out/__test__/reconciler.test.js +3 -2
- package/out/__test__/reconcilerTestRenderer.js +2 -0
- package/out/__test__/testUtils.js +6 -0
- package/out/components/index.d.ts +8 -0
- package/out/components/index.d.ts.map +1 -1
- package/out/components/index.js +8 -0
- package/out/components/uikit2-components.js +1 -0
- package/out/hooks/__test__/confluenceEntity.test.js +3 -1
- package/out/hooks/__test__/jiraEntity.test.js +2 -1
- package/out/hooks/__test__/mockPropertyHook.d.ts +3 -0
- package/out/hooks/__test__/mockPropertyHook.d.ts.map +1 -1
- package/out/hooks/__test__/mockPropertyHook.js +5 -0
- package/out/hooks/__test__/useConfig.test.js +4 -1
- package/out/hooks/__test__/useEntityProperty.test.js +3 -3
- package/out/hooks/__test__/useProductContext.test.js +3 -1
- package/out/hooks/confluenceEntity.d.ts +4 -0
- package/out/hooks/confluenceEntity.d.ts.map +1 -1
- package/out/hooks/confluenceEntity.js +9 -0
- package/out/hooks/jiraEntity.d.ts +4 -0
- package/out/hooks/jiraEntity.d.ts.map +1 -1
- package/out/hooks/jiraEntity.js +9 -0
- package/out/hooks/useContentProperty.d.ts +9 -0
- package/out/hooks/useContentProperty.d.ts.map +1 -1
- package/out/hooks/useContentProperty.js +9 -0
- package/out/hooks/useEntityProperty.js +7 -1
- package/out/hooks/useForm.js +23 -1
- package/out/hooks/useIssueProperty.d.ts +9 -0
- package/out/hooks/useIssueProperty.d.ts.map +1 -1
- package/out/hooks/useIssueProperty.js +10 -1
- package/out/hooks/useSpaceProperty.d.ts +9 -0
- package/out/hooks/useSpaceProperty.d.ts.map +1 -1
- package/out/hooks/useSpaceProperty.js +9 -0
- package/out/hooks/utils/apiRequestUtils.js +2 -0
- package/out/hooks/utils/valueUtils.js +2 -0
- package/out/reconciler.d.ts +13 -0
- package/out/reconciler.d.ts.map +1 -1
- package/out/reconciler.js +35 -0
- package/out/types/effect.d.ts +3 -0
- package/out/types/effect.d.ts.map +1 -1
- package/out/types/extension.d.ts +4 -0
- package/out/types/extension.d.ts.map +1 -1
- package/package.json +1 -1
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @forge/react
|
|
2
2
|
|
|
3
|
+
## 10.2.1-next.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 028fcfc: Include JSComments to be included in the build output
|
|
8
|
+
|
|
9
|
+
## 10.2.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- e14a6c7: Add Frame component support in UI Kit [EAP].
|
|
14
|
+
|
|
15
|
+
For more information, see the [Frame component documentation](https://developer.atlassian.com/platform/forge/ui-kit/components/frame).
|
|
16
|
+
|
|
3
17
|
## 10.2.0-next.0
|
|
4
18
|
|
|
5
19
|
### Minor Changes
|
|
@@ -48,7 +48,7 @@ describe('hostConfig used functions', () => {
|
|
|
48
48
|
reconciler_1.hostConfig.appendChild(parent, child);
|
|
49
49
|
expect(parent).toHaveProperty('children', [child]);
|
|
50
50
|
reconciler_1.hostConfig.appendChild(parent, child);
|
|
51
|
-
expect(parent).toHaveProperty('children', [child]);
|
|
51
|
+
expect(parent).toHaveProperty('children', [child]); // Still just one child!
|
|
52
52
|
}
|
|
53
53
|
});
|
|
54
54
|
it('appendChildToContainer', () => {
|
|
@@ -142,6 +142,11 @@ describe('hostConfig used functions', () => {
|
|
|
142
142
|
}
|
|
143
143
|
});
|
|
144
144
|
});
|
|
145
|
+
// The reason for including the following tests is to ensure that any changes to the
|
|
146
|
+
// HostConfig are verified both in the source and in the tests. The need to check that
|
|
147
|
+
// some of the functions are even defined indicates that we don't need to declare
|
|
148
|
+
// all the functions in the reconciler, but keeping them with the tets ensures we do the
|
|
149
|
+
// appropriate due diligence on any changes. It also ensures we have good code coverage!
|
|
145
150
|
describe('hostConfig unused functions', () => {
|
|
146
151
|
it('should return empty object from getRootHostContext', () => {
|
|
147
152
|
expect(reconciler_1.hostConfig.getRootHostContext(emptyForgeDoc)).toEqual({});
|
|
@@ -33,13 +33,14 @@ describe('Reconcilation', () => {
|
|
|
33
33
|
});
|
|
34
34
|
it('forgeDoc is created on initial render', () => {
|
|
35
35
|
const forgeDoc = (0, testUtils_1.getLastBridgeCallForgeDoc)(bridgeCalls);
|
|
36
|
-
expect(forgeDoc).toHaveProperty(`children[${TEXT}].type`, 'Text');
|
|
37
|
-
expect(forgeDoc).toHaveProperty(`children[${BUTTON}].type`, 'Button');
|
|
36
|
+
expect(forgeDoc).toHaveProperty(`children[${TEXT}].type`, 'Text'); // First child is text
|
|
37
|
+
expect(forgeDoc).toHaveProperty(`children[${BUTTON}].type`, 'Button'); // Second child is button
|
|
38
38
|
expect(forgeDoc).toHaveProperty(`children[${STATIC_TEXT}].type`, 'Lozenge');
|
|
39
39
|
expect(forgeDoc).toMatchSnapshot();
|
|
40
40
|
});
|
|
41
41
|
it('forgeDoc is updated on state update', () => {
|
|
42
42
|
let forgeDoc = (0, testUtils_1.getLastBridgeCallForgeDoc)(bridgeCalls);
|
|
43
|
+
// Get the click handler for the 1st button
|
|
43
44
|
const onClick = (0, get_1.default)(forgeDoc, `children[${BUTTON}].props.onClick`);
|
|
44
45
|
expect(onClick).not.toBeUndefined();
|
|
45
46
|
onClick();
|
|
@@ -4,6 +4,8 @@ exports.addConfig = exports.create = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const React = tslib_1.__importStar(require("react"));
|
|
6
6
|
const reconciler_1 = require("../reconciler");
|
|
7
|
+
// NOTE: This only works with React 18
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7
9
|
const _act = React.unstable_act;
|
|
8
10
|
const act = _act;
|
|
9
11
|
const create = async (element) => {
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.findElementInForgeDoc = exports.getLastBridgeCallForgeDoc = exports.getLastBridgeCall = exports.setupBridge = void 0;
|
|
4
|
+
// In an actual UI Kit 2 application the bridge is added to the global namespace by scripts served
|
|
5
|
+
// from the Forge CDN. In order to be able to test our reconciler we need to see what data is being
|
|
6
|
+
// passed over the bridge. This function simulates the function and allows tests to access all the
|
|
7
|
+
// calls that are made.
|
|
4
8
|
const setupBridge = () => {
|
|
5
9
|
const bridgeCalls = [];
|
|
10
|
+
// @ts-ignore
|
|
6
11
|
global['self'] = {
|
|
7
12
|
__bridge: {
|
|
13
|
+
// @ts-ignore to get past type error from new tsconfig lib
|
|
8
14
|
callBridge: (cmd, data) => {
|
|
9
15
|
bridgeCalls.push({ cmd, data });
|
|
10
16
|
}
|
|
@@ -9,7 +9,15 @@ export declare const UserGroup: (props: UserGroupProps) => ForgeElement;
|
|
|
9
9
|
export declare const Em: (props: MarkupProps) => ForgeElement;
|
|
10
10
|
export declare const Strike: (props: MarkupProps) => ForgeElement;
|
|
11
11
|
export declare const Strong: (props: MarkupProps) => ForgeElement;
|
|
12
|
+
/**
|
|
13
|
+
* `Frame` component is in EAP (Early Access Program).
|
|
14
|
+
*
|
|
15
|
+
* For more information, see the {@link https://developer.atlassian.com/platform/forge/ui-kit/components/frame|Frame component} documentation.
|
|
16
|
+
*/
|
|
12
17
|
export declare const Frame: (props: FrameProps) => ForgeElement;
|
|
18
|
+
/**
|
|
19
|
+
* Export Code generated UI Kit 2 Components
|
|
20
|
+
*/
|
|
13
21
|
export * from './uikit2-components';
|
|
14
22
|
declare type CheckboxGroupProps = {
|
|
15
23
|
name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,WAAW,EACX,gBAAgB,IAAI,UAAU,EAC9B,eAAe,IAAI,SAAS,EAC5B,eAAe,IAAI,SAAS,EAC5B,qBAAqB,IAAI,eAAe,EACxC,cAAc,EACd,SAAS,EACT,UAAU,EACX,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,eAAO,MAAM,KAAK,UAAiC,UAAU,KAAK,YAAY,CAAC;AAC/E,eAAO,MAAM,IAAI,UAAgC,SAAS,KAAK,YAAY,CAAC;AAC5E,eAAO,MAAM,IAAI,UAAgC,SAAS,KAAK,YAAY,CAAC;AAC5E,eAAO,MAAM,UAAU,UAAsC,eAAe,KAAK,YAAY,CAAC;AAC9F,eAAO,MAAM,IAAI,UAAgC,SAAS,KAAK,YAAY,CAAC;AAC5E,eAAO,MAAM,SAAS,UAAqC,cAAc,KAAK,YAAY,CAAC;AAE3F,eAAO,MAAM,EAAE,UAA8B,WAAW,KAAK,YAAY,CAAC;AAC1E,eAAO,MAAM,MAAM,UAAkC,WAAW,KAAK,YAAY,CAAC;AAClF,eAAO,MAAM,MAAM,UAAkC,WAAW,KAAK,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,WAAW,EACX,gBAAgB,IAAI,UAAU,EAC9B,eAAe,IAAI,SAAS,EAC5B,eAAe,IAAI,SAAS,EAC5B,qBAAqB,IAAI,eAAe,EACxC,cAAc,EACd,SAAS,EACT,UAAU,EACX,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,eAAO,MAAM,KAAK,UAAiC,UAAU,KAAK,YAAY,CAAC;AAC/E,eAAO,MAAM,IAAI,UAAgC,SAAS,KAAK,YAAY,CAAC;AAC5E,eAAO,MAAM,IAAI,UAAgC,SAAS,KAAK,YAAY,CAAC;AAC5E,eAAO,MAAM,UAAU,UAAsC,eAAe,KAAK,YAAY,CAAC;AAC9F,eAAO,MAAM,IAAI,UAAgC,SAAS,KAAK,YAAY,CAAC;AAC5E,eAAO,MAAM,SAAS,UAAqC,cAAc,KAAK,YAAY,CAAC;AAE3F,eAAO,MAAM,EAAE,UAA8B,WAAW,KAAK,YAAY,CAAC;AAC1E,eAAO,MAAM,MAAM,UAAkC,WAAW,KAAK,YAAY,CAAC;AAClF,eAAO,MAAM,MAAM,UAAkC,WAAW,KAAK,YAAY,CAAC;AAElF;;;;GAIG;AACH,eAAO,MAAM,KAAK,UAAiC,UAAU,KAAK,YAAY,CAAC;AAE/E;;GAEG;AACH,cAAc,qBAAqB,CAAC;AAGpC,aAAK,kBAAkB,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC3C,YAAY,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACnD,CAAC;AACF,eAAO,MAAM,aAAa,UAAyC,kBAAkB,KAAK,YAAY,CAAC"}
|
package/out/components/index.js
CHANGED
|
@@ -11,6 +11,14 @@ exports.UserGroup = 'UserGroup';
|
|
|
11
11
|
exports.Em = 'Em';
|
|
12
12
|
exports.Strike = 'Strike';
|
|
13
13
|
exports.Strong = 'Strong';
|
|
14
|
+
/**
|
|
15
|
+
* `Frame` component is in EAP (Early Access Program).
|
|
16
|
+
*
|
|
17
|
+
* For more information, see the {@link https://developer.atlassian.com/platform/forge/ui-kit/components/frame|Frame component} documentation.
|
|
18
|
+
*/
|
|
14
19
|
exports.Frame = 'Frame';
|
|
20
|
+
/**
|
|
21
|
+
* Export Code generated UI Kit 2 Components
|
|
22
|
+
*/
|
|
15
23
|
tslib_1.__exportStar(require("./uikit2-components"), exports);
|
|
16
24
|
exports.CheckboxGroup = 'CheckboxGroup';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// defining mock functions above import so they are initialised before jest.mock runs
|
|
3
4
|
const mockRequestConf = jest.fn();
|
|
4
5
|
const mockGetContext = jest.fn(async () => mockPropertyHook_1.mockConfContext);
|
|
5
6
|
const confluenceEntity_1 = require("../confluenceEntity");
|
|
@@ -54,7 +55,7 @@ describe('confluenceEntity', () => {
|
|
|
54
55
|
it('if the property exists, it should return its value', async () => {
|
|
55
56
|
const output = await contentEntity.get();
|
|
56
57
|
expect(output).toEqual(mockPropertyHook_1.EXISTING_PROP_VALUE);
|
|
57
|
-
expect(mockRequestConf).toHaveBeenCalledTimes(1);
|
|
58
|
+
expect(mockRequestConf).toHaveBeenCalledTimes(1); // stop making further requests
|
|
58
59
|
});
|
|
59
60
|
it('should throw an error if the GET request fails', async () => {
|
|
60
61
|
mockRequestConf.mockResolvedValueOnce(mockPropertyHook_1.mockFailedRes);
|
|
@@ -93,6 +94,7 @@ describe('confluenceEntity', () => {
|
|
|
93
94
|
const contentGetUrl = contentEndpoints.fetch('forge-MOCK_LOCAL_ID-MOCK_PROP_KEY');
|
|
94
95
|
const contentGetBody = expect.objectContaining({ method: 'GET' });
|
|
95
96
|
const contentPutUrl = contentEndpoints.update('MOCK_PROP_ID');
|
|
97
|
+
// both value & version props need to be present in body string
|
|
96
98
|
const valueUpdateStr = `"value":${mockPropertyHook_1.UPDATED_PROP_VALUE}`;
|
|
97
99
|
const versionUpdateStr = `"version":{"number":${mockPropertyHook_1.UPDATED_PROP_VALUE}`;
|
|
98
100
|
const contentPutBody = (updateStr) => expect.objectContaining({
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// defining mock functions above import so they are initialised before jest.mock runs
|
|
3
4
|
const mockRequestJira = jest.fn();
|
|
4
5
|
const mockGetContext = jest.fn(async () => mockPropertyHook_1.mockJiraContext);
|
|
5
6
|
const jiraEntity_1 = require("../jiraEntity");
|
|
@@ -48,7 +49,7 @@ describe('jiraIssuePropsManager', () => {
|
|
|
48
49
|
it('if the property exists, it should return its value', async () => {
|
|
49
50
|
const output = await issueProps.get();
|
|
50
51
|
expect(output).toEqual(mockPropertyHook_1.EXISTING_PROP_VALUE);
|
|
51
|
-
expect(mockRequestJira).toHaveBeenCalledTimes(1);
|
|
52
|
+
expect(mockRequestJira).toHaveBeenCalledTimes(1); // stop making further requests
|
|
52
53
|
});
|
|
53
54
|
it('should throw an error if the GET request fails', async () => {
|
|
54
55
|
mockRequestJira.mockResolvedValueOnce(mockPropertyHook_1.mockFailedRes);
|
|
@@ -2,6 +2,9 @@ import type { EntityContext } from '../types';
|
|
|
2
2
|
export declare const DEFAULT_PROP_VALUE: number, EXISTING_PROP_VALUE: number, UPDATED_PROP_VALUE: number;
|
|
3
3
|
export declare const mockConfContext: EntityContext;
|
|
4
4
|
export declare const mockJiraContext: EntityContext;
|
|
5
|
+
/**
|
|
6
|
+
* Mock functions for API calls
|
|
7
|
+
*/
|
|
5
8
|
export declare const mockFailedRes: {
|
|
6
9
|
ok: boolean;
|
|
7
10
|
status: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mockPropertyHook.d.ts","sourceRoot":"","sources":["../../../src/hooks/__test__/mockPropertyHook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG9C,eAAO,MAAO,kBAAkB,UAAE,mBAAmB,UAAE,kBAAkB,QAAa,CAAC;AAEvF,eAAO,MAAM,eAAe,EAAE,aAU7B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,aAO7B,CAAC;
|
|
1
|
+
{"version":3,"file":"mockPropertyHook.d.ts","sourceRoot":"","sources":["../../../src/hooks/__test__/mockPropertyHook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG9C,eAAO,MAAO,kBAAkB,UAAE,mBAAmB,UAAE,kBAAkB,QAAa,CAAC;AAEvF,eAAO,MAAM,eAAe,EAAE,aAU7B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,aAO7B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa;;;CAGzB,CAAC;AACF,eAAO,MAAM,sBAAsB;;;;;;;;;;;;CAMlC,CAAC;AACF,eAAO,MAAM,yBAAyB;;;;;;CAMrC,CAAC;AACF,eAAO,MAAM,iBAAiB;;;;;;;CAI7B,CAAC;AACF,eAAO,MAAM,sBAAsB;;;;;;;CAIlC,CAAC;AACF,eAAO,MAAM,yBAAyB;;;;;;;CAIrC,CAAC;AACF,eAAO,MAAM,iBAAiB;;;CAG7B,CAAC;AAEF,eAAO,MAAM,kBAAkB;;;CAG9B,CAAC;AACF,eAAO,MAAM,sBAAsB;;;;;;;CAIlC,CAAC;AACF,eAAO,MAAM,yBAAyB;;;CAGrC,CAAC"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
var _a;
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.mockJiraGetNonExistentRes = exports.mockJiraGetExistingRes = exports.mockJiraSuccessRes = exports.mockConfDeleteRes = exports.mockConfUpdateFunctionRes = exports.mockConfUpdateValueRes = exports.mockConfCreateRes = exports.mockConfGetNonExistentRes = exports.mockConfGetExistingRes = exports.mockFailedRes = exports.mockJiraContext = exports.mockConfContext = exports.UPDATED_PROP_VALUE = exports.EXISTING_PROP_VALUE = exports.DEFAULT_PROP_VALUE = void 0;
|
|
5
|
+
// mock property values
|
|
5
6
|
_a = [1, 2, 3], exports.DEFAULT_PROP_VALUE = _a[0], exports.EXISTING_PROP_VALUE = _a[1], exports.UPDATED_PROP_VALUE = _a[2];
|
|
6
7
|
exports.mockConfContext = {
|
|
7
8
|
localId: 'MOCK_LOCAL_ID',
|
|
@@ -22,6 +23,9 @@ exports.mockJiraContext = {
|
|
|
22
23
|
}
|
|
23
24
|
}
|
|
24
25
|
};
|
|
26
|
+
/**
|
|
27
|
+
* Mock functions for API calls
|
|
28
|
+
*/
|
|
25
29
|
exports.mockFailedRes = {
|
|
26
30
|
ok: false,
|
|
27
31
|
status: 400
|
|
@@ -59,6 +63,7 @@ exports.mockConfDeleteRes = {
|
|
|
59
63
|
ok: true,
|
|
60
64
|
status: 204
|
|
61
65
|
};
|
|
66
|
+
// jira issue responses
|
|
62
67
|
exports.mockJiraSuccessRes = {
|
|
63
68
|
ok: true,
|
|
64
69
|
status: 201
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
// defining mock function above import so it is initialised before jest.mock runs
|
|
5
6
|
const mockGetContext = jest.fn(async () => null);
|
|
6
7
|
const react_1 = tslib_1.__importStar(require("react"));
|
|
7
8
|
const reconcilerTestRenderer_1 = tslib_1.__importDefault(require("../../__test__/reconcilerTestRenderer"));
|
|
@@ -24,6 +25,7 @@ const MOCK_CONTEXT_NO_CONFIG = {
|
|
|
24
25
|
extension: {}
|
|
25
26
|
};
|
|
26
27
|
const configListener = jest.fn();
|
|
28
|
+
// react app fragment to be load useProductContext hook
|
|
27
29
|
const renderTest = async () => {
|
|
28
30
|
const Test = () => {
|
|
29
31
|
const config = (0, useConfig_1.useConfig)();
|
|
@@ -43,7 +45,8 @@ describe('useConfig', () => {
|
|
|
43
45
|
it('when there is no config, outputs undefined', async () => {
|
|
44
46
|
mockGetContext.mockResolvedValue(MOCK_CONTEXT_NO_CONFIG);
|
|
45
47
|
await renderTest();
|
|
46
|
-
expect(configListener.mock.calls[0][0]).toEqual(undefined);
|
|
48
|
+
expect(configListener.mock.calls[0][0]).toEqual(undefined); // initial rendered value
|
|
49
|
+
// no change to undef value after productContext call, do not re-render
|
|
47
50
|
expect(configListener).not.toHaveBeenNthCalledWith(2, expect.anything);
|
|
48
51
|
});
|
|
49
52
|
});
|
|
@@ -42,7 +42,7 @@ const renderTest = async (action = renderActions.noAction, retryCount) => {
|
|
|
42
42
|
(0, react_1.useEffect)(() => {
|
|
43
43
|
if (action === renderActions.toUpdate) {
|
|
44
44
|
setProp(mockPropertyHook_1.UPDATED_PROP_VALUE, retryCount).catch((err) => {
|
|
45
|
-
console.error(err);
|
|
45
|
+
console.error(err); // eslint-disable-line no-console
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
48
|
if (action === renderActions.toDelete) {
|
|
@@ -84,7 +84,7 @@ describe('useEntityProperty', () => {
|
|
|
84
84
|
it('makes 2 retries (by default) when initial attempt fails', async () => {
|
|
85
85
|
mockRequest.mockResolvedValue(() => mockPropertyHook_1.mockFailedRes);
|
|
86
86
|
await renderTest(renderActions.toUpdate);
|
|
87
|
-
expect(mockRequest).toHaveBeenNthCalledWith(2, 'update');
|
|
87
|
+
expect(mockRequest).toHaveBeenNthCalledWith(2, 'update'); // initial attempt
|
|
88
88
|
expect(mockRequest).toHaveBeenNthCalledWith(3, 'update');
|
|
89
89
|
expect(mockRequest).toHaveBeenNthCalledWith(4, 'update');
|
|
90
90
|
expect(mockRequest).not.toHaveBeenNthCalledWith(5, 'update');
|
|
@@ -92,7 +92,7 @@ describe('useEntityProperty', () => {
|
|
|
92
92
|
it('stops retrying when a previous retry succeeds', async () => {
|
|
93
93
|
mockRequest.mockResolvedValueOnce(() => mockPropertyHook_1.mockFailedRes).mockResolvedValueOnce(() => mockPropertyHook_1.mockConfUpdateValueRes);
|
|
94
94
|
await renderTest(renderActions.toUpdate);
|
|
95
|
-
expect(mockRequest).toHaveBeenNthCalledWith(2, 'update');
|
|
95
|
+
expect(mockRequest).toHaveBeenNthCalledWith(2, 'update'); // initial attempt
|
|
96
96
|
expect(mockRequest).toHaveBeenNthCalledWith(3, 'update');
|
|
97
97
|
expect(mockRequest).not.toHaveBeenNthCalledWith(4, 'update');
|
|
98
98
|
});
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
// defining mock function above import so it is initialised before jest.mock runs
|
|
5
6
|
const mockGetContext = jest.fn(async () => null);
|
|
6
7
|
const useProductContext_1 = require("../useProductContext");
|
|
7
8
|
const react_1 = tslib_1.__importStar(require("react"));
|
|
@@ -24,6 +25,7 @@ const MOCK_CONTEXT = {
|
|
|
24
25
|
timezone: 'DUMMY-timezone'
|
|
25
26
|
};
|
|
26
27
|
const prodContListener = jest.fn();
|
|
28
|
+
// react app fragment to be load useProductContext hook
|
|
27
29
|
const renderTest = async () => {
|
|
28
30
|
const Test = () => {
|
|
29
31
|
const prodCont = (0, useProductContext_1.useProductContext)();
|
|
@@ -52,7 +54,7 @@ describe('useProductContext', () => {
|
|
|
52
54
|
});
|
|
53
55
|
await renderTest();
|
|
54
56
|
expect(prodContListener).not.toHaveBeenNthCalledWith(2, expect.anything());
|
|
55
|
-
await new Promise((res) => setTimeout(res, LOAD_TIME * 2));
|
|
57
|
+
await new Promise((res) => setTimeout(res, LOAD_TIME * 2)); // wait for data to load
|
|
56
58
|
expect(prodContListener.mock.calls[1][0]).toEqual(MOCK_CONTEXT);
|
|
57
59
|
}, LOAD_TIME * 3);
|
|
58
60
|
});
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import type { ConfEndpointInitializer, ManagePropsData, ConfluenceEntityType, EntityManager } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* given an entityType and a product context, returns functions that uses property data to
|
|
4
|
+
* output URLs to use for property management via Confluence v2 REST API
|
|
5
|
+
*/
|
|
2
6
|
export declare const confAPIEndpoints: ({ entityType, context }: ConfEndpointInitializer) => {
|
|
3
7
|
create: () => string;
|
|
4
8
|
fetch: (propertyKey: string) => string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"confluenceEntity.d.ts","sourceRoot":"","sources":["../../src/hooks/confluenceEntity.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,uBAAuB,EAEvB,eAAe,EACf,oBAAoB,EACpB,aAAa,EAEd,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"confluenceEntity.d.ts","sourceRoot":"","sources":["../../src/hooks/confluenceEntity.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,uBAAuB,EAEvB,eAAe,EACf,oBAAoB,EACpB,aAAa,EAEd,MAAM,SAAS,CAAC;AAEjB;;;GAGG;AACH,eAAO,MAAM,gBAAgB,4BAA6B,uBAAuB;;yBAqBxD,MAAM;yBACN,MAAM;yBACN,MAAM;CAE9B,CAAC;AAEF,eAAO,MAAM,gBAAgB;gBAIiB,oBAAoB;8BAqGjE,CAAC"}
|
|
@@ -5,6 +5,10 @@ const bridge_1 = require("@forge/bridge");
|
|
|
5
5
|
const apiRequestUtils_1 = require("./utils/apiRequestUtils");
|
|
6
6
|
const valueUtils_1 = require("./utils/valueUtils");
|
|
7
7
|
const types_1 = require("./types");
|
|
8
|
+
/**
|
|
9
|
+
* given an entityType and a product context, returns functions that uses property data to
|
|
10
|
+
* output URLs to use for property management via Confluence v2 REST API
|
|
11
|
+
*/
|
|
8
12
|
const confAPIEndpoints = ({ entityType, context }) => {
|
|
9
13
|
let entityId, urlEntity;
|
|
10
14
|
switch (entityType) {
|
|
@@ -40,6 +44,7 @@ const confluenceEntity = ({ entityType, origPropertyKey, initValue }) => {
|
|
|
40
44
|
origPropertyKey
|
|
41
45
|
});
|
|
42
46
|
};
|
|
47
|
+
// fetches existing prop value from server. to be reused for GET, UPDATE, DELETE operations
|
|
43
48
|
const fetchOriginal = async ({ endpointFactory, propertyKey }) => {
|
|
44
49
|
const url = endpointFactory.fetch(propertyKey);
|
|
45
50
|
const response = await (0, apiRequestUtils_1.makeRequest)({ url, apiMethod, method: 'GET' });
|
|
@@ -47,7 +52,9 @@ const confluenceEntity = ({ entityType, origPropertyKey, initValue }) => {
|
|
|
47
52
|
const existingData = await (0, apiRequestUtils_1.getJSONData)(response);
|
|
48
53
|
return existingData.results[0];
|
|
49
54
|
};
|
|
55
|
+
// named `deleteProp` since `delete` is reserved word
|
|
50
56
|
const deleteProp = async ({ endpointFactory, propertyKey }) => {
|
|
57
|
+
// fetch original prop first to get its id
|
|
51
58
|
const originalProp = await fetchOriginal({ endpointFactory, propertyKey });
|
|
52
59
|
if (!originalProp) {
|
|
53
60
|
throw new types_1.EntityPropertyRequestFailedError({
|
|
@@ -67,6 +74,7 @@ const confluenceEntity = ({ entityType, origPropertyKey, initValue }) => {
|
|
|
67
74
|
if (existingProp) {
|
|
68
75
|
return existingProp.value;
|
|
69
76
|
}
|
|
77
|
+
// if property doesn't exist, create it
|
|
70
78
|
const resolvedInitVal = await (0, valueUtils_1.resolveValue)(initValue);
|
|
71
79
|
const url = endpointFactory.create();
|
|
72
80
|
const body = JSON.stringify({ key: propertyKey, value: resolvedInitVal });
|
|
@@ -75,6 +83,7 @@ const confluenceEntity = ({ entityType, origPropertyKey, initValue }) => {
|
|
|
75
83
|
return (await (0, apiRequestUtils_1.getJSONData)(response)).value;
|
|
76
84
|
};
|
|
77
85
|
const update = async ({ endpointFactory, propertyKey }, valueUpdate) => {
|
|
86
|
+
// fetch original prop first to update based on its value + version + id
|
|
78
87
|
const originalProp = await fetchOriginal({ endpointFactory, propertyKey });
|
|
79
88
|
if (!originalProp) {
|
|
80
89
|
throw new types_1.EntityPropertyRequestFailedError({
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import type { EntityContext, ManagePropsData } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* given a context, returns functions that uses property data to
|
|
4
|
+
* output URLs to use for issue property management via Jira v2 REST API
|
|
5
|
+
*/
|
|
2
6
|
export declare const issueAPIEndpoints: (context: EntityContext) => {
|
|
3
7
|
create: () => string;
|
|
4
8
|
fetch: (propertyKey: string) => string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jiraEntity.d.ts","sourceRoot":"","sources":["../../src/hooks/jiraEntity.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAe,eAAe,EAAyB,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"jiraEntity.d.ts","sourceRoot":"","sources":["../../src/hooks/jiraEntity.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAe,eAAe,EAAyB,MAAM,SAAS,CAAC;AAElG;;;GAGG;AACH,eAAO,MAAM,iBAAiB,YAAa,aAAa;;yBAM/B,MAAM;0BACL,MAAM;0BACN,MAAM;CAE/B,CAAC;AAEF,eAAO,MAAM,qBAAqB;;;;CA6GjC,CAAC"}
|
package/out/hooks/jiraEntity.js
CHANGED
|
@@ -5,6 +5,10 @@ const bridge_1 = require("@forge/bridge");
|
|
|
5
5
|
const apiRequestUtils_1 = require("./utils/apiRequestUtils");
|
|
6
6
|
const valueUtils_1 = require("./utils/valueUtils");
|
|
7
7
|
const types_1 = require("./types");
|
|
8
|
+
/**
|
|
9
|
+
* given a context, returns functions that uses property data to
|
|
10
|
+
* output URLs to use for issue property management via Jira v2 REST API
|
|
11
|
+
*/
|
|
8
12
|
const issueAPIEndpoints = (context) => {
|
|
9
13
|
const issueId = context.extension.issue?.id;
|
|
10
14
|
if (!issueId)
|
|
@@ -28,6 +32,7 @@ const jiraIssuePropsManager = ({ origPropertyKey, initValue }) => {
|
|
|
28
32
|
origPropertyKey
|
|
29
33
|
});
|
|
30
34
|
};
|
|
35
|
+
// fetches existing prop value from server. to be reused for GET, UPDATE, DELETE operations
|
|
31
36
|
const fetchOriginal = async ({ endpointFactory, propertyKey }) => {
|
|
32
37
|
const url = endpointFactory.fetch(propertyKey);
|
|
33
38
|
const response = await (0, apiRequestUtils_1.makeRequest)({ url, apiMethod, method: 'GET' });
|
|
@@ -45,6 +50,7 @@ const jiraIssuePropsManager = ({ origPropertyKey, initValue }) => {
|
|
|
45
50
|
const existingData = await (0, apiRequestUtils_1.getJSONData)(response);
|
|
46
51
|
return existingData;
|
|
47
52
|
};
|
|
53
|
+
// named `deleteProp` since `delete` is reserved word
|
|
48
54
|
const deleteProp = async ({ endpointFactory, propertyKey }) => {
|
|
49
55
|
const url = endpointFactory.delete(propertyKey);
|
|
50
56
|
const response = await (0, apiRequestUtils_1.makeRequest)({ url, apiMethod, method: 'DELETE' });
|
|
@@ -55,6 +61,7 @@ const jiraIssuePropsManager = ({ origPropertyKey, initValue }) => {
|
|
|
55
61
|
if (existingProp) {
|
|
56
62
|
return existingProp.value;
|
|
57
63
|
}
|
|
64
|
+
// if property doesn't exist, create it
|
|
58
65
|
const resolvedInitVal = await (0, valueUtils_1.resolveValue)(initValue);
|
|
59
66
|
const url = endpointFactory.create();
|
|
60
67
|
const entityId = context.extension.issue?.id;
|
|
@@ -75,9 +82,11 @@ const jiraIssuePropsManager = ({ origPropertyKey, initValue }) => {
|
|
|
75
82
|
};
|
|
76
83
|
const update = async ({ endpointFactory, propertyKey, context }, valueUpdate) => {
|
|
77
84
|
const newValueOrRunUpdaterOnOriginal = async (valueUpdate) => {
|
|
85
|
+
// concrete value update, does not require fetching original value
|
|
78
86
|
if (!(valueUpdate instanceof Function)) {
|
|
79
87
|
return valueUpdate;
|
|
80
88
|
}
|
|
89
|
+
// value update via function, fetch original prop first to update based on its value
|
|
81
90
|
const originalProp = await fetchOriginal({ endpointFactory, propertyKey, context });
|
|
82
91
|
if (!originalProp) {
|
|
83
92
|
throw new types_1.EntityPropertyRequestFailedError({
|
|
@@ -1,2 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This function manages the content properties of a Confluence page where the app is installed.
|
|
3
|
+
* @param propertyKey Name (key) of the property
|
|
4
|
+
* @param initValue Default value if it did not exist previously
|
|
5
|
+
* @returns An array with 3 items:
|
|
6
|
+
* 1. Current value of the property.
|
|
7
|
+
* 2. A function to update the property value (with another value or an updater function). If an initial update fails, it automatically tries to update for another <retryCount> times (default 2).
|
|
8
|
+
* 3. A function to delete the property.
|
|
9
|
+
*/
|
|
1
10
|
export declare const useContentProperty: <PropValue>(propertyKey: string, initValue: PropValue) => readonly [PropValue | undefined, (valueUpdate: import("./types/entityProps").ValueUpdate<PropValue>, retryCount?: number) => Promise<void>, () => Promise<void>];
|
|
2
11
|
//# sourceMappingURL=useContentProperty.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useContentProperty.d.ts","sourceRoot":"","sources":["../../src/hooks/useContentProperty.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useContentProperty.d.ts","sourceRoot":"","sources":["../../src/hooks/useContentProperty.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,2BAA4B,MAAM,2LAWhE,CAAC"}
|
|
@@ -4,6 +4,15 @@ exports.useContentProperty = void 0;
|
|
|
4
4
|
const react_1 = require("react");
|
|
5
5
|
const confluenceEntity_1 = require("./confluenceEntity");
|
|
6
6
|
const useEntityProperty_1 = require("./useEntityProperty");
|
|
7
|
+
/**
|
|
8
|
+
* This function manages the content properties of a Confluence page where the app is installed.
|
|
9
|
+
* @param propertyKey Name (key) of the property
|
|
10
|
+
* @param initValue Default value if it did not exist previously
|
|
11
|
+
* @returns An array with 3 items:
|
|
12
|
+
* 1. Current value of the property.
|
|
13
|
+
* 2. A function to update the property value (with another value or an updater function). If an initial update fails, it automatically tries to update for another <retryCount> times (default 2).
|
|
14
|
+
* 3. A function to delete the property.
|
|
15
|
+
*/
|
|
7
16
|
const useContentProperty = (propertyKey, initValue) => {
|
|
8
17
|
const entityManager = (0, react_1.useMemo)(() => (0, confluenceEntity_1.confluenceEntity)({
|
|
9
18
|
entityType: 'Content',
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.useEntityProperty = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* React-based property management hook for Confluence API and entities
|
|
6
|
+
*/
|
|
4
7
|
const react_1 = require("react");
|
|
8
|
+
// outputs a stateful variable and a function to update it
|
|
5
9
|
const useEntityProperty = ({ entityManager, defaultRetryCount = 2 }) => {
|
|
6
10
|
const [propValue, setPropValue] = (0, react_1.useState)();
|
|
7
11
|
(0, react_1.useEffect)(() => {
|
|
@@ -10,6 +14,7 @@ const useEntityProperty = ({ entityManager, defaultRetryCount = 2 }) => {
|
|
|
10
14
|
setPropValue(currentVal);
|
|
11
15
|
};
|
|
12
16
|
getProp().catch(() => {
|
|
17
|
+
// repeat fetch in case previous creation failed due to variable already concurrently created
|
|
13
18
|
getProp().catch((secondErr) => {
|
|
14
19
|
throw secondErr;
|
|
15
20
|
});
|
|
@@ -19,6 +24,7 @@ const useEntityProperty = ({ entityManager, defaultRetryCount = 2 }) => {
|
|
|
19
24
|
let success = false;
|
|
20
25
|
let tryCounts = 0;
|
|
21
26
|
const attempt = async () => setPropValue(await entityManager.update(valueUpdate));
|
|
27
|
+
// initial update attempt + up to <retryCount> retries if update unsuccessful
|
|
22
28
|
while (!success && tryCounts <= retryCount) {
|
|
23
29
|
try {
|
|
24
30
|
tryCounts++;
|
|
@@ -27,7 +33,7 @@ const useEntityProperty = ({ entityManager, defaultRetryCount = 2 }) => {
|
|
|
27
33
|
}
|
|
28
34
|
catch (err) {
|
|
29
35
|
if (tryCounts > retryCount) {
|
|
30
|
-
console.error(err);
|
|
36
|
+
console.error(err); // eslint-disable-line no-console
|
|
31
37
|
}
|
|
32
38
|
}
|
|
33
39
|
}
|
package/out/hooks/useForm.js
CHANGED
|
@@ -6,18 +6,32 @@ const react_1 = require("react");
|
|
|
6
6
|
const react_hook_form_1 = require("react-hook-form");
|
|
7
7
|
const get_1 = tslib_1.__importDefault(require("lodash/get"));
|
|
8
8
|
function useForm(props = {}) {
|
|
9
|
+
// Generate an id to prevent clashes with other forms on the page
|
|
9
10
|
const id = (0, react_1.useId)();
|
|
10
11
|
const getFieldId = (fieldName) => {
|
|
11
12
|
return `form-${id}-${fieldName}`;
|
|
12
13
|
};
|
|
13
|
-
const { register, formState,
|
|
14
|
+
const { register, formState,
|
|
15
|
+
// watch, disabling for the time being as can be expensive for performance
|
|
16
|
+
handleSubmit, setValue, getValues, trigger, clearErrors
|
|
17
|
+
// Only allow for defaultValues in props for the timebeing
|
|
18
|
+
} = (0, react_hook_form_1.useForm)({
|
|
14
19
|
defaultValues: props.defaultValues,
|
|
15
20
|
mode: 'onBlur',
|
|
16
21
|
reValidateMode: 'onChange'
|
|
17
22
|
});
|
|
18
23
|
const defaultValues = props?.defaultValues;
|
|
19
24
|
const forgeFormRegister = (fieldName, options) => {
|
|
25
|
+
/**
|
|
26
|
+
* Removed:
|
|
27
|
+
* - ref cannot be serialised and passed through the run time
|
|
28
|
+
* - removed required to stop the default browser validation pop up
|
|
29
|
+
* - UI Kit 2 components take `isDisabled` instead of `disabled`
|
|
30
|
+
* - `onChange` is modified to handle our controlled components as refs cannot be used
|
|
31
|
+
*/
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
20
33
|
const { onChange, ref, required, disabled, onBlur, ...rest } = register(fieldName, {
|
|
34
|
+
// Only permitting the below as they've been tested and confirmed working
|
|
21
35
|
required: options?.required,
|
|
22
36
|
disabled: options?.disabled,
|
|
23
37
|
maxLength: options?.maxLength,
|
|
@@ -29,6 +43,8 @@ function useForm(props = {}) {
|
|
|
29
43
|
});
|
|
30
44
|
const additionalProps = {};
|
|
31
45
|
if (defaultValues) {
|
|
46
|
+
// only checkbox and toggle have boolean vals.
|
|
47
|
+
// Typically this is handled by the ref obj but we need to manage the default values ourselves here
|
|
32
48
|
if (typeof (0, get_1.default)(defaultValues, fieldName) === 'boolean') {
|
|
33
49
|
additionalProps.defaultChecked = (0, get_1.default)(defaultValues, fieldName);
|
|
34
50
|
}
|
|
@@ -39,11 +55,14 @@ function useForm(props = {}) {
|
|
|
39
55
|
const isError = !!(0, get_1.default)(formState, `errors["${fieldName}"]`);
|
|
40
56
|
const onChangeOptions = {
|
|
41
57
|
shouldDirty: true,
|
|
58
|
+
// revalidate on change if the field has been touched(blurred) or if the form has been submitted previously
|
|
42
59
|
shouldValidate: formState.submitCount > 0 || !!(0, get_1.default)(formState, `touchedFields["${fieldName}"]`)
|
|
43
60
|
};
|
|
44
61
|
return {
|
|
45
62
|
...rest,
|
|
46
63
|
onChange: (event) => {
|
|
64
|
+
// onChange is modified here to handle our controlled components as refs cannot be used
|
|
65
|
+
// handles Checkbox and Toggle
|
|
47
66
|
if (event?.target?.type === 'checkbox') {
|
|
48
67
|
return Promise.resolve(setValue(fieldName, event.target.checked, onChangeOptions));
|
|
49
68
|
}
|
|
@@ -51,9 +70,12 @@ function useForm(props = {}) {
|
|
|
51
70
|
return Promise.resolve(setValue(fieldName, event.target.value, onChangeOptions));
|
|
52
71
|
}
|
|
53
72
|
else {
|
|
73
|
+
// handles onChange arguments where the value is passed instead of an event object
|
|
54
74
|
return Promise.resolve(setValue(fieldName, event, onChangeOptions));
|
|
55
75
|
}
|
|
56
76
|
},
|
|
77
|
+
// The onBlur event from `register` is unintentionally setting the value to `undefined` when the field is blurred.
|
|
78
|
+
// Replacing the onBlur event here to prevent this behaviour.
|
|
57
79
|
onBlur: () => {
|
|
58
80
|
return Promise.resolve(trigger(fieldName));
|
|
59
81
|
},
|
|
@@ -1,2 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This function manages the properties of a Jira issue where the app is installed
|
|
3
|
+
* @param propertyKey Name (key) of the property
|
|
4
|
+
* @param initValue Default value if it did not exist previously
|
|
5
|
+
* @returns An array with 3 items:
|
|
6
|
+
* 1. Current value of the property.
|
|
7
|
+
* 2. A function to update the property value (with another value or an updater function). If a <retryCount> is given and an initial update fails, it automatically tries to update for another <retryCount> times (default 0).
|
|
8
|
+
* 3. A function to delete the property.
|
|
9
|
+
*/
|
|
1
10
|
export declare const useIssueProperty: <PropValue>(propertyKey: string, initValue: PropValue) => readonly [any, (valueUpdate: any, retryCount?: number) => Promise<void>, () => Promise<void>];
|
|
2
11
|
//# sourceMappingURL=useIssueProperty.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useIssueProperty.d.ts","sourceRoot":"","sources":["../../src/hooks/useIssueProperty.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useIssueProperty.d.ts","sourceRoot":"","sources":["../../src/hooks/useIssueProperty.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,2BAA4B,MAAM,wHAW9D,CAAC"}
|
|
@@ -4,12 +4,21 @@ exports.useIssueProperty = void 0;
|
|
|
4
4
|
const react_1 = require("react");
|
|
5
5
|
const jiraEntity_1 = require("./jiraEntity");
|
|
6
6
|
const useEntityProperty_1 = require("./useEntityProperty");
|
|
7
|
+
/**
|
|
8
|
+
* This function manages the properties of a Jira issue where the app is installed
|
|
9
|
+
* @param propertyKey Name (key) of the property
|
|
10
|
+
* @param initValue Default value if it did not exist previously
|
|
11
|
+
* @returns An array with 3 items:
|
|
12
|
+
* 1. Current value of the property.
|
|
13
|
+
* 2. A function to update the property value (with another value or an updater function). If a <retryCount> is given and an initial update fails, it automatically tries to update for another <retryCount> times (default 0).
|
|
14
|
+
* 3. A function to delete the property.
|
|
15
|
+
*/
|
|
7
16
|
const useIssueProperty = (propertyKey, initValue) => {
|
|
8
17
|
const entityManager = (0, react_1.useMemo)(() => (0, jiraEntity_1.jiraIssuePropsManager)({
|
|
9
18
|
entityType: 'Issue',
|
|
10
19
|
origPropertyKey: propertyKey,
|
|
11
20
|
initValue
|
|
12
21
|
}), []);
|
|
13
|
-
return (0, useEntityProperty_1.useEntityProperty)({ entityManager, defaultRetryCount: 0 });
|
|
22
|
+
return (0, useEntityProperty_1.useEntityProperty)({ entityManager, defaultRetryCount: 0 }); // no update retries needed for issue properties
|
|
14
23
|
};
|
|
15
24
|
exports.useIssueProperty = useIssueProperty;
|
|
@@ -1,2 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This function manages the space properties of a Confluence space where the app is installed.
|
|
3
|
+
* @param propertyKey Name (key) of the property
|
|
4
|
+
* @param initValue Default value if it did not exist previously
|
|
5
|
+
* @returns An array with 3 items:
|
|
6
|
+
* 1. Current value of the property.
|
|
7
|
+
* 2. A function to update the property value (with another value or an updater function). If an initial update fails, it automatically tries to update for another <retryCount> times (default 2).
|
|
8
|
+
* 3. A function to delete the property.
|
|
9
|
+
*/
|
|
1
10
|
export declare const useSpaceProperty: <PropValue>(propertyKey: string, initValue: PropValue) => readonly [PropValue | undefined, (valueUpdate: import("./types/entityProps").ValueUpdate<PropValue>, retryCount?: number) => Promise<void>, () => Promise<void>];
|
|
2
11
|
//# sourceMappingURL=useSpaceProperty.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSpaceProperty.d.ts","sourceRoot":"","sources":["../../src/hooks/useSpaceProperty.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useSpaceProperty.d.ts","sourceRoot":"","sources":["../../src/hooks/useSpaceProperty.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,2BAA4B,MAAM,2LAW9D,CAAC"}
|