useCluster.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. import { useContext } from "react";
  2. import { Contract } from "@porter-dev/api-contracts";
  3. import { useQuery } from "@tanstack/react-query";
  4. import { z } from "zod";
  5. import { SUPPORTED_CLOUD_PROVIDERS } from "lib/clusters/constants";
  6. import {
  7. clusterValidator,
  8. contractValidator,
  9. type APIContract,
  10. type ClientCluster,
  11. } from "lib/clusters/types";
  12. import api from "shared/api";
  13. import { Context } from "shared/Context";
  14. import { valueExists } from "shared/util";
  15. type TUseClusterList = {
  16. clusters: ClientCluster[];
  17. isLoading: boolean;
  18. };
  19. export const useClusterList = (): TUseClusterList => {
  20. const { currentProject } = useContext(Context);
  21. const clusterReq = useQuery(
  22. ["getClusters", currentProject?.id],
  23. async () => {
  24. if (!currentProject?.id || currentProject.id === -1) {
  25. return;
  26. }
  27. const res = await api.getClusters(
  28. "<token>",
  29. {},
  30. { id: currentProject.id }
  31. );
  32. const parsed = await z.array(clusterValidator).parseAsync(res.data);
  33. return parsed
  34. .map((c) => {
  35. const cloudProviderMatch = SUPPORTED_CLOUD_PROVIDERS.find(
  36. (s) => s.name === c.cloud_provider
  37. );
  38. return cloudProviderMatch
  39. ? { ...c, cloud_provider: cloudProviderMatch }
  40. : null;
  41. })
  42. .filter(valueExists);
  43. },
  44. {
  45. enabled: !!currentProject && currentProject.id !== -1,
  46. }
  47. );
  48. return {
  49. clusters: clusterReq.data ?? [],
  50. isLoading: clusterReq.isLoading,
  51. };
  52. };
  53. type TUseCluster = {
  54. cluster: ClientCluster | undefined;
  55. isLoading: boolean;
  56. isError: boolean;
  57. };
  58. export const useCluster = ({
  59. clusterId,
  60. }: {
  61. clusterId: number | undefined;
  62. }): TUseCluster => {
  63. const { currentProject } = useContext(Context);
  64. const clusterReq = useQuery(
  65. ["getCluster", currentProject?.id, clusterId],
  66. async () => {
  67. if (
  68. !currentProject?.id ||
  69. currentProject.id === -1 ||
  70. !clusterId ||
  71. clusterId === -1
  72. ) {
  73. return;
  74. }
  75. const res = await api.getCluster(
  76. "<token>",
  77. {},
  78. { project_id: currentProject.id, cluster_id: clusterId }
  79. );
  80. const parsed = await clusterValidator.parseAsync(res.data);
  81. const cloudProviderMatch = SUPPORTED_CLOUD_PROVIDERS.find(
  82. (s) => s.name === parsed.cloud_provider
  83. );
  84. if (!cloudProviderMatch) {
  85. return;
  86. }
  87. return { ...parsed, cloud_provider: cloudProviderMatch };
  88. },
  89. {
  90. enabled:
  91. !!currentProject &&
  92. currentProject.id !== -1 &&
  93. !!clusterId &&
  94. clusterId !== -1,
  95. }
  96. );
  97. return {
  98. cluster: clusterReq.data,
  99. isLoading: clusterReq.isLoading,
  100. isError: clusterReq.isError,
  101. };
  102. };
  103. export const useLatestClusterContract = ({
  104. clusterId,
  105. }: {
  106. clusterId: number | undefined;
  107. }): {
  108. contractDB: APIContract | undefined;
  109. contractProto: Contract | undefined;
  110. isLoading: boolean;
  111. isError: boolean;
  112. } => {
  113. const { currentProject } = useContext(Context);
  114. const latestClusterContractReq = useQuery(
  115. ["getLatestClusterContract", currentProject?.id, clusterId],
  116. async () => {
  117. if (
  118. !currentProject?.id ||
  119. currentProject.id === -1 ||
  120. !clusterId ||
  121. clusterId === -1
  122. ) {
  123. return;
  124. }
  125. const res = await api.getContracts(
  126. "<token>",
  127. {
  128. latest: true,
  129. },
  130. { project_id: currentProject.id }
  131. );
  132. const data = await z.array(contractValidator).parseAsync(res.data);
  133. const filtered = data.filter(
  134. (contract) => contract.cluster_id === clusterId
  135. );
  136. if (filtered.length === 0) {
  137. return;
  138. }
  139. const match = filtered[0];
  140. return {
  141. contractDB: match,
  142. contractProto: Contract.fromJsonString(atob(match.base64_contract), {
  143. ignoreUnknownFields: true,
  144. }),
  145. };
  146. },
  147. {
  148. refetchInterval: 3000,
  149. enabled:
  150. !!currentProject &&
  151. currentProject.id !== -1 &&
  152. !!clusterId &&
  153. clusterId !== -1,
  154. }
  155. );
  156. return {
  157. contractDB: latestClusterContractReq.data?.contractDB,
  158. contractProto: latestClusterContractReq.data?.contractProto,
  159. isLoading: latestClusterContractReq.isLoading,
  160. isError: latestClusterContractReq.isError,
  161. };
  162. };