@jobber/components-native 0.89.5-JOB-139254-4e3c64d.7 → 0.90.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/dist/package.json +2 -2
- package/dist/src/Form/Form.js +2 -2
- package/dist/src/Form/hooks/useInternalForm.js +2 -2
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types/src/Form/hooks/useInternalForm.d.ts +2 -2
- package/dist/types/src/Form/types.d.ts +1 -1
- package/package.json +2 -2
- package/src/Form/Form.test.tsx +143 -0
- package/src/Form/Form.tsx +2 -2
- package/src/Form/hooks/useInternalForm.ts +3 -3
- package/src/Form/types.ts +1 -1
|
@@ -2,7 +2,7 @@ import type { DeepPartial, FieldValues, UseFormHandleSubmit, UseFormReturn } fro
|
|
|
2
2
|
import type { MutableRefObject, RefObject } from "react";
|
|
3
3
|
import type { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
|
|
4
4
|
import type { InternalFormProps } from "../types";
|
|
5
|
-
type UseInternalFormProps<T extends FieldValues, SubmitResponseType> = Pick<InternalFormProps<T, SubmitResponseType>, "mode" | "reValidateMode" | "initialValues" | "formRef" | "localCacheKey" | "localCacheExclude" | "localCacheId" | "
|
|
5
|
+
type UseInternalFormProps<T extends FieldValues, SubmitResponseType> = Pick<InternalFormProps<T, SubmitResponseType>, "mode" | "reValidateMode" | "initialValues" | "formRef" | "localCacheKey" | "localCacheExclude" | "localCacheId" | "UNSAFE_allowDiscardLocalCacheWhenOffline"> & {
|
|
6
6
|
scrollViewRef?: RefObject<KeyboardAwareScrollView>;
|
|
7
7
|
readonly saveButtonHeight: number;
|
|
8
8
|
readonly messageBannerHeight: number;
|
|
@@ -15,5 +15,5 @@ interface UseInternalForm<T extends FieldValues> {
|
|
|
15
15
|
readonly removeListenerRef: MutableRefObject<() => void>;
|
|
16
16
|
readonly setLocalCache: (data: DeepPartial<T>) => void;
|
|
17
17
|
}
|
|
18
|
-
export declare function useInternalForm<T extends FieldValues, SubmitResponseType>({ mode, reValidateMode, initialValues, formRef, localCacheKey, localCacheId, scrollViewRef, saveButtonHeight, messageBannerHeight,
|
|
18
|
+
export declare function useInternalForm<T extends FieldValues, SubmitResponseType>({ mode, reValidateMode, initialValues, formRef, localCacheKey, localCacheId, scrollViewRef, saveButtonHeight, messageBannerHeight, UNSAFE_allowDiscardLocalCacheWhenOffline, }: UseInternalFormProps<T, SubmitResponseType>): UseInternalForm<T>;
|
|
19
19
|
export {};
|
|
@@ -136,7 +136,7 @@ export interface FormProps<T extends FieldValues, SubmitResponseType> {
|
|
|
136
136
|
* the dirty form even when offline. By default, cache is only removed on back when online.
|
|
137
137
|
* Defaults to false.
|
|
138
138
|
*/
|
|
139
|
-
|
|
139
|
+
UNSAFE_allowDiscardLocalCacheWhenOffline?: boolean;
|
|
140
140
|
/**
|
|
141
141
|
* Secondary Action for ButtonGroup
|
|
142
142
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jobber/components-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.90.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "React Native implementation of Atlantis",
|
|
6
6
|
"repository": {
|
|
@@ -94,5 +94,5 @@
|
|
|
94
94
|
"react-native-safe-area-context": "^5.4.0",
|
|
95
95
|
"react-native-svg": ">=12.0.0"
|
|
96
96
|
},
|
|
97
|
-
"gitHead": "
|
|
97
|
+
"gitHead": "39c1c0fc8175f82c32c7636b972712a710fbf527"
|
|
98
98
|
}
|
package/src/Form/Form.test.tsx
CHANGED
|
@@ -104,6 +104,7 @@ interface FormTestProps {
|
|
|
104
104
|
readonly onBeforeSubmit?: jest.Mock;
|
|
105
105
|
readonly renderFooter?: React.ReactNode;
|
|
106
106
|
readonly saveButtonOffset?: number;
|
|
107
|
+
readonly UNSAFE_allowDiscardLocalCacheWhenOffline?: boolean;
|
|
107
108
|
}
|
|
108
109
|
|
|
109
110
|
function FormTest(props: FormTestProps) {
|
|
@@ -125,6 +126,7 @@ function MockForm({
|
|
|
125
126
|
localCacheId,
|
|
126
127
|
renderFooter,
|
|
127
128
|
saveButtonOffset,
|
|
129
|
+
UNSAFE_allowDiscardLocalCacheWhenOffline = false,
|
|
128
130
|
}: FormTestProps) {
|
|
129
131
|
const formErrors: FormBannerErrors = {};
|
|
130
132
|
|
|
@@ -154,6 +156,9 @@ function MockForm({
|
|
|
154
156
|
onBeforeSubmit={onBeforeSubmit}
|
|
155
157
|
renderFooter={renderFooter}
|
|
156
158
|
saveButtonOffset={saveButtonOffset}
|
|
159
|
+
UNSAFE_allowDiscardLocalCacheWhenOffline={
|
|
160
|
+
UNSAFE_allowDiscardLocalCacheWhenOffline
|
|
161
|
+
}
|
|
157
162
|
>
|
|
158
163
|
<InputText
|
|
159
164
|
name={testInputTextName}
|
|
@@ -561,4 +566,142 @@ describe("Form", () => {
|
|
|
561
566
|
expect(queryByTestId("ATL-FormSafeArea")).toBeNull();
|
|
562
567
|
});
|
|
563
568
|
});
|
|
569
|
+
|
|
570
|
+
describe("Leaving the form", () => {
|
|
571
|
+
let mockUseConfirmBeforeBack: jest.Mock;
|
|
572
|
+
let mockRemoveLocalCache: jest.Mock;
|
|
573
|
+
const atlantisContextSpy = jest.spyOn(
|
|
574
|
+
atlantisContext,
|
|
575
|
+
"useAtlantisContext",
|
|
576
|
+
);
|
|
577
|
+
|
|
578
|
+
beforeEach(() => {
|
|
579
|
+
mockUseConfirmBeforeBack = jest
|
|
580
|
+
.fn()
|
|
581
|
+
.mockReturnValue({ current: jest.fn() });
|
|
582
|
+
mockRemoveLocalCache = jest.fn();
|
|
583
|
+
|
|
584
|
+
jest
|
|
585
|
+
.spyOn(
|
|
586
|
+
require("../Form/context/AtlantisFormContext"),
|
|
587
|
+
"useAtlantisFormContext",
|
|
588
|
+
)
|
|
589
|
+
.mockReturnValue({
|
|
590
|
+
useConfirmBeforeBack: mockUseConfirmBeforeBack,
|
|
591
|
+
useInternalFormLocalCache: () => ({
|
|
592
|
+
setLocalCache: jest.fn(),
|
|
593
|
+
removeLocalCache: mockRemoveLocalCache,
|
|
594
|
+
}),
|
|
595
|
+
edgeToEdgeEnabled: false,
|
|
596
|
+
});
|
|
597
|
+
});
|
|
598
|
+
|
|
599
|
+
afterEach(() => {
|
|
600
|
+
jest.restoreAllMocks();
|
|
601
|
+
});
|
|
602
|
+
|
|
603
|
+
describe("when UNSAFE_allowDiscardLocalCacheWhenOffline is false", () => {
|
|
604
|
+
it("should NOT pass onAcceptEvent when offline", () => {
|
|
605
|
+
atlantisContextSpy.mockReturnValue({
|
|
606
|
+
...atlantisContextDefaultValues,
|
|
607
|
+
isOnline: false,
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
render(
|
|
611
|
+
<FormTest
|
|
612
|
+
onSubmit={onSubmitMock}
|
|
613
|
+
UNSAFE_allowDiscardLocalCacheWhenOffline={false}
|
|
614
|
+
localCacheKey="testCacheKey"
|
|
615
|
+
/>,
|
|
616
|
+
);
|
|
617
|
+
|
|
618
|
+
expect(mockUseConfirmBeforeBack).toHaveBeenCalled();
|
|
619
|
+
const callArgs = mockUseConfirmBeforeBack.mock.calls[0][0];
|
|
620
|
+
expect(callArgs.onAcceptEvent).toBeUndefined();
|
|
621
|
+
expect(callArgs.showLostProgressMessage).toBe(false);
|
|
622
|
+
});
|
|
623
|
+
|
|
624
|
+
it("should pass onAcceptEvent when online", () => {
|
|
625
|
+
atlantisContextSpy.mockReturnValue({
|
|
626
|
+
...atlantisContextDefaultValues,
|
|
627
|
+
isOnline: true,
|
|
628
|
+
});
|
|
629
|
+
|
|
630
|
+
render(
|
|
631
|
+
<FormTest
|
|
632
|
+
onSubmit={onSubmitMock}
|
|
633
|
+
UNSAFE_allowDiscardLocalCacheWhenOffline={false}
|
|
634
|
+
localCacheKey="testCacheKey"
|
|
635
|
+
/>,
|
|
636
|
+
);
|
|
637
|
+
|
|
638
|
+
expect(mockUseConfirmBeforeBack).toHaveBeenCalled();
|
|
639
|
+
const callArgs = mockUseConfirmBeforeBack.mock.calls[0][0];
|
|
640
|
+
expect(callArgs.onAcceptEvent).toBe(mockRemoveLocalCache);
|
|
641
|
+
expect(callArgs.showLostProgressMessage).toBe(true);
|
|
642
|
+
});
|
|
643
|
+
});
|
|
644
|
+
|
|
645
|
+
describe("when UNSAFE_allowDiscardLocalCacheWhenOffline is true", () => {
|
|
646
|
+
it("should pass onAcceptEvent when offline", () => {
|
|
647
|
+
atlantisContextSpy.mockReturnValue({
|
|
648
|
+
...atlantisContextDefaultValues,
|
|
649
|
+
isOnline: false,
|
|
650
|
+
});
|
|
651
|
+
|
|
652
|
+
render(
|
|
653
|
+
<FormTest
|
|
654
|
+
onSubmit={onSubmitMock}
|
|
655
|
+
UNSAFE_allowDiscardLocalCacheWhenOffline={true}
|
|
656
|
+
localCacheKey="testCacheKey"
|
|
657
|
+
/>,
|
|
658
|
+
);
|
|
659
|
+
|
|
660
|
+
expect(mockUseConfirmBeforeBack).toHaveBeenCalled();
|
|
661
|
+
const callArgs = mockUseConfirmBeforeBack.mock.calls[0][0];
|
|
662
|
+
expect(callArgs.onAcceptEvent).toBe(mockRemoveLocalCache);
|
|
663
|
+
expect(callArgs.showLostProgressMessage).toBe(true);
|
|
664
|
+
});
|
|
665
|
+
|
|
666
|
+
it("should pass onAcceptEvent when online", () => {
|
|
667
|
+
atlantisContextSpy.mockReturnValue({
|
|
668
|
+
...atlantisContextDefaultValues,
|
|
669
|
+
isOnline: true,
|
|
670
|
+
});
|
|
671
|
+
|
|
672
|
+
render(
|
|
673
|
+
<FormTest
|
|
674
|
+
onSubmit={onSubmitMock}
|
|
675
|
+
UNSAFE_allowDiscardLocalCacheWhenOffline={true}
|
|
676
|
+
localCacheKey="testCacheKey"
|
|
677
|
+
/>,
|
|
678
|
+
);
|
|
679
|
+
|
|
680
|
+
expect(mockUseConfirmBeforeBack).toHaveBeenCalled();
|
|
681
|
+
const callArgs = mockUseConfirmBeforeBack.mock.calls[0][0];
|
|
682
|
+
expect(callArgs.onAcceptEvent).toBe(mockRemoveLocalCache);
|
|
683
|
+
expect(callArgs.showLostProgressMessage).toBe(true);
|
|
684
|
+
});
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
describe("without localCacheKey", () => {
|
|
688
|
+
it("should always show lost progress message when no cache key is provided", () => {
|
|
689
|
+
atlantisContextSpy.mockReturnValue({
|
|
690
|
+
...atlantisContextDefaultValues,
|
|
691
|
+
isOnline: false,
|
|
692
|
+
});
|
|
693
|
+
|
|
694
|
+
render(
|
|
695
|
+
<FormTest
|
|
696
|
+
onSubmit={onSubmitMock}
|
|
697
|
+
UNSAFE_allowDiscardLocalCacheWhenOffline={false}
|
|
698
|
+
/>,
|
|
699
|
+
);
|
|
700
|
+
|
|
701
|
+
expect(mockUseConfirmBeforeBack).toHaveBeenCalled();
|
|
702
|
+
const callArgs = mockUseConfirmBeforeBack.mock.calls[0][0];
|
|
703
|
+
expect(callArgs.showLostProgressMessage).toBe(true);
|
|
704
|
+
});
|
|
705
|
+
});
|
|
706
|
+
});
|
|
564
707
|
});
|
package/src/Form/Form.tsx
CHANGED
|
@@ -66,7 +66,7 @@ function InternalForm<T extends FieldValues, S>({
|
|
|
66
66
|
saveButtonOffset,
|
|
67
67
|
showStickySaveButton = false,
|
|
68
68
|
renderFooter,
|
|
69
|
-
|
|
69
|
+
UNSAFE_allowDiscardLocalCacheWhenOffline,
|
|
70
70
|
}: InternalFormProps<T, S>) {
|
|
71
71
|
const { scrollViewRef, bottomViewRef, scrollToTop } = useFormViewRefs();
|
|
72
72
|
const [saveButtonHeight, setSaveButtonHeight] = useState(0);
|
|
@@ -88,7 +88,7 @@ function InternalForm<T extends FieldValues, S>({
|
|
|
88
88
|
scrollViewRef,
|
|
89
89
|
saveButtonHeight,
|
|
90
90
|
messageBannerHeight,
|
|
91
|
-
|
|
91
|
+
UNSAFE_allowDiscardLocalCacheWhenOffline,
|
|
92
92
|
});
|
|
93
93
|
const { windowHeight, headerHeight } = useScreenInformation();
|
|
94
94
|
const [keyboardHeight, setKeyboardHeight] = useState(0);
|
|
@@ -20,7 +20,7 @@ type UseInternalFormProps<T extends FieldValues, SubmitResponseType> = Pick<
|
|
|
20
20
|
| "localCacheKey"
|
|
21
21
|
| "localCacheExclude"
|
|
22
22
|
| "localCacheId"
|
|
23
|
-
| "
|
|
23
|
+
| "UNSAFE_allowDiscardLocalCacheWhenOffline"
|
|
24
24
|
> & {
|
|
25
25
|
scrollViewRef?: RefObject<KeyboardAwareScrollView>;
|
|
26
26
|
readonly saveButtonHeight: number;
|
|
@@ -46,7 +46,7 @@ export function useInternalForm<T extends FieldValues, SubmitResponseType>({
|
|
|
46
46
|
scrollViewRef,
|
|
47
47
|
saveButtonHeight,
|
|
48
48
|
messageBannerHeight,
|
|
49
|
-
|
|
49
|
+
UNSAFE_allowDiscardLocalCacheWhenOffline = false,
|
|
50
50
|
}: UseInternalFormProps<T, SubmitResponseType>): UseInternalForm<T> {
|
|
51
51
|
const { useConfirmBeforeBack, useInternalFormLocalCache } =
|
|
52
52
|
useAtlantisFormContext();
|
|
@@ -84,7 +84,7 @@ export function useInternalForm<T extends FieldValues, SubmitResponseType>({
|
|
|
84
84
|
};
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
const shouldRemoveCacheOnBack =
|
|
87
|
+
const shouldRemoveCacheOnBack = UNSAFE_allowDiscardLocalCacheWhenOffline
|
|
88
88
|
? true
|
|
89
89
|
: isOnline;
|
|
90
90
|
|
package/src/Form/types.ts
CHANGED
|
@@ -176,7 +176,7 @@ export interface FormProps<T extends FieldValues, SubmitResponseType> {
|
|
|
176
176
|
* the dirty form even when offline. By default, cache is only removed on back when online.
|
|
177
177
|
* Defaults to false.
|
|
178
178
|
*/
|
|
179
|
-
|
|
179
|
+
UNSAFE_allowDiscardLocalCacheWhenOffline?: boolean;
|
|
180
180
|
|
|
181
181
|
/**
|
|
182
182
|
* Secondary Action for ButtonGroup
|