Skip to content

Commit 907452b

Browse files
committed
feat(loading state): add loading state while generating files
1 parent 8b69678 commit 907452b

5 files changed

Lines changed: 134 additions & 44 deletions

File tree

web/src/features/terraform/Terraform.tsx

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Endpoints } from "../constants";
44
import { routes, terraformBtnMapping } from "../../utils/routing";
55
import { Button } from "@chakra-ui/react";
66
import { Link, Outlet } from "react-router-dom";
7+
import { nameGenerator } from "../../utils/nameGenerator";
78

89
const Terraform = () => {
910
const { endpoint, isSuccess } = useGptStore((s) => s.generatorQuery);
@@ -13,13 +14,29 @@ const Terraform = () => {
1314

1415
const [selected, setSelected] = useState<number>();
1516

16-
const downloadFile = useCallback(() => {
17+
const downloadFile = useCallback(async () => {
1718
if (!isSuccess) return;
18-
if (downloadRef.current) {
19-
downloadRef.current.href = Endpoints.DOWNLOAD_LINK;
20-
downloadRef.current.download = "media";
21-
downloadRef.current.target = "_blank";
22-
downloadRef.current.click();
19+
20+
try {
21+
const response = await fetch(Endpoints.DOWNLOAD_LINK);
22+
if (!response.ok) throw new Error("Failed to fetch file");
23+
24+
const blob = await response.blob();
25+
const url = URL.createObjectURL(blob);
26+
27+
const fileName = nameGenerator(endpoint);
28+
29+
const tempLink = document.createElement("a");
30+
tempLink.href = url;
31+
tempLink.download = fileName;
32+
tempLink.style.display = "none";
33+
document.body.appendChild(tempLink);
34+
35+
tempLink.click();
36+
document.body.removeChild(tempLink);
37+
URL.revokeObjectURL(url);
38+
} catch (error) {
39+
console.error("Error downloading file:", error);
2340
}
2441
}, [isSuccess, endpoint]);
2542

web/src/features/terraform/components/Docker.tsx

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Button, HStack } from "@chakra-ui/react";
1+
import { Button, HStack, Spinner } from "@chakra-ui/react";
22
import { FormProvider } from "react-hook-form";
33
import CheckBox from "../../../components/internal-ui/CheckBox";
44
import {
@@ -15,11 +15,18 @@ import useTerraFormHandler from "../hooks";
1515
import { terraformDockerMapper } from "../../../utils/mapperFunctions";
1616

1717
const Docker = () => {
18-
const { formMethods, handleSubmit, onSubmit, isSuccess, isError } =
19-
useTerraFormHandler<TerraformDockerFormData, ApiRequestTerraformDocker>(
20-
terraformDockerDefaultValues,
21-
Endpoints.POST_IAC_T_DOCKER
22-
);
18+
const {
19+
formMethods,
20+
handleSubmit,
21+
onSubmit,
22+
isSuccess,
23+
isError,
24+
data,
25+
status,
26+
} = useTerraFormHandler<TerraformDockerFormData, ApiRequestTerraformDocker>(
27+
terraformDockerDefaultValues,
28+
Endpoints.POST_IAC_T_DOCKER
29+
);
2330

2431
const handleFormSubmit = handleSubmit((data) =>
2532
onSubmit(terraformDockerMapper(data))
@@ -34,19 +41,33 @@ const Docker = () => {
3441
<p className="font-bold">Docker service: </p>
3542
<CheckBox
3643
fieldName={TerraformDockerFields.DOCKER_IMAGE}
37-
label="Docker image?"
44+
label="Docker image"
3845
/>
3946
<CheckBox
4047
fieldName={TerraformDockerFields.DOCKER_CONTAINER}
41-
label="Docker container?"
48+
label="Docker container"
4249
/>
4350
</HStack>
44-
<Button type="submit" bg="orange.700" w="8rem" h="3rem">
45-
Generate
51+
<Button
52+
type="submit"
53+
disabled={status === "pending" && !data}
54+
bg="orange.700"
55+
w="8rem"
56+
h="3rem"
57+
>
58+
{status === "pending" ? (
59+
<span className="loading loading-ring loading-md "></span>
60+
) : (
61+
<p>Generate</p>
62+
)}
4663
</Button>
4764
</div>
4865
</form>
4966
</FormProvider>
67+
{(formMethods.formState.isLoading ||
68+
formMethods.formState.isSubmitting) && (
69+
<Spinner colorPalette={"cyan"} size="md" />
70+
)}
5071
{isSuccess && <p className="text-green-600">Generated Succesfully</p>}
5172
{isError && <p className="text-red-700">Operation failed</p>}
5273
</div>

web/src/features/terraform/components/EC2.tsx

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Button, HStack } from "@chakra-ui/react";
1+
import { Button, HStack, Spinner } from "@chakra-ui/react";
22
import { FormProvider } from "react-hook-form";
33
import CheckBox from "../../../components/internal-ui/CheckBox";
44
import {
@@ -12,11 +12,18 @@ import { terraformEC2Mapper } from "../../../utils/mapperFunctions";
1212
import useTerraFormHandler from "../hooks";
1313

1414
const EC2 = () => {
15-
const { formMethods, handleSubmit, onSubmit, isSuccess, isError } =
16-
useTerraFormHandler<TerraformEc2FormData, ApiRequestTerraformEc2>(
17-
terraformEc2DefaultValues,
18-
Endpoints.POST_IAC_T_EC2
19-
);
15+
const {
16+
formMethods,
17+
handleSubmit,
18+
onSubmit,
19+
isSuccess,
20+
isError,
21+
status,
22+
data,
23+
} = useTerraFormHandler<TerraformEc2FormData, ApiRequestTerraformEc2>(
24+
terraformEc2DefaultValues,
25+
Endpoints.POST_IAC_T_EC2
26+
);
2027

2128
const handleFormSubmit = handleSubmit((data) =>
2229
onSubmit(terraformEC2Mapper(data))
@@ -31,29 +38,40 @@ const EC2 = () => {
3138
<p className="font-bold">EC2 service: </p>
3239
<CheckBox
3340
fieldName={TerraformEC2Fields.KEY_PAIR}
34-
label="Key pair?"
41+
label="Key pair"
3542
/>
3643
<CheckBox
3744
fieldName={TerraformEC2Fields.SECURITY_GROUP}
38-
label="Security group?"
45+
label="Security group"
3946
/>
4047
<CheckBox
4148
fieldName={TerraformEC2Fields.AWS_INSTANCE}
42-
label="AWS instance?"
49+
label="AWS instance"
4350
/>
4451
<CheckBox
4552
fieldName={TerraformEC2Fields.AMI_FROM_INSTANCE}
46-
label="AMI from instance?"
53+
label="AMI from instance"
4754
/>
4855
</HStack>
49-
<Button type="submit" bg="orange.700" w="8rem" h="3rem">
50-
Generate
56+
<Button
57+
type="submit"
58+
disabled={status === "pending" && !data}
59+
bg="orange.700"
60+
w="8rem"
61+
h="3rem"
62+
>
63+
{status === "pending" ? (
64+
<span className="loading loading-ring loading-md "></span>
65+
) : (
66+
<p>Generate</p>
67+
)}
5168
</Button>
5269
</div>
5370
</form>
5471
</FormProvider>
5572
{isSuccess && <p className="text-green-600">Generated Succesfully</p>}
5673
{isError && <p className="text-red-700">Operation failed</p>}
74+
{(status === "pending" || status === "idle") && <Spinner />}
5775
</div>
5876
);
5977
};

web/src/features/terraform/components/IAM.tsx

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,18 @@ import { terraformIAMMapper } from "../../../utils/mapperFunctions";
1212
import useTerraFormHandler from "../hooks";
1313

1414
const IAM = () => {
15-
const { formMethods, handleSubmit, onSubmit, isSuccess, isError } =
16-
useTerraFormHandler<TerraformIAMFormData, ApiRequestTerraformIam>(
17-
terraformIamDefaultValues,
18-
Endpoints.POST_IAC_T_IAM
19-
);
15+
const {
16+
formMethods,
17+
handleSubmit,
18+
onSubmit,
19+
isSuccess,
20+
isError,
21+
status,
22+
data,
23+
} = useTerraFormHandler<TerraformIAMFormData, ApiRequestTerraformIam>(
24+
terraformIamDefaultValues,
25+
Endpoints.POST_IAC_T_IAM
26+
);
2027

2128
const handleFormSubmit = handleSubmit((data) =>
2229
onSubmit(terraformIAMMapper(data))
@@ -31,15 +38,25 @@ const IAM = () => {
3138
<p className="font-bold">IAM service: </p>
3239
<CheckBox
3340
fieldName={TerraformIAMFields.IAM_USER}
34-
label="IAM user?"
41+
label="IAM user"
3542
/>
3643
<CheckBox
3744
fieldName={TerraformIAMFields.IAM_GROUP}
3845
label="IAM group"
3946
/>
4047
</HStack>
41-
<Button type="submit" bg="orange.700" w="8rem" h="3rem">
42-
Generate
48+
<Button
49+
type="submit"
50+
disabled={status === "pending" && !data}
51+
bg="orange.700"
52+
w="8rem"
53+
h="3rem"
54+
>
55+
{status === "pending" ? (
56+
<span className="loading loading-ring loading-md "></span>
57+
) : (
58+
<p>Generate</p>
59+
)}
4360
</Button>
4461
</div>
4562
</form>

web/src/features/terraform/components/S3.tsx

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,18 @@ import { terraformS3Mapper } from "../../../utils/mapperFunctions";
1212
import useTerraFormHandler from "../hooks";
1313

1414
const S3 = () => {
15-
const { formMethods, handleSubmit, onSubmit, isSuccess, isError } =
16-
useTerraFormHandler<TerraformS3FormData, ApiRequestTerraformS3>(
17-
terraformS3DefaultValues,
18-
Endpoints.POST_IAC_T_S3
19-
);
15+
const {
16+
formMethods,
17+
handleSubmit,
18+
onSubmit,
19+
isSuccess,
20+
isError,
21+
status,
22+
data,
23+
} = useTerraFormHandler<TerraformS3FormData, ApiRequestTerraformS3>(
24+
terraformS3DefaultValues,
25+
Endpoints.POST_IAC_T_S3
26+
);
2027

2128
const handleFormSubmit = handleSubmit((data) =>
2229
onSubmit(terraformS3Mapper(data))
@@ -31,15 +38,25 @@ const S3 = () => {
3138
<p className="font-bold">S3 service: </p>
3239
<CheckBox
3340
fieldName={TerraformS3Fields.S3_BUCKET}
34-
label="S3 bucket?"
41+
label="S3 bucket"
3542
/>
3643
<CheckBox
3744
fieldName={TerraformS3Fields.BUCKET_VERSIONING}
3845
label="Bucket versioning"
3946
/>
4047
</HStack>
41-
<Button type="submit" bg="orange.700" w="8rem" h="3rem">
42-
Generate
48+
<Button
49+
type="submit"
50+
disabled={status === "pending" && !data}
51+
bg="orange.700"
52+
w="8rem"
53+
h="3rem"
54+
>
55+
{status === "pending" ? (
56+
<span className="loading loading-ring loading-md "></span>
57+
) : (
58+
<p>Generate</p>
59+
)}
4360
</Button>
4461
</div>
4562
</form>

0 commit comments

Comments
 (0)