-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathIframePost.tsx
More file actions
97 lines (87 loc) · 2.84 KB
/
IframePost.tsx
File metadata and controls
97 lines (87 loc) · 2.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import { SaleorThrobber } from "@dashboard/components/Throbber";
import { getAbsoluteApiUrl } from "@dashboard/config";
import { type AppDetailsUrlMountQueryParams } from "@dashboard/extensions/urls";
import { Box, Skeleton } from "@saleor/macaw-ui-next";
import { type CSSProperties, useEffect, useRef } from "react";
const hiddenStyle: CSSProperties = { visibility: "hidden" };
interface IframePostProps {
extensionId: string;
extensionUrl: string;
appId: string;
accessToken: string;
params?: AppDetailsUrlMountQueryParams;
height?: number | string;
loaderType?: "skeleton" | "throbber";
}
/**
* Renders a hidden form which auto-submits on mount with POST so the iframe
* receives credentials in the body instead of the URL.
*/
export const IframePost = ({
extensionId,
extensionUrl,
appId,
accessToken,
params,
height = 200,
loaderType = "skeleton",
}: IframePostProps) => {
const formRef = useRef<HTMLFormElement | null>(null);
const iframeRef = useRef<HTMLIFrameElement | null>(null);
const loadingRef = useRef<HTMLDivElement | null>(null);
useEffect(() => {
if (formRef.current) {
formRef.current.submit();
}
const iframe = iframeRef.current;
const loading = loadingRef.current;
if (!iframe || !loading) {
return;
}
const onload = () => {
loading.style.display = "none";
iframe.style.visibility = "visible";
};
iframe.addEventListener("load", onload);
return () => {
iframe.removeEventListener("load", onload);
};
}, []);
return (
<Box width="100%" __height={height as number | string}>
<form ref={formRef} action={extensionUrl} method="POST" target={`ext-frame-${extensionId}`}>
<input type="hidden" name="saleorApiUrl" value={getAbsoluteApiUrl()} />
<input type="hidden" name="accessToken" value={accessToken} />
<input type="hidden" name="appId" value={appId} />
{params &&
Object.entries(params).map(([key, value]) => (
<input type="hidden" key={key} name={key} value={value} />
))}
</form>
<Box
ref={loadingRef}
width="100%"
__height={height as number | string}
display={loaderType === "throbber" ? "flex" : "block"}
alignItems={loaderType === "throbber" ? "center" : undefined}
justifyContent={loaderType === "throbber" ? "center" : undefined}
>
{loaderType === "throbber" ? (
<SaleorThrobber />
) : (
<Skeleton __height={height as number | string} />
)}
</Box>
<Box
style={hiddenStyle}
ref={iframeRef}
as="iframe"
borderWidth={0}
__height={height as number | string}
sandbox="allow-same-origin allow-forms allow-scripts allow-downloads"
name={`ext-frame-${extensionId}`}
width="100%"
/>
</Box>
);
};