@harperfast/harper 5.1.0-beta.3 → 5.1.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.
Files changed (52) hide show
  1. package/bin/copyDb.ts +16 -3
  2. package/dist/bin/copyDb.js +16 -3
  3. package/dist/bin/copyDb.js.map +1 -1
  4. package/dist/resources/Table.js +43 -4
  5. package/dist/resources/Table.js.map +1 -1
  6. package/dist/resources/databases.js +135 -41
  7. package/dist/resources/databases.js.map +1 -1
  8. package/dist/resources/graphql.js +3 -0
  9. package/dist/resources/graphql.js.map +1 -1
  10. package/dist/resources/replayLogs.d.ts +1 -0
  11. package/dist/resources/replayLogs.js +100 -40
  12. package/dist/resources/replayLogs.js.map +1 -1
  13. package/dist/resources/replayLogsGuards.d.ts +25 -8
  14. package/dist/resources/replayLogsGuards.js +50 -10
  15. package/dist/resources/replayLogsGuards.js.map +1 -1
  16. package/dist/server/nodeName.js +9 -3
  17. package/dist/server/nodeName.js.map +1 -1
  18. package/dist/server/operationsServer.js +20 -0
  19. package/dist/server/operationsServer.js.map +1 -1
  20. package/dist/utility/install/installer.js +12 -6
  21. package/dist/utility/install/installer.js.map +1 -1
  22. package/package.json +3 -3
  23. package/resources/Table.ts +41 -4
  24. package/resources/databases.ts +134 -42
  25. package/resources/graphql.ts +3 -0
  26. package/resources/replayLogs.ts +114 -42
  27. package/resources/replayLogsGuards.ts +58 -9
  28. package/server/nodeName.ts +9 -3
  29. package/server/operationsServer.ts +17 -0
  30. package/studio/web/assets/{Chat-BdFickL8.js → Chat-DMBW4pI2.js} +2 -2
  31. package/studio/web/assets/{Chat-BdFickL8.js.map → Chat-DMBW4pI2.js.map} +1 -1
  32. package/studio/web/assets/{FloatingChat-CaAoco8I.js → FloatingChat-DTmhPsrm.js} +4 -4
  33. package/studio/web/assets/{FloatingChat-CaAoco8I.js.map → FloatingChat-DTmhPsrm.js.map} +1 -1
  34. package/studio/web/assets/{applications-C3y3xwyG.js → applications-CigxJarn.js} +2 -2
  35. package/studio/web/assets/{applications-C3y3xwyG.js.map → applications-CigxJarn.js.map} +1 -1
  36. package/studio/web/assets/{index-Cd3Zh3nK.js → index-oRZw5GW3.js} +6 -6
  37. package/studio/web/assets/index-oRZw5GW3.js.map +1 -0
  38. package/studio/web/assets/{index.lazy-0hLbh5Fo.js → index.lazy-DY3VcR86.js} +4 -4
  39. package/studio/web/assets/{index.lazy-0hLbh5Fo.js.map → index.lazy-DY3VcR86.js.map} +1 -1
  40. package/studio/web/assets/{profile-CwBWGuVt.js → profile-DiV60L50.js} +2 -2
  41. package/studio/web/assets/{profile-CwBWGuVt.js.map → profile-DiV60L50.js.map} +1 -1
  42. package/studio/web/assets/{setComponentFile-Dhrmd8eR.js → setComponentFile-Bz6WI4jy.js} +2 -2
  43. package/studio/web/assets/{setComponentFile-Dhrmd8eR.js.map → setComponentFile-Bz6WI4jy.js.map} +1 -1
  44. package/studio/web/assets/{status-Bykq6QcD.js → status-fW6PBpPM.js} +2 -2
  45. package/studio/web/assets/{status-Bykq6QcD.js.map → status-fW6PBpPM.js.map} +1 -1
  46. package/studio/web/assets/{swagger-ui-react-CF94s29D.js → swagger-ui-react-DRYf7G3J.js} +2 -2
  47. package/studio/web/assets/{swagger-ui-react-CF94s29D.js.map → swagger-ui-react-DRYf7G3J.js.map} +1 -1
  48. package/studio/web/assets/{useEntityRestURL-D7vuaG2W.js → useEntityRestURL-14jWKu9J.js} +2 -2
  49. package/studio/web/assets/{useEntityRestURL-D7vuaG2W.js.map → useEntityRestURL-14jWKu9J.js.map} +1 -1
  50. package/studio/web/index.html +1 -1
  51. package/utility/install/installer.ts +12 -5
  52. package/studio/web/assets/index-Cd3Zh3nK.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"mappings":"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","names":["__iconNode","Table","PropTypes"],"ignoreList":[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,203,204,205,206,208],"sources":["../../src/hooks/useAuth.ts","../../src/components/ui/card.tsx","../../src/lib/types/isLocalUser.ts","../../src/lib/urls/getDefaultSignedInCloudRouteForUser.ts","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/activity.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/arrow-down-to-line.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/arrow-down.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/arrow-left.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/arrow-right.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/arrow-up-down.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/arrow-up-from-line.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/arrow-up.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/bell.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/book-open-text.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/brush-cleaning.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/bug.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/building.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/calendar-clock.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/chart-pie.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/check.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/chevron-down.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/chevron-right.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/chevron-up.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/circle-alert.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/circle-check-big.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/circle.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/clipboard-check.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/clipboard.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/cloud-alert.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/cloud-download.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/cloud-upload.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/columns-3-cog.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/copy.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/credit-card.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/database.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/ellipsis.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/external-link.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/funnel-plus.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/funnel-x.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/funnel.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/gauge.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/git-graph.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/globe.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/grip-vertical.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/handshake.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/house.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/info.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/key-round.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/key.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/list-todo.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/loader-circle.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/log-in.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/log-out.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/mail-warning.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/map-pin.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/menu.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/monitor.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/moon.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/notepad-text.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/package.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/pencil.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/plus.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/receipt-text.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/receipt.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/refresh-cw.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/rotate-ccw.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/save.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/scale.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/search.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/server.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/settings.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/shield-check.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/shield-x.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/sliders-horizontal.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/square-pen.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/sun.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/table.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/terminal.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/ticket.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/trash-2.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/trash.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/triangle-alert.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/user.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/users.mjs","../../node_modules/.pnpm/lucide-react@1.17.0_react@19.2.7/node_modules/lucide-react/dist/esm/icons/x.mjs","../../src/components/ErrorComponent.tsx","../../src/components/NotFoundComponent.tsx","../../src/lib/browserIsTouchBased.ts","../../src/react-query/queryClient.ts","../../src/lib/arrays/excludeFalsy.ts","../../src/integrations/datadog/datadog.ts","../../src/components/StudioLocal.tsx","../../src/router/rootRoute.ts","../../src/components/DiscordLogo.tsx","../../src/components/MainLogo.tsx","../../src/lib/string/safeParse.ts","../../src/lib/storage/getLocalStorage.ts","../../src/lib/storage/setLocalStorage.ts","../../src/hooks/useLocalStorage.ts","../../src/hooks/useSystemTheme.tsx","../../src/lib/storage/localStorageKeys.ts","../../src/hooks/useTheme.tsx","../../src/components/ThemeToggle.tsx","../../src/components/ui/navigation/NavigationMenuViewport.tsx","../../src/components/ui/navigation/NavigationMenu.tsx","../../src/components/ui/navigation/NavigationMenuItem.tsx","../../src/components/ui/navigation/NavigationMenuLink.tsx","../../src/components/ui/navigation/NavigationMenuList.tsx","../../src/components/ui/badgeVariants.tsx","../../src/components/Version.tsx","../../src/config/useInstanceClient.tsx","../../src/lib/storage/clearLocalStorage.ts","../../src/lib/storage/clearSessionStorage.ts","../../src/features/auth/handlers/logoutOnSuccess.ts","../../src/features/auth/hooks/useLogout.ts","../../src/hooks/usePermissions.ts","../../src/components/Navbar.tsx","../../src/features/auth/AuthLayout.tsx","../../src/integrations/reo/reo.ts","../../src/lib/string/parseCompanyFromEmail.ts","../../src/features/auth/CheckOAuth.tsx","../../src/components/ui/tooltip.tsx","../../src/lib/string/capitalizeWords.ts","../../src/components/Breadcrumbs.tsx","../../src/components/ui/form/Form.tsx","../../src/components/ui/form/formFieldContext.tsx","../../src/components/ui/form/formItemContext.tsx","../../src/components/ui/form/useFormField.tsx","../../src/components/ui/form/FormControl.tsx","../../src/components/ui/form/FormField.tsx","../../src/components/ui/form/FormItem.tsx","../../src/components/ui/label.tsx","../../src/components/ui/form/FormLabel.tsx","../../src/components/ui/form/FormMessage.tsx","../../src/components/ui/input.tsx","../../src/config/clusterStatuses.ts","../../src/config/deepLinks.ts","../../src/integrations/api/instance/auth/useInstanceLoginMutation.ts","../../src/features/auth/hooks/useClusterInstanceSignIn.ts","../../src/features/cluster/queries/getClusterInfoQuery.ts","../../src/lib/zod/email.ts","../../src/lib/zod/password.ts","../../src/lib/zod/username.ts","../../src/integrations/api/instance/auth/signInSchema.ts","../../src/integrations/api/instance/status/getInstanceHealth.ts","../../src/lib/urls/detectCrossLocalhostUrls.ts","../../src/features/auth/ClusterInstanceSignIn.tsx","../../src/features/auth/hooks/useForgotPassword.ts","../../src/features/auth/ForgotPassword.tsx","../../src/features/auth/hooks/useResetPassword.ts","../../src/features/auth/ResetPassword.tsx","../../src/features/auth/components/GitHubAuthenticationButton.tsx","../../src/features/auth/components/GoogleAuthenticationButton.tsx","../../src/features/auth/hooks/useCloudSignIn.ts","../../src/features/auth/SignIn.tsx","../../src/lib/string/regex/personNameRegex.ts","../../src/features/auth/hooks/useSignUp.ts","../../src/features/auth/SignUp.tsx","../../src/features/auth/hooks/useResendEmailVerification.ts","../../src/features/auth/hooks/useVerifyEmail.ts","../../src/features/auth/VerifyEmail.tsx","../../src/features/auth/Verifying.tsx","../../src/features/auth/routes.ts","../../src/components/SubNavMenu.tsx","../../src/components/ui/utils/badgeStatus.tsx","../../src/components/ui/dialog.tsx","../../src/components/ConfirmDeletionModal.tsx","../../src/components/ui/badge.tsx","../../src/components/ui/dropdownMenu.tsx","../../src/integrations/api/clusterIsSelfManaged.ts","../../src/features/clusters/components/ClusterCardAction.tsx","../../src/lib/arrays/mapBy.ts","../../src/features/clusters/components/ClusterProgress.tsx","../../src/features/clusters/mutations/terminateCluster.ts","../../src/hooks/useCopyToClipboard.tsx","../../src/features/clusters/components/ClusterCard.tsx","../../src/components/ContactUs.tsx","../../src/components/Loading.tsx","../../src/components/SubNavSimpleLayout.tsx","../../src/features/cluster/queries/getPlanTypesQuery.ts","../../src/features/clusters/queries/getHarperVersionsQuery.ts","../../src/features/clusters/queries/getRegionLocationsQuery.ts","../../src/lib/arrays/sort/byField.ts","../../src/lib/numbers/ipAddressToNumber.ts","../../src/lib/string/isIpAddress.ts","../../src/lib/arrays/sort/byInstanceFqdnThenPort.ts","../../src/lib/groupBy.ts","../../src/lib/keyBy.ts","../../src/lib/groupThenKeyBy.ts","../../src/lib/string/wasAReleasedBeforeB.ts","../../src/components/ProgressBar.tsx","../../src/components/EstimatedProgressBar.tsx","../../src/features/clusters/hooks/useCreateNewCluster.ts","../../src/features/clusters/hooks/useUpdateCluster.ts","../../src/features/organization/queries/getOrganizationQuery.ts","../../src/integrations/api/orgType.ts","../../src/lib/string/collapseKebabsToMaxLength.ts","../../src/lib/string/stringsShareAPrefix.ts","../../src/lib/string/to-kebab-case.ts","../../src/lib/types/isPositive.ts","../../src/features/organization/mutations/payments/attachPaymentMethodToOrganization.ts","../../src/integrations/stripe/useProcessStripePaymentMethod.tsx","../../src/integrations/stripe/useStripeOptions.tsx","../../node_modules/.pnpm/prop-types@15.8.1/node_modules/prop-types/lib/ReactPropTypesSecret.js","../../node_modules/.pnpm/prop-types@15.8.1/node_modules/prop-types/factoryWithThrowingShims.js","../../node_modules/.pnpm/prop-types@15.8.1/node_modules/prop-types/index.js","../../node_modules/.pnpm/@stripe+react-stripe-js@6.6.0_@stripe+stripe-js@9.7.0_react-dom@19.2.7_react@19.2.7__react@19.2.7/node_modules/@stripe/react-stripe-js/dist/react-stripe.esm.mjs","../../src/features/organization/billing/paymentMethod/AddNewPaymentMethodForm.tsx","../../node_modules/.pnpm/@stripe+stripe-js@9.7.0/node_modules/@stripe/stripe-js/dist/index.mjs","../../src/integrations/stripe/addStripeToOrganizationAndGetIntent.ts","../../src/integrations/stripe/getNewStripeIntentForOrganization.ts","../../src/integrations/stripe/useGetStripeClientSecret.ts","../../src/integrations/stripe/StripeContext.tsx","../../src/features/organization/billing/paymentMethod/AddNewPaymentMethod.tsx","../../src/integrations/stripe/paymentMethodStatus.ts","../../src/integrations/stripe/translateStripePaymentMethodStatus.tsx","../../src/lib/formatMonthAndYear.ts","../../src/features/organization/billing/paymentMethod/PaymentMethodsDisplay.tsx","../../src/features/clusters/upsert/ClusterBilling.tsx","../../src/lib/string/regex/hostNameRegex.ts","../../src/lib/types/portNumbers.ts","../../src/features/clusters/upsert/upsertClusterSchema.ts","../../src/features/clusters/upsert/fields/ClusterAbbreviatedName.tsx","../../src/components/TextLoadingSkeleton.tsx","../../src/components/ui/select.tsx","../../src/features/clusters/upsert/fields/ClusterDeploymentDescription.tsx","../../src/features/clusters/upsert/fields/ClusterFQDN.tsx","../../src/features/clusters/upsert/fields/ClusterName.tsx","../../src/features/clusters/upsert/fields/ClusterPerformanceDescription.tsx","../../src/components/ui/form/FormDescription.tsx","../../src/features/clusters/upsert/fields/ClusterSkipGtmWait.tsx","../../src/features/clusters/upsert/fields/ClusterVersion.tsx","../../src/lib/arrays/sort/byNumberPrefix.ts","../../src/lib/units.ts","../../src/lib/humanFileSize.ts","../../src/lib/addCommasToNumbers.ts","../../src/lib/humanNumber.ts","../../src/features/clusters/upsert/lib/calculateUsageScale.ts","../../src/features/clusters/upsert/components/ResourcesPerInstance.tsx","../../src/features/clusters/upsert/components/RegionFormInputs.tsx","../../src/features/clusters/upsert/ClusterRegions.tsx","../../src/features/clusters/upsert/components/InstanceFormInputs.tsx","../../src/features/clusters/upsert/components/ClusterInstances.tsx","../../src/features/clusters/upsert/lib/calculatePremiumOnlyRegions.ts","../../src/features/clusters/upsert/ClusterDetails.tsx","../../src/features/clusters/upsert/lib/calculateInstanceFQDN.ts","../../src/features/clusters/upsert/lib/calculateDefaultDeploymentPerformanceAndRegionPlans.ts","../../src/features/clusters/upsert/lib/pickDefaultDeploymentPerformanceAndRegionPlans.ts","../../src/features/clusters/upsert/PriceDisplay.tsx","../../src/features/clusters/upsert/ClusterForm.tsx","../../src/features/clusters/upsert/isUpsertClusterSchema.ts","../../src/features/clusters/upsert/lib/detectPartialUpgrade.ts","../../src/features/clusters/upsert/index.tsx","../../src/lib/arrays/sort/byClusterStatusThenName.ts","../../src/lib/string/filterByFuzzySearch.ts","../../src/features/clusters/ClustersList.tsx","../../src/lib/urls/currentUrlAfterHash.ts","../../src/lib/urls/currentUrlIncludingHash.ts","../../src/features/organization/billing/confirm/ProcessSetupIntent.tsx","../../src/features/organization/billing/confirm/ConfirmSetupIntent.tsx","../../src/lib/urls/buildAbsoluteLinkToPage.ts","../../src/features/organization/billing/index.tsx","../../src/components/ui/table.tsx","../../src/components/SimpleBrowseDataTable.tsx","../../src/integrations/stripe/translateStripeStatusToVariant.tsx","../../src/lib/toUSD.ts","../../src/lib/translateSecondsToAgo.ts","../../src/features/organization/billing/invoices/constants/tableDefinition.tsx","../../src/hooks/useRefreshClick.ts","../../src/integrations/stripe/useGetStripeInvoices.ts","../../src/features/organization/billing/invoices/Invoices.tsx","../../src/features/organization/billing/routes.ts","../../src/features/organization/queries/getOrganizationRoles.ts","../../src/features/organization/roles/constants/tableDefinition.ts","../../src/features/organization/mutations/addOrganizationRole.ts","../../src/features/organization/mutations/OrganizationRoleFormSchema.ts","../../src/hooks/useMonacoTheme.ts","../../src/lib/monaco/MonacoEditor.tsx","../../src/features/organization/roles/modals/AddOrganizationRoleModal.tsx","../../src/features/organization/mutations/deleteOrganizationRole.ts","../../src/features/organization/mutations/updateOrganizationRole.ts","../../src/features/organization/queries/getOrganizationRoleInfo.ts","../../src/features/organization/roles/modals/ConfirmDeletionContent.tsx","../../src/features/organization/roles/modals/EditOrganizationRoleModal.tsx","../../src/features/organization/roles/index.tsx","../../src/components/ui/switch.tsx","../../src/lib/urls/getOAuthSignInUrl.ts","../../src/features/organization/settings/index.tsx","../../src/features/organization/users/constants/tableDefinition.ts","../../src/features/organization/mutations/addUserToOrganizationRole.ts","../../src/features/organization/mutations/inviteUserToOrganizationRole.ts","../../src/features/organization/users/modals/AddUserModal.tsx","../../src/features/organization/mutations/removeUserFromOrganizationRole.ts","../../src/hooks/useCheckboxCallback.ts","../../src/features/organization/users/components/OrgUserRoleCheckbox.tsx","../../src/features/organization/users/modals/EditUserModal.tsx","../../src/lib/arrays/sort/byEmail.ts","../../src/features/organization/users/index.tsx","../../src/components/ui/skeleton.tsx","../../src/features/organizations/components/OAuthLockedOrgCard.tsx","../../src/features/organization/mutations/AddCouponSchema.ts","../../src/features/organization/mutations/addCouponToOrganization.ts","../../src/features/organization/modals/AddCouponModal.tsx","../../src/features/organizations/components/OrgCard.tsx","../../src/features/organizations/mutations/deleteOrganization.ts","../../src/features/organizations/hooks/useCreateNewOrganization.ts","../../src/features/organizations/mutations/newOrganizationSchema.ts","../../src/features/organizations/components/NewOrgForm.tsx","../../src/features/organizations/NewOrg.tsx","../../src/features/organizations/queries/getAllOrganizations.ts","../../src/hooks/useDebounce.ts","../../src/lib/arrays/shallowCompareObjects.ts","../../src/hooks/useEffectedState.ts","../../src/lib/events/listener.ts","../../src/lib/storage/getSessionStorage.ts","../../src/lib/storage/setSessionStorage.ts","../../src/hooks/useSessionStorage.ts","../../src/features/organizations/index.tsx","../../src/features/layouts/Dashboard.tsx","../../src/lib/urls/buildRedirectInSearch.ts","../../src/router/dashboardRoute.ts","../../src/features/organizations/routes.ts","../../src/features/organization/routes.ts","../../src/features/clusters/routes.ts","../../src/features/cluster/ClusterLayout.tsx","../../src/features/cluster/clusterLayoutRoute.ts","../../src/components/NestedContentWithSubNavMenu.tsx","../../src/lib/string/extractDomainFromTLD.ts","../../src/features/cluster/domains/AssociateDomainWithCluster.tsx","../../src/features/cluster/domains/components/CertificateProgress.tsx","../../src/integrations/api/instance/database/getSearchByValue.ts","../../src/features/cluster/domains/queries/getChallengeCertificates.ts","../../src/features/cluster/domains/VerifyDomainOwnership.tsx","../../src/features/clusters/mutations/setDomainIdsOnCluster.ts","../../src/features/organization/mutations/deleteDomain.ts","../../src/lib/arrays/unique.ts","../../src/features/cluster/domains/constants/tableDefinition.tsx","../../src/features/organization/mutations/addDomainToOrganization.ts","../../src/features/organization/mutations/validateDomainInOrganization.ts","../../src/features/organization/queries/getOrganizationDomains.ts","../../src/features/cluster/domains/Management.tsx","../../src/features/cluster/domains/Page.tsx","../../src/integrations/api/instance/auth/addUserFormSchema.ts","../../src/features/cluster/queries/resetPasswordUpdater.ts","../../src/integrations/api/instance/auth/addUser.ts","../../src/integrations/api/instance/auth/alterUser.ts","../../src/integrations/api/instance/auth/deleteUser.ts","../../src/integrations/api/instance/auth/useInstanceResetPasswordMutation.ts","../../src/features/cluster/FinishSetup.tsx","../../src/components/DataTable.tsx","../../src/features/cluster/EmptyCluster.tsx","../../src/features/cluster/InstanceLogInCell.tsx","../../src/integrations/api/instance/status/getStatus.ts","../../src/integrations/api/instance/status/setStatus.ts","../../src/features/cluster/InstanceStatusCell.tsx","../../src/features/cluster/Instances.tsx","../../src/features/cluster/Scaling.tsx","../../src/features/cluster/StartingUp.tsx","../../src/features/cluster/routes.ts","../../src/features/instance/apis/routes.ts","../../src/features/instance/applications/routes.ts","../../src/integrations/api/instance/certificates/listCertificates.ts","../../src/features/instance/config/certificates/constants/tableDefinition.ts","../../src/components/ui/textarea.tsx","../../src/integrations/api/instance/certificates/addCertificate.ts","../../src/integrations/api/instance/certificates/useAddCertificate.ts","../../src/features/instance/config/certificates/modals/AddCertificateModal.tsx","../../src/integrations/api/instance/certificates/removeCertificate.ts","../../src/integrations/api/instance/certificates/useRemoveCertificate.ts","../../src/features/instance/config/certificates/modals/ViewCertificateModal.tsx","../../src/features/instance/config/certificates/index.tsx","../../src/features/instance/config/domains/index.tsx","../../src/features/instance/config/index.tsx","../../src/lib/axiosRetry.ts","../../src/integrations/api/instance/status/restartInstance.ts","../../src/hooks/useRestartClusterClick.tsx","../../src/hooks/useRestartInstanceClick.ts","../../src/components/RestartButton.tsx","../../src/components/ui/alertVariants.tsx","../../src/components/ui/alert.tsx","../../src/features/cluster/queries/getInstanceInfoQuery.ts","../../src/features/instance/config/overview/components/HarperVersion.tsx","../../src/features/instance/config/overview/components/LastDeployedTimestamp.tsx","../../src/integrations/api/instance/status/setConfiguration.ts","../../src/hooks/useRollingConfigUpdate.tsx","../../src/integrations/api/instance/applications/getComponents.ts","../../src/integrations/api/instance/status/getConfiguration.ts","../../src/integrations/api/instance/status/getRegistrationInfo.ts","../../src/integrations/api/instance/status/getUsageLicenses.ts","../../src/features/instance/config/overview/configRestrictions.ts","../../src/features/instance/config/overview/harper-config/configMonaco.ts","../../src/features/instance/config/overview/index.tsx","../../src/features/instance/config/roles/constants/tableDefinition.ts","../../src/integrations/api/instance/auth/addRole.ts","../../src/integrations/api/instance/auth/addRoleFormSchema.ts","../../src/features/instance/config/roles/modals/AddRoleModal.tsx","../../src/integrations/api/instance/auth/getListRoles.ts","../../src/features/instance/config/roles/defaultCalculator.ts","../../src/integrations/api/instance/auth/alterRole.ts","../../src/integrations/api/instance/auth/deleteRole.ts","../../src/integrations/api/instance/database/getDescribeAll.ts","../../src/features/instance/config/roles/modals/EditRoleModal.tsx","../../src/features/instance/config/roles/index.tsx","../../src/integrations/api/instance/ssh/listSSHKeys.ts","../../src/features/instance/config/sshKeys/constants/tableDefinition.ts","../../src/integrations/api/instance/ssh/getSSHKnownHosts.ts","../../src/integrations/api/instance/ssh/setSSHKnownHosts.ts","../../src/features/instance/config/sshKeys/KnownHosts.tsx","../../src/integrations/api/instance/ssh/addSSHKey.ts","../../src/features/instance/config/sshKeys/modals/AddSSHKeyModal.tsx","../../src/integrations/api/instance/ssh/deleteSSHKey.ts","../../src/integrations/api/instance/ssh/getSSHKey.ts","../../src/integrations/api/instance/ssh/updateSSHKey.ts","../../src/features/instance/config/sshKeys/modals/EditSSHKeyModal.tsx","../../src/features/instance/config/sshKeys/index.tsx","../../src/features/instance/config/users/constants/tableDefinition.ts","../../src/features/instance/config/users/modals/AddUserModal.tsx","../../src/integrations/api/instance/auth/alterUserFormSchema.ts","../../src/features/instance/config/users/components/AlterUserForm.tsx","../../src/integrations/api/instance/auth/deleteUserFormSchema.ts","../../src/features/instance/config/users/components/DeleteUserForm.tsx","../../src/features/instance/config/users/modals/EditUserModal.tsx","../../src/integrations/api/instance/auth/getListUsers.ts","../../src/features/instance/config/users/index.tsx","../../src/features/instance/registrationInfoLoader.ts","../../src/features/instance/config/routes.ts","../../src/lib/urls/buildAbsoluteLinkToDatabasePage.ts","../../src/components/ui/scrollArea.tsx","../../src/integrations/api/instance/database/createTable.ts","../../src/integrations/api/instance/database/schemaRegex.ts","../../src/integrations/api/instance/database/databaseNameSchema.ts","../../src/integrations/api/instance/database/tableNameSchema.ts","../../src/features/instance/databases/modals/CreateNewTableModal.tsx","../../src/features/instance/databases/components/DatabasesSidebar.tsx","../../src/features/instance/databases/functions/formatBrowseDataTableHeader.ts","../../src/integrations/api/instance/database/insertTableRecords.ts","../../src/features/instance/databases/modals/AddTableRowModal.tsx","../../src/integrations/api/instance/database/deleteDatabase.ts","../../src/lib/attemptToRestoreFocus.ts","../../src/lib/events/watcher.ts","../../src/features/instance/databases/modals/DeleteDatabaseModal.tsx","../../src/integrations/api/instance/database/deleteTable.ts","../../src/features/instance/databases/modals/DeleteTableModal.tsx","../../src/features/instance/databases/modals/EditTableRowModal.tsx","../../src/integrations/api/instance/database/addCSVData.ts","../../src/integrations/api/instance/database/addCSVDataFormSchema.ts","../../src/features/instance/databases/modals/ImportCSVModal.tsx","../../src/hooks/useToggler.ts","../../src/integrations/api/instance/database/cleanupOrphanBlobs.ts","../../src/integrations/api/instance/database/deleteTableRecords.ts","../../src/integrations/api/instance/database/getDescribeTable.ts","../../src/lib/boolean/translateKnownBooleanTypedValue.ts","../../src/lib/numbers/isNumber.ts","../../src/lib/numbers/autoCasterIsNumberCheck.ts","../../src/lib/casting/autoCast.ts","../../src/integrations/api/instance/database/getSearchByConditions.ts","../../src/integrations/api/instance/database/getSearchById.ts","../../src/integrations/api/instance/database/updateTableRecords.ts","../../src/lib/onClickStopPropagation.ts","../../src/features/instance/databases/components/ColumnFilters.tsx","../../src/features/instance/databases/components/PickColumnsDropdown.tsx","../../src/components/LoadingSubtle.tsx","../../src/features/instance/databases/components/TableView.tsx","../../src/features/instance/databases/components/DatabaseTableView.tsx","../../src/features/instance/databases/index.tsx","../../src/features/instance/databases/routes.ts","../../src/features/instance/InstanceNavBar.tsx","../../src/features/instance/InstanceLayout.tsx","../../src/features/instance/instanceLayoutRoute.ts","../../src/components/ui/toggleVariants.tsx","../../src/components/ui/toggle.tsx","../../src/components/ui/utils/badgeLogLevel.tsx","../../src/components/ui/utils/badgeNode.tsx","../../src/features/instance/log/LogsDataTable.tsx","../../src/features/instance/log/modals/ViewLogModal.tsx","../../src/integrations/api/instance/status/getReadLog.ts","../../src/integrations/api/instance/status/logFiltersFormSchema.ts","../../src/features/instance/log/components/LogsFiltersForm.tsx","../../src/features/instance/log/index.tsx","../../src/features/instance/log/routes.ts","../../src/features/instance/status/routes.ts","../../src/features/instance/routes.ts","../../src/features/profile/routes.ts","../../src/router/rootRouteTree.ts","../../src/router/useNewRouter.ts","../../src/AppRouted.tsx","../../src/components/ui/sonner.tsx","../../src/integrations/google/gtm.ts","../../src/App.tsx","../../src/main.tsx"],"sourcesContent":["import { isLocalStudio } from '@/config/constants';\nimport {\n\tAuthenticatedCloudConnection,\n\tAuthenticatedConnection,\n\tAuthenticatedInstanceConnection,\n\tauthStore,\n\tEntityIds,\n\tOverallAppSignIn,\n} from '@/features/auth/store/authStore';\nimport { User } from '@/integrations/api/api.patch';\nimport { useParams } from '@tanstack/react-router';\nimport { useEffect, useState } from 'react';\n\nexport function useRootAuthenticationContext(): Record<EntityIds, AuthenticatedConnection> {\n\tconst [connections, setConnections] = useState(authStore.getAllConnections());\n\tuseEffect(() =>\n\t\tauthStore.listenToAllEntities((connection, id) => {\n\t\t\tsetConnections({ ...connections, [id]: connection });\n\t\t}), [connections]);\n\treturn connections;\n}\n\nexport function useOverallAuth(): AuthenticatedConnection {\n\tconst id = authStore.calculateIdFromEntity(OverallAppSignIn);\n\tconst [connection, setConnection] = useState<AuthenticatedConnection>(authStore.getConnectionById(OverallAppSignIn));\n\tuseEffect(() => authStore.listenToEntity(id, setConnection), [id]);\n\treturn connection;\n}\n\nexport function useCloudAuth(): AuthenticatedCloudConnection {\n\treturn useOverallAuth() as AuthenticatedCloudConnection;\n}\n\nexport function useAdminMode(): boolean {\n\tconst { user } = useCloudAuth();\n\treturn isAdminMode(user);\n}\n\nexport function isAdminMode(user: User | null): boolean {\n\treturn user?.fabricRole === 'fabric_admin' || user?.fabricRole === 'super_user';\n}\n\nexport function useInstanceAuth(entityId?: EntityIds): AuthenticatedInstanceConnection {\n\tconst key = isLocalStudio ? OverallAppSignIn : entityId;\n\tconst { clusterId, instanceId }: { instanceId?: string; clusterId: string } = useParams({ strict: false });\n\tconst [connection, setConnection] = useState<AuthenticatedConnection>(\n\t\tauthStore.getConnectionById(key ?? instanceId ?? clusterId),\n\t);\n\tuseEffect(() => authStore.listenToEntity(key, setConnection), [key]);\n\treturn connection as AuthenticatedInstanceConnection;\n}\n","import * as React from 'react';\n\nimport { cn } from '@/lib/cn';\n\nfunction Card({ className, ...props }: React.ComponentProps<'div'>) {\n\treturn (\n\t\t<div\n\t\t\tdata-slot=\"card\"\n\t\t\tclassName={cn(\n\t\t\t\t'bg-card text-card-foreground flex flex-col gap-4 rounded-2xl py-5 shadow-deep ring-1 ring-black/5 dark:ring-white/5',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<'div'>) {\n\treturn <div data-slot=\"card-header\" className={cn('flex flex-col gap-1.5 px-6', className)} {...props} />;\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<'div'>) {\n\treturn <div data-slot=\"card-title\" className={cn('leading-none text-lg', className)} {...props} />;\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<'div'>) {\n\treturn <div data-slot=\"card-description\" className={cn('text-muted-foreground text-xs', className)} {...props} />;\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<'div'>) {\n\treturn <div data-slot=\"card-content\" className={cn('px-6', className)} {...props} />;\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<'div'>) {\n\treturn <div data-slot=\"card-footer\" className={cn('flex items-center px-6', className)} {...props} />;\n}\n\nexport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle };\n","import { LocalUser, User } from '@/integrations/api/api.patch';\n\nexport function isLocalUser(user: User | LocalUser | null): user is LocalUser {\n\treturn user !== null && !!(user as LocalUser).username;\n}\n","import { LocalUser, User } from '@/integrations/api/api.patch';\nimport { isLocalUser } from '@/lib/types/isLocalUser';\n\nexport function getDefaultSignedInCloudRouteForUser(user: User | LocalUser | null): string {\n\tif (user && !isLocalUser(user)) {\n\t\tconst orgIds = Object.keys(user.roles);\n\t\tif (orgIds.length === 1) {\n\t\t\treturn `/${orgIds[0]}`;\n\t\t}\n\t}\n\treturn '/';\n}\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2\",\n key: \"169zse\"\n }\n ]\n];\nconst Activity = createLucideIcon(\"activity\", __iconNode);\n\nexport { __iconNode, Activity as default };\n//# sourceMappingURL=activity.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 17V3\", key: \"1cwfxf\" }],\n [\"path\", { d: \"m6 11 6 6 6-6\", key: \"12ii2o\" }],\n [\"path\", { d: \"M19 21H5\", key: \"150jfl\" }]\n];\nconst ArrowDownToLine = createLucideIcon(\"arrow-down-to-line\", __iconNode);\n\nexport { __iconNode, ArrowDownToLine as default };\n//# sourceMappingURL=arrow-down-to-line.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 5v14\", key: \"s699le\" }],\n [\"path\", { d: \"m19 12-7 7-7-7\", key: \"1idqje\" }]\n];\nconst ArrowDown = createLucideIcon(\"arrow-down\", __iconNode);\n\nexport { __iconNode, ArrowDown as default };\n//# sourceMappingURL=arrow-down.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"m12 19-7-7 7-7\", key: \"1l729n\" }],\n [\"path\", { d: \"M19 12H5\", key: \"x3x0zl\" }]\n];\nconst ArrowLeft = createLucideIcon(\"arrow-left\", __iconNode);\n\nexport { __iconNode, ArrowLeft as default };\n//# sourceMappingURL=arrow-left.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M5 12h14\", key: \"1ays0h\" }],\n [\"path\", { d: \"m12 5 7 7-7 7\", key: \"xquz4c\" }]\n];\nconst ArrowRight = createLucideIcon(\"arrow-right\", __iconNode);\n\nexport { __iconNode, ArrowRight as default };\n//# sourceMappingURL=arrow-right.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"m21 16-4 4-4-4\", key: \"f6ql7i\" }],\n [\"path\", { d: \"M17 20V4\", key: \"1ejh1v\" }],\n [\"path\", { d: \"m3 8 4-4 4 4\", key: \"11wl7u\" }],\n [\"path\", { d: \"M7 4v16\", key: \"1glfcx\" }]\n];\nconst ArrowUpDown = createLucideIcon(\"arrow-up-down\", __iconNode);\n\nexport { __iconNode, ArrowUpDown as default };\n//# sourceMappingURL=arrow-up-down.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"m18 9-6-6-6 6\", key: \"kcunyi\" }],\n [\"path\", { d: \"M12 3v14\", key: \"7cf3v8\" }],\n [\"path\", { d: \"M5 21h14\", key: \"11awu3\" }]\n];\nconst ArrowUpFromLine = createLucideIcon(\"arrow-up-from-line\", __iconNode);\n\nexport { __iconNode, ArrowUpFromLine as default };\n//# sourceMappingURL=arrow-up-from-line.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"m5 12 7-7 7 7\", key: \"hav0vg\" }],\n [\"path\", { d: \"M12 19V5\", key: \"x0mq9r\" }]\n];\nconst ArrowUp = createLucideIcon(\"arrow-up\", __iconNode);\n\nexport { __iconNode, ArrowUp as default };\n//# sourceMappingURL=arrow-up.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M10.268 21a2 2 0 0 0 3.464 0\", key: \"vwvbt9\" }],\n [\n \"path\",\n {\n d: \"M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326\",\n key: \"11g9vi\"\n }\n ]\n];\nconst Bell = createLucideIcon(\"bell\", __iconNode);\n\nexport { __iconNode, Bell as default };\n//# sourceMappingURL=bell.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 7v14\", key: \"1akyts\" }],\n [\"path\", { d: \"M16 12h2\", key: \"7q9ll5\" }],\n [\"path\", { d: \"M16 8h2\", key: \"msurwy\" }],\n [\n \"path\",\n {\n d: \"M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z\",\n key: \"ruj8y\"\n }\n ],\n [\"path\", { d: \"M6 12h2\", key: \"32wvfc\" }],\n [\"path\", { d: \"M6 8h2\", key: \"30oboj\" }]\n];\nconst BookOpenText = createLucideIcon(\"book-open-text\", __iconNode);\n\nexport { __iconNode, BookOpenText as default };\n//# sourceMappingURL=book-open-text.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"m16 22-1-4\", key: \"1ow2iv\" }],\n [\n \"path\",\n {\n d: \"M19 14a1 1 0 0 0 1-1v-1a2 2 0 0 0-2-2h-3a1 1 0 0 1-1-1V4a2 2 0 0 0-4 0v5a1 1 0 0 1-1 1H6a2 2 0 0 0-2 2v1a1 1 0 0 0 1 1\",\n key: \"11gii7\"\n }\n ],\n [\"path\", { d: \"M19 14H5l-1.973 6.767A1 1 0 0 0 4 22h16a1 1 0 0 0 .973-1.233z\", key: \"bju7h4\" }],\n [\"path\", { d: \"m8 22 1-4\", key: \"s3unb\" }]\n];\nconst BrushCleaning = createLucideIcon(\"brush-cleaning\", __iconNode);\n\nexport { __iconNode, BrushCleaning as default };\n//# sourceMappingURL=brush-cleaning.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 20v-9\", key: \"1qisl0\" }],\n [\"path\", { d: \"M14 7a4 4 0 0 1 4 4v3a6 6 0 0 1-12 0v-3a4 4 0 0 1 4-4z\", key: \"uouzyp\" }],\n [\"path\", { d: \"M14.12 3.88 16 2\", key: \"qol33r\" }],\n [\"path\", { d: \"M21 21a4 4 0 0 0-3.81-4\", key: \"1b0z45\" }],\n [\"path\", { d: \"M21 5a4 4 0 0 1-3.55 3.97\", key: \"5cxbf6\" }],\n [\"path\", { d: \"M22 13h-4\", key: \"1jl80f\" }],\n [\"path\", { d: \"M3 21a4 4 0 0 1 3.81-4\", key: \"1fjd4g\" }],\n [\"path\", { d: \"M3 5a4 4 0 0 0 3.55 3.97\", key: \"1d7oge\" }],\n [\"path\", { d: \"M6 13H2\", key: \"82j7cp\" }],\n [\"path\", { d: \"m8 2 1.88 1.88\", key: \"fmnt4t\" }],\n [\"path\", { d: \"M9 7.13V6a3 3 0 1 1 6 0v1.13\", key: \"1vgav8\" }]\n];\nconst Bug = createLucideIcon(\"bug\", __iconNode);\n\nexport { __iconNode, Bug as default };\n//# sourceMappingURL=bug.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 10h.01\", key: \"1nrarc\" }],\n [\"path\", { d: \"M12 14h.01\", key: \"1etili\" }],\n [\"path\", { d: \"M12 6h.01\", key: \"1vi96p\" }],\n [\"path\", { d: \"M16 10h.01\", key: \"1m94wz\" }],\n [\"path\", { d: \"M16 14h.01\", key: \"1gbofw\" }],\n [\"path\", { d: \"M16 6h.01\", key: \"1x0f13\" }],\n [\"path\", { d: \"M8 10h.01\", key: \"19clt8\" }],\n [\"path\", { d: \"M8 14h.01\", key: \"6423bh\" }],\n [\"path\", { d: \"M8 6h.01\", key: \"1dz90k\" }],\n [\"path\", { d: \"M9 22v-3a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v3\", key: \"cabbwy\" }],\n [\"rect\", { x: \"4\", y: \"2\", width: \"16\", height: \"20\", rx: \"2\", key: \"1uxh74\" }]\n];\nconst Building = createLucideIcon(\"building\", __iconNode);\n\nexport { __iconNode, Building as default };\n//# sourceMappingURL=building.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M16 14v2.2l1.6 1\", key: \"fo4ql5\" }],\n [\"path\", { d: \"M16 2v4\", key: \"4m81vk\" }],\n [\"path\", { d: \"M21 7.5V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h3.5\", key: \"1osxxc\" }],\n [\"path\", { d: \"M3 10h5\", key: \"r794hk\" }],\n [\"path\", { d: \"M8 2v4\", key: \"1cmpym\" }],\n [\"circle\", { cx: \"16\", cy: \"16\", r: \"6\", key: \"qoo3c4\" }]\n];\nconst CalendarClock = createLucideIcon(\"calendar-clock\", __iconNode);\n\nexport { __iconNode, CalendarClock as default };\n//# sourceMappingURL=calendar-clock.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M21 12c.552 0 1.005-.449.95-.998a10 10 0 0 0-8.953-8.951c-.55-.055-.998.398-.998.95v8a1 1 0 0 0 1 1z\",\n key: \"pzmjnu\"\n }\n ],\n [\"path\", { d: \"M21.21 15.89A10 10 0 1 1 8 2.83\", key: \"k2fpak\" }]\n];\nconst ChartPie = createLucideIcon(\"chart-pie\", __iconNode);\n\nexport { __iconNode, ChartPie as default };\n//# sourceMappingURL=chart-pie.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [[\"path\", { d: \"M20 6 9 17l-5-5\", key: \"1gmf2c\" }]];\nconst Check = createLucideIcon(\"check\", __iconNode);\n\nexport { __iconNode, Check as default };\n//# sourceMappingURL=check.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [[\"path\", { d: \"m6 9 6 6 6-6\", key: \"qrunsl\" }]];\nconst ChevronDown = createLucideIcon(\"chevron-down\", __iconNode);\n\nexport { __iconNode, ChevronDown as default };\n//# sourceMappingURL=chevron-down.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [[\"path\", { d: \"m9 18 6-6-6-6\", key: \"mthhwq\" }]];\nconst ChevronRight = createLucideIcon(\"chevron-right\", __iconNode);\n\nexport { __iconNode, ChevronRight as default };\n//# sourceMappingURL=chevron-right.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [[\"path\", { d: \"m18 15-6-6-6 6\", key: \"153udz\" }]];\nconst ChevronUp = createLucideIcon(\"chevron-up\", __iconNode);\n\nexport { __iconNode, ChevronUp as default };\n//# sourceMappingURL=chevron-up.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"line\", { x1: \"12\", x2: \"12\", y1: \"8\", y2: \"12\", key: \"1pkeuh\" }],\n [\"line\", { x1: \"12\", x2: \"12.01\", y1: \"16\", y2: \"16\", key: \"4dfq90\" }]\n];\nconst CircleAlert = createLucideIcon(\"circle-alert\", __iconNode);\n\nexport { __iconNode, CircleAlert as default };\n//# sourceMappingURL=circle-alert.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M21.801 10A10 10 0 1 1 17 3.335\", key: \"yps3ct\" }],\n [\"path\", { d: \"m9 11 3 3L22 4\", key: \"1pflzl\" }]\n];\nconst CircleCheckBig = createLucideIcon(\"circle-check-big\", __iconNode);\n\nexport { __iconNode, CircleCheckBig as default };\n//# sourceMappingURL=circle-check-big.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [[\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }]];\nconst Circle = createLucideIcon(\"circle\", __iconNode);\n\nexport { __iconNode, Circle as default };\n//# sourceMappingURL=circle.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"rect\", { width: \"8\", height: \"4\", x: \"8\", y: \"2\", rx: \"1\", ry: \"1\", key: \"tgr4d6\" }],\n [\n \"path\",\n {\n d: \"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2\",\n key: \"116196\"\n }\n ],\n [\"path\", { d: \"m9 14 2 2 4-4\", key: \"df797q\" }]\n];\nconst ClipboardCheck = createLucideIcon(\"clipboard-check\", __iconNode);\n\nexport { __iconNode, ClipboardCheck as default };\n//# sourceMappingURL=clipboard-check.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"rect\", { width: \"8\", height: \"4\", x: \"8\", y: \"2\", rx: \"1\", ry: \"1\", key: \"tgr4d6\" }],\n [\n \"path\",\n {\n d: \"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2\",\n key: \"116196\"\n }\n ]\n];\nconst Clipboard = createLucideIcon(\"clipboard\", __iconNode);\n\nexport { __iconNode, Clipboard as default };\n//# sourceMappingURL=clipboard.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 12v4\", key: \"tww15h\" }],\n [\"path\", { d: \"M12 20h.01\", key: \"zekei9\" }],\n [\"path\", { d: \"M8.128 16.949A7 7 0 1 1 15.71 8h1.79a1 1 0 0 1 0 9h-1.642\", key: \"1namsd\" }]\n];\nconst CloudAlert = createLucideIcon(\"cloud-alert\", __iconNode);\n\nexport { __iconNode, CloudAlert as default };\n//# sourceMappingURL=cloud-alert.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 13v8l-4-4\", key: \"1f5nwf\" }],\n [\"path\", { d: \"m12 21 4-4\", key: \"1lfcce\" }],\n [\"path\", { d: \"M4.393 15.269A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.436 8.284\", key: \"ui1hmy\" }]\n];\nconst CloudDownload = createLucideIcon(\"cloud-download\", __iconNode);\n\nexport { __iconNode, CloudDownload as default };\n//# sourceMappingURL=cloud-download.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 13v8\", key: \"1l5pq0\" }],\n [\"path\", { d: \"M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242\", key: \"1pljnt\" }],\n [\"path\", { d: \"m8 17 4-4 4 4\", key: \"1quai1\" }]\n];\nconst CloudUpload = createLucideIcon(\"cloud-upload\", __iconNode);\n\nexport { __iconNode, CloudUpload as default };\n//# sourceMappingURL=cloud-upload.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M10.5 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v5.5\", key: \"1g2yzs\" }],\n [\"path\", { d: \"m14.3 19.6 1-.4\", key: \"11sv9r\" }],\n [\"path\", { d: \"M15 3v7.5\", key: \"7lm50a\" }],\n [\"path\", { d: \"m15.2 16.9-.9-.3\", key: \"1t7mvx\" }],\n [\"path\", { d: \"m16.6 21.7.3-.9\", key: \"1j67ps\" }],\n [\"path\", { d: \"m16.8 15.3-.4-1\", key: \"1ei7r6\" }],\n [\"path\", { d: \"m19.1 15.2.3-.9\", key: \"18r7jp\" }],\n [\"path\", { d: \"m19.6 21.7-.4-1\", key: \"z2vh2\" }],\n [\"path\", { d: \"m20.7 16.8 1-.4\", key: \"19m87a\" }],\n [\"path\", { d: \"m21.7 19.4-.9-.3\", key: \"1qgwi9\" }],\n [\"path\", { d: \"M9 3v18\", key: \"fh3hqa\" }],\n [\"circle\", { cx: \"18\", cy: \"18\", r: \"3\", key: \"1xkwt0\" }]\n];\nconst Columns3Cog = createLucideIcon(\"columns-3-cog\", __iconNode);\n\nexport { __iconNode, Columns3Cog as default };\n//# sourceMappingURL=columns-3-cog.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"rect\", { width: \"14\", height: \"14\", x: \"8\", y: \"8\", rx: \"2\", ry: \"2\", key: \"17jyea\" }],\n [\"path\", { d: \"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\", key: \"zix9uf\" }]\n];\nconst Copy = createLucideIcon(\"copy\", __iconNode);\n\nexport { __iconNode, Copy as default };\n//# sourceMappingURL=copy.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"rect\", { width: \"20\", height: \"14\", x: \"2\", y: \"5\", rx: \"2\", key: \"ynyp8z\" }],\n [\"line\", { x1: \"2\", x2: \"22\", y1: \"10\", y2: \"10\", key: \"1b3vmo\" }]\n];\nconst CreditCard = createLucideIcon(\"credit-card\", __iconNode);\n\nexport { __iconNode, CreditCard as default };\n//# sourceMappingURL=credit-card.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"ellipse\", { cx: \"12\", cy: \"5\", rx: \"9\", ry: \"3\", key: \"msslwz\" }],\n [\"path\", { d: \"M3 5V19A9 3 0 0 0 21 19V5\", key: \"1wlel7\" }],\n [\"path\", { d: \"M3 12A9 3 0 0 0 21 12\", key: \"mv7ke4\" }]\n];\nconst Database = createLucideIcon(\"database\", __iconNode);\n\nexport { __iconNode, Database as default };\n//# sourceMappingURL=database.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"1\", key: \"41hilf\" }],\n [\"circle\", { cx: \"19\", cy: \"12\", r: \"1\", key: \"1wjl8i\" }],\n [\"circle\", { cx: \"5\", cy: \"12\", r: \"1\", key: \"1pcz8c\" }]\n];\nconst Ellipsis = createLucideIcon(\"ellipsis\", __iconNode);\n\nexport { __iconNode, Ellipsis as default };\n//# sourceMappingURL=ellipsis.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M15 3h6v6\", key: \"1q9fwt\" }],\n [\"path\", { d: \"M10 14 21 3\", key: \"gplh6r\" }],\n [\"path\", { d: \"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\", key: \"a6xqqp\" }]\n];\nconst ExternalLink = createLucideIcon(\"external-link\", __iconNode);\n\nexport { __iconNode, ExternalLink as default };\n//# sourceMappingURL=external-link.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M13.354 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14v6a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341l1.218-1.348\",\n key: \"8mvsmf\"\n }\n ],\n [\"path\", { d: \"M16 6h6\", key: \"1dogtp\" }],\n [\"path\", { d: \"M19 3v6\", key: \"1ytpjt\" }]\n];\nconst FunnelPlus = createLucideIcon(\"funnel-plus\", __iconNode);\n\nexport { __iconNode, FunnelPlus as default };\n//# sourceMappingURL=funnel-plus.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M12.531 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14v6a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341l.427-.473\",\n key: \"ol2ft2\"\n }\n ],\n [\"path\", { d: \"m16.5 3.5 5 5\", key: \"15e6fa\" }],\n [\"path\", { d: \"m21.5 3.5-5 5\", key: \"m0lwru\" }]\n];\nconst FunnelX = createLucideIcon(\"funnel-x\", __iconNode);\n\nexport { __iconNode, FunnelX as default };\n//# sourceMappingURL=funnel-x.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z\",\n key: \"sc7q7i\"\n }\n ]\n];\nconst Funnel = createLucideIcon(\"funnel\", __iconNode);\n\nexport { __iconNode, Funnel as default };\n//# sourceMappingURL=funnel.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"m12 14 4-4\", key: \"9kzdfg\" }],\n [\"path\", { d: \"M3.34 19a10 10 0 1 1 17.32 0\", key: \"19p75a\" }]\n];\nconst Gauge = createLucideIcon(\"gauge\", __iconNode);\n\nexport { __iconNode, Gauge as default };\n//# sourceMappingURL=gauge.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"circle\", { cx: \"5\", cy: \"6\", r: \"3\", key: \"1qnov2\" }],\n [\"path\", { d: \"M5 9v6\", key: \"158jrl\" }],\n [\"circle\", { cx: \"5\", cy: \"18\", r: \"3\", key: \"104gr9\" }],\n [\"path\", { d: \"M12 3v18\", key: \"108xh3\" }],\n [\"circle\", { cx: \"19\", cy: \"6\", r: \"3\", key: \"108a5v\" }],\n [\"path\", { d: \"M16 15.7A9 9 0 0 0 19 9\", key: \"1e3vqb\" }]\n];\nconst GitGraph = createLucideIcon(\"git-graph\", __iconNode);\n\nexport { __iconNode, GitGraph as default };\n//# sourceMappingURL=git-graph.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"path\", { d: \"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20\", key: \"13o1zl\" }],\n [\"path\", { d: \"M2 12h20\", key: \"9i4pu4\" }]\n];\nconst Globe = createLucideIcon(\"globe\", __iconNode);\n\nexport { __iconNode, Globe as default };\n//# sourceMappingURL=globe.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"circle\", { cx: \"9\", cy: \"12\", r: \"1\", key: \"1vctgf\" }],\n [\"circle\", { cx: \"9\", cy: \"5\", r: \"1\", key: \"hp0tcf\" }],\n [\"circle\", { cx: \"9\", cy: \"19\", r: \"1\", key: \"fkjjf6\" }],\n [\"circle\", { cx: \"15\", cy: \"12\", r: \"1\", key: \"1tmaij\" }],\n [\"circle\", { cx: \"15\", cy: \"5\", r: \"1\", key: \"19l28e\" }],\n [\"circle\", { cx: \"15\", cy: \"19\", r: \"1\", key: \"f4zoj3\" }]\n];\nconst GripVertical = createLucideIcon(\"grip-vertical\", __iconNode);\n\nexport { __iconNode, GripVertical as default };\n//# sourceMappingURL=grip-vertical.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"m11 17 2 2a1 1 0 1 0 3-3\", key: \"efffak\" }],\n [\n \"path\",\n {\n d: \"m14 14 2.5 2.5a1 1 0 1 0 3-3l-3.88-3.88a3 3 0 0 0-4.24 0l-.88.88a1 1 0 1 1-3-3l2.81-2.81a5.79 5.79 0 0 1 7.06-.87l.47.28a2 2 0 0 0 1.42.25L21 4\",\n key: \"9pr0kb\"\n }\n ],\n [\"path\", { d: \"m21 3 1 11h-2\", key: \"1tisrp\" }],\n [\"path\", { d: \"M3 3 2 14l6.5 6.5a1 1 0 1 0 3-3\", key: \"1uvwmv\" }],\n [\"path\", { d: \"M3 4h8\", key: \"1ep09j\" }]\n];\nconst Handshake = createLucideIcon(\"handshake\", __iconNode);\n\nexport { __iconNode, Handshake as default };\n//# sourceMappingURL=handshake.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8\", key: \"5wwlr5\" }],\n [\n \"path\",\n {\n d: \"M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\",\n key: \"r6nss1\"\n }\n ]\n];\nconst House = createLucideIcon(\"house\", __iconNode);\n\nexport { __iconNode, House as default };\n//# sourceMappingURL=house.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"path\", { d: \"M12 16v-4\", key: \"1dtifu\" }],\n [\"path\", { d: \"M12 8h.01\", key: \"e9boi3\" }]\n];\nconst Info = createLucideIcon(\"info\", __iconNode);\n\nexport { __iconNode, Info as default };\n//# sourceMappingURL=info.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z\",\n key: \"1s6t7t\"\n }\n ],\n [\"circle\", { cx: \"16.5\", cy: \"7.5\", r: \".5\", fill: \"currentColor\", key: \"w0ekpg\" }]\n];\nconst KeyRound = createLucideIcon(\"key-round\", __iconNode);\n\nexport { __iconNode, KeyRound as default };\n//# sourceMappingURL=key-round.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"m15.5 7.5 2.3 2.3a1 1 0 0 0 1.4 0l2.1-2.1a1 1 0 0 0 0-1.4L19 4\", key: \"g0fldk\" }],\n [\"path\", { d: \"m21 2-9.6 9.6\", key: \"1j0ho8\" }],\n [\"circle\", { cx: \"7.5\", cy: \"15.5\", r: \"5.5\", key: \"yqb3hr\" }]\n];\nconst Key = createLucideIcon(\"key\", __iconNode);\n\nexport { __iconNode, Key as default };\n//# sourceMappingURL=key.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M13 5h8\", key: \"a7qcls\" }],\n [\"path\", { d: \"M13 12h8\", key: \"h98zly\" }],\n [\"path\", { d: \"M13 19h8\", key: \"c3s6r1\" }],\n [\"path\", { d: \"m3 17 2 2 4-4\", key: \"1jhpwq\" }],\n [\"rect\", { x: \"3\", y: \"4\", width: \"6\", height: \"6\", rx: \"1\", key: \"cif1o7\" }]\n];\nconst ListTodo = createLucideIcon(\"list-todo\", __iconNode);\n\nexport { __iconNode, ListTodo as default };\n//# sourceMappingURL=list-todo.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [[\"path\", { d: \"M21 12a9 9 0 1 1-6.219-8.56\", key: \"13zald\" }]];\nconst LoaderCircle = createLucideIcon(\"loader-circle\", __iconNode);\n\nexport { __iconNode, LoaderCircle as default };\n//# sourceMappingURL=loader-circle.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"m10 17 5-5-5-5\", key: \"1bsop3\" }],\n [\"path\", { d: \"M15 12H3\", key: \"6jk70r\" }],\n [\"path\", { d: \"M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4\", key: \"u53s6r\" }]\n];\nconst LogIn = createLucideIcon(\"log-in\", __iconNode);\n\nexport { __iconNode, LogIn as default };\n//# sourceMappingURL=log-in.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"m16 17 5-5-5-5\", key: \"1bji2h\" }],\n [\"path\", { d: \"M21 12H9\", key: \"dn1m92\" }],\n [\"path\", { d: \"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\", key: \"1uf3rs\" }]\n];\nconst LogOut = createLucideIcon(\"log-out\", __iconNode);\n\nexport { __iconNode, LogOut as default };\n//# sourceMappingURL=log-out.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M22 10.5V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v12c0 1.1.9 2 2 2h12.5\", key: \"e61zoh\" }],\n [\"path\", { d: \"m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7\", key: \"1ocrg3\" }],\n [\"path\", { d: \"M20 14v4\", key: \"1hm744\" }],\n [\"path\", { d: \"M20 22v.01\", key: \"12bgn6\" }]\n];\nconst MailWarning = createLucideIcon(\"mail-warning\", __iconNode);\n\nexport { __iconNode, MailWarning as default };\n//# sourceMappingURL=mail-warning.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0\",\n key: \"1r0f0z\"\n }\n ],\n [\"circle\", { cx: \"12\", cy: \"10\", r: \"3\", key: \"ilqhr7\" }]\n];\nconst MapPin = createLucideIcon(\"map-pin\", __iconNode);\n\nexport { __iconNode, MapPin as default };\n//# sourceMappingURL=map-pin.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M4 5h16\", key: \"1tepv9\" }],\n [\"path\", { d: \"M4 12h16\", key: \"1lakjw\" }],\n [\"path\", { d: \"M4 19h16\", key: \"1djgab\" }]\n];\nconst Menu = createLucideIcon(\"menu\", __iconNode);\n\nexport { __iconNode, Menu as default };\n//# sourceMappingURL=menu.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"rect\", { width: \"20\", height: \"14\", x: \"2\", y: \"3\", rx: \"2\", key: \"48i651\" }],\n [\"line\", { x1: \"8\", x2: \"16\", y1: \"21\", y2: \"21\", key: \"1svkeh\" }],\n [\"line\", { x1: \"12\", x2: \"12\", y1: \"17\", y2: \"21\", key: \"vw1qmm\" }]\n];\nconst Monitor = createLucideIcon(\"monitor\", __iconNode);\n\nexport { __iconNode, Monitor as default };\n//# sourceMappingURL=monitor.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401\",\n key: \"kfwtm\"\n }\n ]\n];\nconst Moon = createLucideIcon(\"moon\", __iconNode);\n\nexport { __iconNode, Moon as default };\n//# sourceMappingURL=moon.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M8 2v4\", key: \"1cmpym\" }],\n [\"path\", { d: \"M12 2v4\", key: \"3427ic\" }],\n [\"path\", { d: \"M16 2v4\", key: \"4m81vk\" }],\n [\"rect\", { width: \"16\", height: \"18\", x: \"4\", y: \"4\", rx: \"2\", key: \"1u9h20\" }],\n [\"path\", { d: \"M8 10h6\", key: \"3oa6kw\" }],\n [\"path\", { d: \"M8 14h8\", key: \"1fgep2\" }],\n [\"path\", { d: \"M8 18h5\", key: \"17enja\" }]\n];\nconst NotepadText = createLucideIcon(\"notepad-text\", __iconNode);\n\nexport { __iconNode, NotepadText as default };\n//# sourceMappingURL=notepad-text.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z\",\n key: \"1a0edw\"\n }\n ],\n [\"path\", { d: \"M12 22V12\", key: \"d0xqtd\" }],\n [\"polyline\", { points: \"3.29 7 12 12 20.71 7\", key: \"ousv84\" }],\n [\"path\", { d: \"m7.5 4.27 9 5.15\", key: \"1c824w\" }]\n];\nconst Package = createLucideIcon(\"package\", __iconNode);\n\nexport { __iconNode, Package as default };\n//# sourceMappingURL=package.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z\",\n key: \"1a8usu\"\n }\n ],\n [\"path\", { d: \"m15 5 4 4\", key: \"1mk7zo\" }]\n];\nconst Pencil = createLucideIcon(\"pencil\", __iconNode);\n\nexport { __iconNode, Pencil as default };\n//# sourceMappingURL=pencil.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M5 12h14\", key: \"1ays0h\" }],\n [\"path\", { d: \"M12 5v14\", key: \"s699le\" }]\n];\nconst Plus = createLucideIcon(\"plus\", __iconNode);\n\nexport { __iconNode, Plus as default };\n//# sourceMappingURL=plus.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M13 16H8\", key: \"wsln4y\" }],\n [\"path\", { d: \"M14 8H8\", key: \"1l3xfs\" }],\n [\"path\", { d: \"M16 12H8\", key: \"1fr5h0\" }],\n [\n \"path\",\n {\n d: \"M4 3a1 1 0 0 1 1-1 1.3 1.3 0 0 1 .7.2l.933.6a1.3 1.3 0 0 0 1.4 0l.934-.6a1.3 1.3 0 0 1 1.4 0l.933.6a1.3 1.3 0 0 0 1.4 0l.933-.6a1.3 1.3 0 0 1 1.4 0l.934.6a1.3 1.3 0 0 0 1.4 0l.933-.6A1.3 1.3 0 0 1 19 2a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1 1.3 1.3 0 0 1-.7-.2l-.933-.6a1.3 1.3 0 0 0-1.4 0l-.934.6a1.3 1.3 0 0 1-1.4 0l-.933-.6a1.3 1.3 0 0 0-1.4 0l-.933.6a1.3 1.3 0 0 1-1.4 0l-.934-.6a1.3 1.3 0 0 0-1.4 0l-.933.6a1.3 1.3 0 0 1-.7.2 1 1 0 0 1-1-1z\",\n key: \"ycz6yz\"\n }\n ]\n];\nconst ReceiptText = createLucideIcon(\"receipt-text\", __iconNode);\n\nexport { __iconNode, ReceiptText as default };\n//# sourceMappingURL=receipt-text.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 17V7\", key: \"pyj7ub\" }],\n [\"path\", { d: \"M16 8h-6a2 2 0 0 0 0 4h4a2 2 0 0 1 0 4H8\", key: \"1elt7d\" }],\n [\n \"path\",\n {\n d: \"M4 3a1 1 0 0 1 1-1 1.3 1.3 0 0 1 .7.2l.933.6a1.3 1.3 0 0 0 1.4 0l.934-.6a1.3 1.3 0 0 1 1.4 0l.933.6a1.3 1.3 0 0 0 1.4 0l.933-.6a1.3 1.3 0 0 1 1.4 0l.934.6a1.3 1.3 0 0 0 1.4 0l.933-.6A1.3 1.3 0 0 1 19 2a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1 1.3 1.3 0 0 1-.7-.2l-.933-.6a1.3 1.3 0 0 0-1.4 0l-.934.6a1.3 1.3 0 0 1-1.4 0l-.933-.6a1.3 1.3 0 0 0-1.4 0l-.933.6a1.3 1.3 0 0 1-1.4 0l-.934-.6a1.3 1.3 0 0 0-1.4 0l-.933.6a1.3 1.3 0 0 1-.7.2 1 1 0 0 1-1-1z\",\n key: \"ycz6yz\"\n }\n ]\n];\nconst Receipt = createLucideIcon(\"receipt\", __iconNode);\n\nexport { __iconNode, Receipt as default };\n//# sourceMappingURL=receipt.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8\", key: \"v9h5vc\" }],\n [\"path\", { d: \"M21 3v5h-5\", key: \"1q7to0\" }],\n [\"path\", { d: \"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16\", key: \"3uifl3\" }],\n [\"path\", { d: \"M8 16H3v5\", key: \"1cv678\" }]\n];\nconst RefreshCw = createLucideIcon(\"refresh-cw\", __iconNode);\n\nexport { __iconNode, RefreshCw as default };\n//# sourceMappingURL=refresh-cw.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\", key: \"1357e3\" }],\n [\"path\", { d: \"M3 3v5h5\", key: \"1xhq8a\" }]\n];\nconst RotateCcw = createLucideIcon(\"rotate-ccw\", __iconNode);\n\nexport { __iconNode, RotateCcw as default };\n//# sourceMappingURL=rotate-ccw.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z\",\n key: \"1c8476\"\n }\n ],\n [\"path\", { d: \"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7\", key: \"1ydtos\" }],\n [\"path\", { d: \"M7 3v4a1 1 0 0 0 1 1h7\", key: \"t51u73\" }]\n];\nconst Save = createLucideIcon(\"save\", __iconNode);\n\nexport { __iconNode, Save as default };\n//# sourceMappingURL=save.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 3v18\", key: \"108xh3\" }],\n [\"path\", { d: \"m19 8 3 8a5 5 0 0 1-6 0zV7\", key: \"zcdpyk\" }],\n [\"path\", { d: \"M3 7h1a17 17 0 0 0 8-2 17 17 0 0 0 8 2h1\", key: \"1yorad\" }],\n [\"path\", { d: \"m5 8 3 8a5 5 0 0 1-6 0zV7\", key: \"eua70x\" }],\n [\"path\", { d: \"M7 21h10\", key: \"1b0cd5\" }]\n];\nconst Scale = createLucideIcon(\"scale\", __iconNode);\n\nexport { __iconNode, Scale as default };\n//# sourceMappingURL=scale.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"m21 21-4.34-4.34\", key: \"14j7rj\" }],\n [\"circle\", { cx: \"11\", cy: \"11\", r: \"8\", key: \"4ej97u\" }]\n];\nconst Search = createLucideIcon(\"search\", __iconNode);\n\nexport { __iconNode, Search as default };\n//# sourceMappingURL=search.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"rect\", { width: \"20\", height: \"8\", x: \"2\", y: \"2\", rx: \"2\", ry: \"2\", key: \"ngkwjq\" }],\n [\"rect\", { width: \"20\", height: \"8\", x: \"2\", y: \"14\", rx: \"2\", ry: \"2\", key: \"iecqi9\" }],\n [\"line\", { x1: \"6\", x2: \"6.01\", y1: \"6\", y2: \"6\", key: \"16zg32\" }],\n [\"line\", { x1: \"6\", x2: \"6.01\", y1: \"18\", y2: \"18\", key: \"nzw8ys\" }]\n];\nconst Server = createLucideIcon(\"server\", __iconNode);\n\nexport { __iconNode, Server as default };\n//# sourceMappingURL=server.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915\",\n key: \"1i5ecw\"\n }\n ],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"3\", key: \"1v7zrd\" }]\n];\nconst Settings = createLucideIcon(\"settings\", __iconNode);\n\nexport { __iconNode, Settings as default };\n//# sourceMappingURL=settings.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z\",\n key: \"oel41y\"\n }\n ],\n [\"path\", { d: \"m9 12 2 2 4-4\", key: \"dzmm74\" }]\n];\nconst ShieldCheck = createLucideIcon(\"shield-check\", __iconNode);\n\nexport { __iconNode, ShieldCheck as default };\n//# sourceMappingURL=shield-check.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z\",\n key: \"oel41y\"\n }\n ],\n [\"path\", { d: \"m14.5 9.5-5 5\", key: \"17q4r4\" }],\n [\"path\", { d: \"m9.5 9.5 5 5\", key: \"18nt4w\" }]\n];\nconst ShieldX = createLucideIcon(\"shield-x\", __iconNode);\n\nexport { __iconNode, ShieldX as default };\n//# sourceMappingURL=shield-x.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M10 5H3\", key: \"1qgfaw\" }],\n [\"path\", { d: \"M12 19H3\", key: \"yhmn1j\" }],\n [\"path\", { d: \"M14 3v4\", key: \"1sua03\" }],\n [\"path\", { d: \"M16 17v4\", key: \"1q0r14\" }],\n [\"path\", { d: \"M21 12h-9\", key: \"1o4lsq\" }],\n [\"path\", { d: \"M21 19h-5\", key: \"1rlt1p\" }],\n [\"path\", { d: \"M21 5h-7\", key: \"1oszz2\" }],\n [\"path\", { d: \"M8 10v4\", key: \"tgpxqk\" }],\n [\"path\", { d: \"M8 12H3\", key: \"a7s4jb\" }]\n];\nconst SlidersHorizontal = createLucideIcon(\"sliders-horizontal\", __iconNode);\n\nexport { __iconNode, SlidersHorizontal as default };\n//# sourceMappingURL=sliders-horizontal.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\", key: \"1m0v6g\" }],\n [\n \"path\",\n {\n d: \"M18.375 2.625a1 1 0 0 1 3 3l-9.013 9.014a2 2 0 0 1-.853.505l-2.873.84a.5.5 0 0 1-.62-.62l.84-2.873a2 2 0 0 1 .506-.852z\",\n key: \"ohrbg2\"\n }\n ]\n];\nconst SquarePen = createLucideIcon(\"square-pen\", __iconNode);\n\nexport { __iconNode, SquarePen as default };\n//# sourceMappingURL=square-pen.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"4\", key: \"4exip2\" }],\n [\"path\", { d: \"M12 2v2\", key: \"tus03m\" }],\n [\"path\", { d: \"M12 20v2\", key: \"1lh1kg\" }],\n [\"path\", { d: \"m4.93 4.93 1.41 1.41\", key: \"149t6j\" }],\n [\"path\", { d: \"m17.66 17.66 1.41 1.41\", key: \"ptbguv\" }],\n [\"path\", { d: \"M2 12h2\", key: \"1t8f8n\" }],\n [\"path\", { d: \"M20 12h2\", key: \"1q8mjw\" }],\n [\"path\", { d: \"m6.34 17.66-1.41 1.41\", key: \"1m8zz5\" }],\n [\"path\", { d: \"m19.07 4.93-1.41 1.41\", key: \"1shlcs\" }]\n];\nconst Sun = createLucideIcon(\"sun\", __iconNode);\n\nexport { __iconNode, Sun as default };\n//# sourceMappingURL=sun.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 3v18\", key: \"108xh3\" }],\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M3 9h18\", key: \"1pudct\" }],\n [\"path\", { d: \"M3 15h18\", key: \"5xshup\" }]\n];\nconst Table = createLucideIcon(\"table\", __iconNode);\n\nexport { __iconNode, Table as default };\n//# sourceMappingURL=table.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 19h8\", key: \"baeox8\" }],\n [\"path\", { d: \"m4 17 6-6-6-6\", key: \"1yngyt\" }]\n];\nconst Terminal = createLucideIcon(\"terminal\", __iconNode);\n\nexport { __iconNode, Terminal as default };\n//# sourceMappingURL=terminal.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z\",\n key: \"qn84l0\"\n }\n ],\n [\"path\", { d: \"M13 5v2\", key: \"dyzc3o\" }],\n [\"path\", { d: \"M13 17v2\", key: \"1ont0d\" }],\n [\"path\", { d: \"M13 11v2\", key: \"1wjjxi\" }]\n];\nconst Ticket = createLucideIcon(\"ticket\", __iconNode);\n\nexport { __iconNode, Ticket as default };\n//# sourceMappingURL=ticket.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M10 11v6\", key: \"nco0om\" }],\n [\"path\", { d: \"M14 11v6\", key: \"outv1u\" }],\n [\"path\", { d: \"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\", key: \"miytrc\" }],\n [\"path\", { d: \"M3 6h18\", key: \"d0wm0j\" }],\n [\"path\", { d: \"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\", key: \"e791ji\" }]\n];\nconst Trash2 = createLucideIcon(\"trash-2\", __iconNode);\n\nexport { __iconNode, Trash2 as default };\n//# sourceMappingURL=trash-2.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\", key: \"miytrc\" }],\n [\"path\", { d: \"M3 6h18\", key: \"d0wm0j\" }],\n [\"path\", { d: \"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\", key: \"e791ji\" }]\n];\nconst Trash = createLucideIcon(\"trash\", __iconNode);\n\nexport { __iconNode, Trash as default };\n//# sourceMappingURL=trash.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\",\n key: \"wmoenq\"\n }\n ],\n [\"path\", { d: \"M12 9v4\", key: \"juzpu7\" }],\n [\"path\", { d: \"M12 17h.01\", key: \"p32p05\" }]\n];\nconst TriangleAlert = createLucideIcon(\"triangle-alert\", __iconNode);\n\nexport { __iconNode, TriangleAlert as default };\n//# sourceMappingURL=triangle-alert.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2\", key: \"975kel\" }],\n [\"circle\", { cx: \"12\", cy: \"7\", r: \"4\", key: \"17ys0d\" }]\n];\nconst User = createLucideIcon(\"user\", __iconNode);\n\nexport { __iconNode, User as default };\n//# sourceMappingURL=user.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2\", key: \"1yyitq\" }],\n [\"path\", { d: \"M16 3.128a4 4 0 0 1 0 7.744\", key: \"16gr8j\" }],\n [\"path\", { d: \"M22 21v-2a4 4 0 0 0-3-3.87\", key: \"kshegd\" }],\n [\"circle\", { cx: \"9\", cy: \"7\", r: \"4\", key: \"nufk8\" }]\n];\nconst Users = createLucideIcon(\"users\", __iconNode);\n\nexport { __iconNode, Users as default };\n//# sourceMappingURL=users.mjs.map\n","/**\n * @license lucide-react v1.17.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M18 6 6 18\", key: \"1bl5f8\" }],\n [\"path\", { d: \"m6 6 12 12\", key: \"d8bk6v\" }]\n];\nconst X = createLucideIcon(\"x\", __iconNode);\n\nexport { __iconNode, X as default };\n//# sourceMappingURL=x.mjs.map\n","import { Button } from '@/components/ui/button';\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';\nimport { defaultInstanceRoute, isLocalStudio } from '@/config/constants';\nimport { useOverallAuth } from '@/hooks/useAuth';\nimport { cn } from '@/lib/cn';\nimport { getDefaultSignedInCloudRouteForUser } from '@/lib/urls/getDefaultSignedInCloudRouteForUser';\nimport { Link } from '@tanstack/react-router';\nimport { ArrowLeft } from 'lucide-react';\nimport { ReactNode } from 'react';\n\ninterface ErrorProps {\n\tclassName?: string | undefined;\n\terror: Error | { message: string | ReactNode };\n\ttitle?: string;\n\tshowReturnToHome?: boolean;\n\tchildren?: ReactNode;\n}\n\nexport function ErrorComponent({ className, error, title, showReturnToHome, children }: ErrorProps) {\n\tconst { user, isLoading: isUserLoading } = useOverallAuth();\n\tconst defaultCloudRoute = getDefaultSignedInCloudRouteForUser(user);\n\n\treturn (\n\t\t<Card className={cn('text-red p-5 border border-red rounded-md m-12 mt-36', className)}>\n\t\t\t<CardHeader>\n\t\t\t\t<CardTitle className=\"text-2xl\">\n\t\t\t\t\t<h2>{title ?? 'Component Error'}</h2>\n\t\t\t\t</CardTitle>\n\t\t\t\t<CardDescription>{error.message}</CardDescription>\n\t\t\t</CardHeader>\n\t\t\t<CardContent>\n\t\t\t\t{children}\n\t\t\t\t{showReturnToHome !== false && (user && !isUserLoading\n\t\t\t\t\t? (\n\t\t\t\t\t\t<Link to={isLocalStudio ? defaultInstanceRoute : defaultCloudRoute}>\n\t\t\t\t\t\t\t<Button>\n\t\t\t\t\t\t\t\t{' '}\n\t\t\t\t\t\t\t\t<ArrowLeft /> Return to Home\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t</Link>\n\t\t\t\t\t)\n\t\t\t\t\t: (\n\t\t\t\t\t\t<Link to=\"/sign-in\">\n\t\t\t\t\t\t\t<Button>\n\t\t\t\t\t\t\t\t{' '}\n\t\t\t\t\t\t\t\t<ArrowLeft /> Go to Sign In Page\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t</Link>\n\t\t\t\t\t))}\n\t\t\t</CardContent>\n\t\t</Card>\n\t);\n}\n","import { Button } from '@/components/ui/button';\nimport { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';\nimport { defaultInstanceRoute, isLocalStudio } from '@/config/constants';\nimport { useOverallAuth } from '@/hooks/useAuth';\nimport { getDefaultSignedInCloudRouteForUser } from '@/lib/urls/getDefaultSignedInCloudRouteForUser';\nimport { Link } from '@tanstack/react-router';\nimport { ArrowLeft } from 'lucide-react';\n\nexport function NotFoundComponent() {\n\tconst { user, isLoading: isUserLoading } = useOverallAuth();\n\tconst defaultCloudRoute = getDefaultSignedInCloudRouteForUser(user);\n\treturn (\n\t\t<div className=\"flex items-center justify-center h-screen px-3\">\n\t\t\t<Card className=\"text-red p-5 border border-red rounded-md w-full max-w-md\">\n\t\t\t\t<CardHeader>\n\t\t\t\t\t<CardTitle className=\"text-2xl\">\n\t\t\t\t\t\t<h2>Sorry, Page Not Found</h2>\n\t\t\t\t\t</CardTitle>\n\t\t\t\t</CardHeader>\n\t\t\t\t<CardContent>\n\t\t\t\t\t{user && !isUserLoading\n\t\t\t\t\t\t? (\n\t\t\t\t\t\t\t<Link to={isLocalStudio ? defaultInstanceRoute : defaultCloudRoute}>\n\t\t\t\t\t\t\t\t<Button>\n\t\t\t\t\t\t\t\t\t{' '}\n\t\t\t\t\t\t\t\t\t<ArrowLeft /> Return to Home\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t)\n\t\t\t\t\t\t: (\n\t\t\t\t\t\t\t<Link to=\"/sign-in\">\n\t\t\t\t\t\t\t\t<Button>\n\t\t\t\t\t\t\t\t\t{' '}\n\t\t\t\t\t\t\t\t\t<ArrowLeft /> Go Sign In Page\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t)}\n\t\t\t\t</CardContent>\n\t\t\t</Card>\n\t\t</div>\n\t);\n}\n","export function browserIsTouchBased(): boolean {\n\treturn 'ontouchstart' in window || navigator['maxTouchPoints'] > 0;\n}\n","import { MutationCache, QueryCache, QueryClient } from '@tanstack/react-query';\nimport { AxiosError } from 'axios';\nimport { toast } from 'sonner';\n\nexport function errorHandler(rawErr: unknown) {\n\tlet errorTitle = 'Error';\n\tlet errorMsg = 'We had some trouble!';\n\tconsole.error(rawErr);\n\tconst axiosWrappedErr = rawErr as AxiosError<string | { error?: string; message?: string }>;\n\tconst otherErr = rawErr as { message?: string };\n\tif (typeof rawErr === 'string') {\n\t\terrorMsg = rawErr;\n\t} else if (axiosWrappedErr?.response?.data) {\n\t\tif (typeof axiosWrappedErr.response.data === 'string') {\n\t\t\terrorMsg = axiosWrappedErr.response.data;\n\t\t} else if (axiosWrappedErr.response.data.error) {\n\t\t\terrorMsg = axiosWrappedErr.response.data.error;\n\t\t} else if (axiosWrappedErr.response.data.message) {\n\t\t\terrorMsg = axiosWrappedErr.response.data.message;\n\t\t}\n\t} else if (otherErr?.message) {\n\t\terrorMsg = otherErr.message;\n\t}\n\tif (errorMsg.includes(':')) {\n\t\tconst split = errorMsg.split(':');\n\t\terrorTitle = split.shift()!;\n\t\terrorMsg = split.join(':');\n\t}\n\t// Axios surfaces request timeouts as ECONNABORTED / ETIMEDOUT. Multiple\n\t// queries can timeout in parallel and stack up identical toasts; collapse\n\t// them onto a single id so the user sees one instead of a wall.\n\tconst isTimeout = axiosWrappedErr?.code === 'ECONNABORTED' || axiosWrappedErr?.code === 'ETIMEDOUT';\n\ttoast.error(errorTitle, {\n\t\tid: isTimeout ? 'request-timeout' : undefined,\n\t\tdescription: errorMsg,\n\t\taction: {\n\t\t\tlabel: 'Dismiss',\n\t\t\tonClick: () => toast.dismiss(),\n\t\t},\n\t});\n}\n\nexport const queryClient = new QueryClient({\n\tqueryCache: new QueryCache({\n\t\tonError: errorHandler,\n\t}),\n\tmutationCache: new MutationCache({\n\t\tonError: errorHandler,\n\t}),\n});\n","export function excludeFalsy<T>(item: T | undefined | 0 | false | null): item is T {\n\treturn !!item;\n}\n","import { isLocalStudio } from '@/config/constants';\nimport { useOverallAuth } from '@/hooks/useAuth';\nimport { translateUrlForDatadog } from '@/integrations/datadog/translateUrlForDatadog';\nimport { excludeFalsy } from '@/lib/arrays/excludeFalsy';\nimport { isLocalUser } from '@/lib/types/isLocalUser';\nimport { datadogRum } from '@datadog/browser-rum';\nimport { reactPlugin } from '@datadog/browser-rum-react';\nimport { useLocation, useRouter } from '@tanstack/react-router';\nimport { useEffect } from 'react';\n\nlet initialized = false;\nconst enabled = !import.meta.env.DEV && !isLocalStudio;\n\n/**\n * Reaching an instance can legitimately fail when it's down, restarting, or the\n * user lacks Fabric Connect — these are expected states, not Studio bugs, and they\n * otherwise flood Error Tracking. Drop connectivity-class errors (timeouts, network\n * failures) against instance/cluster operation endpoints so they don't create issues.\n *\n * Returning false discards the event entirely.\n */\nfunction discardExpectedInstanceErrors(\n\tevent: { type: string; error?: { message?: string; source?: string; resource?: { url?: string } } },\n) {\n\tif (event.type !== 'error') {\n\t\treturn true;\n\t}\n\tconst message = event.error?.message ?? '';\n\tconst source = event.error?.source;\n\n\t// Aborted requests are client-initiated cancellations (navigating away, a\n\t// component unmounting, React Query cancelling an in-flight query) — not failures.\n\t// Safe to drop globally regardless of endpoint.\n\tif (/Request aborted/i.test(message)) {\n\t\treturn false;\n\t}\n\n\t// Belt-and-suspenders: any stray \"Fabric Connect not established\" breadcrumb.\n\tif (message.includes('Fabric Connect not established')) {\n\t\treturn false;\n\t}\n\n\t// Network failures (timeouts, connection refused) against an instance/cluster.\n\tconst url = event.error?.resource?.url ?? '';\n\tconst isInstanceEndpoint = /\\/(HDBInstance|Cluster)\\/[^/]+\\/operation/.test(url);\n\tconst isConnectivityFailure = /timeout of \\d+ms exceeded/i.test(message)\n\t\t|| /Network Error/i.test(message)\n\t\t|| source === 'network';\n\tif (isInstanceEndpoint && isConnectivityFailure) {\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nexport function useDatadog() {\n\tuseEffect(() => {\n\t\tif (initialized) {\n\t\t\treturn;\n\t\t}\n\t\tinitialized = true;\n\t\tif (enabled) {\n\t\t\tdatadogRum.init({\n\t\t\t\tapplicationId: 'f590deee-4bac-49b4-a202-3b6963d9721d',\n\t\t\t\tclientToken: 'pub27aa29cea521492f4fef73032f86a023',\n\n\t\t\t\t// proxy: ({ path, parameters }) => `/Drink/?pour=${btoa(`${path}?${parameters}`)}`,\n\n\t\t\t\tsite: 'datadoghq.com',\n\t\t\t\tservice: 'studio',\n\t\t\t\tenv: import.meta.env.VITE_ENV_NAME,\n\t\t\t\tversion: import.meta.env.VITE_STUDIO_VERSION,\n\n\t\t\t\ttrackViewsManually: true,\n\t\t\t\ttrackUserInteractions: true,\n\n\t\t\t\tbeforeSend: discardExpectedInstanceErrors,\n\n\t\t\t\tsessionSampleRate: 100,\n\t\t\t\tsessionReplaySampleRate: 0,\n\t\t\t\tdefaultPrivacyLevel: 'mask',\n\n\t\t\t\tplugins: [reactPlugin()],\n\t\t\t});\n\n\t\t\tdatadogRum.onReady(() => {\n\t\t\t\tdatadogRum.startView({\n\t\t\t\t\tservice: 'studio',\n\t\t\t\t\tversion: import.meta.env.VITE_STUDIO_VERSION,\n\t\t\t\t\tname: window.location.pathname || 'initial',\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\t}, []);\n}\n\nexport function useOnRouteLoadTracker() {\n\tconst location = useLocation();\n\tconst router = useRouter();\n\tconst { user } = useOverallAuth();\n\n\tuseEffect(() => {\n\t\tconst currentMatches = router.matchRoutes(router.state.location);\n\t\tconst name = translateUrlForDatadog(\n\t\t\tlocation.href,\n\t\t\tcurrentMatches.map((m) => m.params),\n\t\t);\n\t\tif (!enabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tdatadogRum.onReady(() => {\n\t\t\tdatadogRum.startView({\n\t\t\t\tservice: 'studio',\n\t\t\t\tversion: import.meta.env.VITE_STUDIO_VERSION,\n\t\t\t\tname,\n\t\t\t});\n\t\t});\n\t}, [location.href, router]);\n\n\tuseEffect(() => {\n\t\tif (!enabled) {\n\t\t\treturn;\n\t\t}\n\t\tif (user && !isLocalUser(user)) {\n\t\t\tdatadogRum.setUser({\n\t\t\t\tid: user.id,\n\t\t\t\tname: [user.firstname, user.lastname].filter(excludeFalsy).join(' ') || undefined,\n\t\t\t\temail: user.email,\n\t\t\t});\n\t\t} else {\n\t\t\tdatadogRum.clearUser();\n\t\t}\n\t}, [user]);\n}\n\nexport function loginSuccessDatadogAction(data: { id: string; email: string; firstname: string; lastname: string }) {\n\tif (!enabled) { return; }\n\n\tdatadogRum.setUser({\n\t\tid: data.id,\n\t\temail: data.email,\n\t\tname: [data.firstname, data.lastname].filter(Boolean).join(' ') || undefined,\n\t});\n\n\t// First vs return login (per user)\n\tconst hasLoggedInKey = `hasLoggedInBefore:${data.id}`;\n\tconst hasLoggedInBefore = !!localStorage.getItem(hasLoggedInKey);\n\n\tif (hasLoggedInBefore) {\n\t\tdatadogRum.addAction('return_login');\n\t} else {\n\t\tdatadogRum.addAction('first_time_login');\n\t\tlocalStorage.setItem(hasLoggedInKey, 'true');\n\t}\n\n\t// Time between logins (per user)\n\tconst lastLoginKey = `lastLoginTimestamp:${data.id}`;\n\tconst lastLogin = localStorage.getItem(lastLoginKey);\n\tconst now = Date.now();\n\n\tif (lastLogin) {\n\t\tconst seconds = Math.floor((now - Number(lastLogin)) / 1000);\n\t\tif (!Number.isNaN(seconds) && seconds >= 0) {\n\t\t\tdatadogRum.addAction('login_time_gap', { value: seconds });\n\t\t}\n\t}\n\n\tlocalStorage.setItem(lastLoginKey, String(now));\n\n\tdatadogRum.addAction('login_success', { userId: data.id });\n}\n","import { HeadContent, Outlet } from '@tanstack/react-router';\n\nexport function StudioLocal() {\n\treturn (\n\t\t<>\n\t\t\t<HeadContent />\n\t\t\t<Outlet />\n\t\t</>\n\t);\n}\n","import { StudioCloud } from '@/components/StudioCloud';\nimport { StudioLocal } from '@/components/StudioLocal';\nimport { isLocalStudio } from '@/config/constants';\nimport { AuthenticatedConnection, EntityIds } from '@/features/auth/store/authStore';\nimport { QueryClient } from '@tanstack/react-query';\nimport { createRootRouteWithContext } from '@tanstack/react-router';\n\nexport const rootRoute = createRootRouteWithContext<{\n\tqueryClient: QueryClient;\n\tauthentication: Record<EntityIds, AuthenticatedConnection>;\n}>()({\n\tcomponent: isLocalStudio ? StudioLocal : StudioCloud,\n});\n","export function DiscordLogo() {\n\treturn (\n\t\t<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 126.644 96\" width={24} height={24}>\n\t\t\t<path\n\t\t\t\tfill=\"currentColor\"\n\t\t\t\td=\"M81.15,0c-1.2376,2.1973-2.3489,4.4704-3.3591,6.794-9.5975-1.4396-19.3718-1.4396-28.9945,0-.985-2.3236-2.1216-4.5967-3.3591-6.794-9.0166,1.5407-17.8059,4.2431-26.1405,8.0568C2.779,32.5304-1.6914,56.3725.5312,79.8863c9.6732,7.1476,20.5083,12.603,32.0505,16.0884,2.6014-3.4854,4.8998-7.1981,6.8698-11.0623-3.738-1.3891-7.3497-3.1318-10.8098-5.1523.9092-.6567,1.7932-1.3386,2.6519-1.9953,20.281,9.547,43.7696,9.547,64.0758,0,.8587.7072,1.7427,1.3891,2.6519,1.9953-3.4601,2.0457-7.0718,3.7632-10.835,5.1776,1.97,3.8642,4.2683,7.5769,6.8698,11.0623,11.5419-3.4854,22.3769-8.9156,32.0509-16.0631,2.626-27.2771-4.496-50.9172-18.817-71.8548C98.9811,4.2684,90.1918,1.5659,81.1752.0505l-.0252-.0505ZM42.2802,65.4144c-6.2383,0-11.4159-5.6575-11.4159-12.6535s4.9755-12.6788,11.3907-12.6788,11.5169,5.708,11.4159,12.6788c-.101,6.9708-5.026,12.6535-11.3907,12.6535ZM84.3576,65.4144c-6.2637,0-11.3907-5.6575-11.3907-12.6535s4.9755-12.6788,11.3907-12.6788,11.4917,5.708,11.3906,12.6788c-.101,6.9708-5.026,12.6535-11.3906,12.6535Z\"\n\t\t\t/>\n\t\t</svg>\n\t);\n}\n","import { isLocalStudio } from '@/config/constants';\n\nexport function MainLogo() {\n\treturn (\n\t\t<>\n\t\t\t{isLocalStudio\n\t\t\t\t? <img src=\"/harper-studio_white.png\" alt=\"Harper Studio\" className=\"w-64 hidden md:inline-block\" />\n\t\t\t\t: (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\tsrc=\"/harper-fabric_black.png\"\n\t\t\t\t\t\t\talt=\"Harper Fabric\"\n\t\t\t\t\t\t\tclassName=\"w-64 hidden md:inline-block dark:hidden\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<img src=\"/harper-fabric_white.png\" alt=\"Harper Fabric\" className=\"w-64 hidden md:dark:inline-block\" />\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t<img src=\"/HDBDogOnly.svg\" width=\"50px\" height=\"44px\" alt=\"Harper\" className=\"inline-block md:hidden\" />\n\t\t</>\n\t);\n}\n","/**\n * Attempts to parse a string as JSON, and narrows the type down to the provided generic. Note that\n * no schema validation happens as a part of this, so the type might be inaccurate. But exceptions\n * won't be thrown by the actual parsing if invalid JSON is provided.\n * @param value\n */\nexport function safeParse<T>(value: string | null | undefined): T | null {\n\ttry {\n\t\tif (value === 'null' || value === 'undefined' || value === null || value === undefined) {\n\t\t\treturn null;\n\t\t}\n\t\treturn JSON.parse(value) as T;\n\t} catch (err) {\n\t\tconsole.error('safeParse failed to parse value, returning null instead', err);\n\t\treturn null;\n\t}\n}\n","import { LocalStorageKeys } from '@/lib/storage/localStorageKeys';\nimport { safeParse } from '@/lib/string/safeParse';\n\n/**\n * Retrieves a value from local storage.\n * @param key\n * @param defaultValue\n */\nexport function getLocalStorage<T>(key: LocalStorageKeys, defaultValue: T): T {\n\tconst lastSetValue = safeParse<T>(localStorage.getItem(key));\n\treturn lastSetValue ?? defaultValue;\n}\n","import { LocalStorageKeys } from '@/lib/storage/localStorageKeys';\n\n/**\n * Stores a value in local storage for later retrieval.\n * @param key\n * @param current\n */\nexport function setLocalStorage<T>(key: LocalStorageKeys, current: T): void {\n\tif (current === null || current === undefined) {\n\t\tlocalStorage.removeItem(key);\n\t} else {\n\t\tlocalStorage.setItem(key, JSON.stringify(current));\n\t}\n}\n","import { getLocalStorage } from '@/lib/storage/getLocalStorage';\nimport { LocalStorageKeys } from '@/lib/storage/localStorageKeys';\nimport { setLocalStorage } from '@/lib/storage/setLocalStorage';\nimport { useEffect, useState } from 'react';\n\n/**\n * Uses state that gets bootstrapped from and persists to local storage with the key you specify.\n * This does NOT pub-sub value changes in realtime across instances of this hook!\n * @param key\n * @param defaultValue\n */\nexport function useLocalStorage<T>(\n\tkey: LocalStorageKeys,\n\tdefaultValue: T,\n): [T, (value: ((prevState: T) => T) | T) => void] {\n\tconst state = useState<T>(getLocalStorage(key, defaultValue));\n\tconst [current] = state;\n\tuseEffect(() => setLocalStorage(key, current), [key, current]);\n\treturn state;\n}\n","import { useEffect, useState } from 'react';\n\nexport function useSystemTheme(): 'light' | 'dark' {\n\tconst [theme, setTheme] = useState<'light' | 'dark'>(\n\t\t() => window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light',\n\t);\n\tuseEffect(() => {\n\t\tconst mq = window.matchMedia('(prefers-color-scheme: dark)');\n\t\tconst handler = (e: MediaQueryListEvent) => setTheme(e.matches ? 'dark' : 'light');\n\t\tmq.addEventListener('change', handler);\n\t\treturn () => mq.removeEventListener('change', handler);\n\t}, []);\n\treturn theme;\n}\n","export const enum LocalStorageKeys {\n\t'ApplicationChatPosition' = 'ApplicationChatPosition',\n\t'ApplicationChatWidth' = 'ApplicationChatWidth',\n\t'ChatAlwaysApprovedTools' = 'ChatAlwaysApprovedTools',\n\t'SavedClusterState' = 'SavedClusterState',\n\t'Theme' = 'Theme',\n}\n","import { useLocalStorage } from '@/hooks/useLocalStorage';\nimport { useSystemTheme } from '@/hooks/useSystemTheme';\nimport { LocalStorageKeys } from '@/lib/storage/localStorageKeys';\nimport { createContext, ReactNode, useContext, useEffect } from 'react';\n\nexport type Theme = 'system' | 'light' | 'dark';\n\nconst ThemeContext = createContext<[Theme, (t: Theme) => void]>(['system', () => {}]);\n\nexport function ThemeProvider({ children }: { children: ReactNode }) {\n\tconst [theme, setTheme] = useLocalStorage<Theme>(LocalStorageKeys.Theme, 'system');\n\tconst systemTheme = useSystemTheme();\n\n\tuseEffect(() => {\n\t\tconst isDark = theme === 'dark' || (theme === 'system' && systemTheme === 'dark');\n\t\tdocument.documentElement.classList.toggle('dark', isDark);\n\t}, [theme, systemTheme]);\n\n\treturn <ThemeContext.Provider value={[theme, setTheme]}>{children}</ThemeContext.Provider>;\n}\n\nexport function useTheme() {\n\treturn useContext(ThemeContext);\n}\n","import { type Theme, useTheme } from '@/hooks/useTheme';\nimport { MonitorIcon, MoonIcon, SunIcon } from 'lucide-react';\n\nconst OPTIONS: Array<{ value: Theme; icon: React.ReactNode; label: string }> = [\n\t{ value: 'light', icon: <SunIcon className=\"size-4\" />, label: 'Light' },\n\t{ value: 'system', icon: <MonitorIcon className=\"size-4\" />, label: 'System' },\n\t{ value: 'dark', icon: <MoonIcon className=\"size-4\" />, label: 'Dark' },\n];\n\nexport function ThemeToggle() {\n\tconst [theme, setTheme] = useTheme();\n\treturn (\n\t\t<div className=\"flex items-center bg-muted dark:bg-black rounded-xl p-0.5 gap-0.5\">\n\t\t\t{OPTIONS.map(({ value, icon, label }) => (\n\t\t\t\t<button\n\t\t\t\t\tkey={value}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\ttitle={label}\n\t\t\t\t\tonClick={() => setTheme(value)}\n\t\t\t\t\tclassName={`p-1.5 rounded-lg transition-colors ${\n\t\t\t\t\t\ttheme === value\n\t\t\t\t\t\t\t? 'bg-background text-foreground shadow-xs'\n\t\t\t\t\t\t\t: 'text-muted-foreground hover:text-foreground'\n\t\t\t\t\t}`}\n\t\t\t\t>\n\t\t\t\t\t{icon}\n\t\t\t\t</button>\n\t\t\t))}\n\t\t</div>\n\t);\n}\n","import { cn } from '@/lib/cn';\nimport * as NavigationMenuPrimitive from '@radix-ui/react-navigation-menu';\nimport * as React from 'react';\n\nexport function NavigationMenuViewport({\n\tclassName,\n\t...props\n}: React.ComponentProps<typeof NavigationMenuPrimitive.Viewport>) {\n\treturn (\n\t\t<div className={cn('absolute top-full left-0 isolate z-50 flex justify-center')}>\n\t\t\t<NavigationMenuPrimitive.Viewport\n\t\t\t\tdata-slot=\"navigation-menu-viewport\"\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'origin-top-center bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border shadow md:w-[var(--radix-navigation-menu-viewport-width)]',\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n","import { NavigationMenuViewport } from '@/components/ui/navigation/NavigationMenuViewport';\nimport { cn } from '@/lib/cn';\nimport * as NavigationMenuPrimitive from '@radix-ui/react-navigation-menu';\nimport * as React from 'react';\n\nexport function NavigationMenu({\n\tclassName,\n\tchildren,\n\tviewport = true,\n\t...props\n}: React.ComponentProps<typeof NavigationMenuPrimitive.Root> & {\n\tviewport?: boolean;\n}) {\n\treturn (\n\t\t<NavigationMenuPrimitive.Root\n\t\t\tdata-slot=\"navigation-menu\"\n\t\t\tdata-viewport={viewport}\n\t\t\tclassName={cn('group/navigation-menu relative flex max-w-max flex-1 items-center justify-center', className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t\t{viewport && <NavigationMenuViewport />}\n\t\t</NavigationMenuPrimitive.Root>\n\t);\n}\n","import { cn } from '@/lib/cn';\nimport * as NavigationMenuPrimitive from '@radix-ui/react-navigation-menu';\nimport * as React from 'react';\n\nexport function NavigationMenuItem({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Item>) {\n\treturn (\n\t\t<NavigationMenuPrimitive.Item data-slot=\"navigation-menu-item\" className={cn('relative', className)} {...props} />\n\t);\n}\n","import { cn } from '@/lib/cn';\nimport * as NavigationMenuPrimitive from '@radix-ui/react-navigation-menu';\nimport * as React from 'react';\n\nexport function NavigationMenuLink({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Link>) {\n\treturn (\n\t\t<NavigationMenuPrimitive.Link\n\t\t\tdata-slot=\"navigation-menu-link\"\n\t\t\tclassName={cn(\n\t\t\t\t\"hover:text-foreground dark:hover:text-white ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 flex flex-col gap-1 rounded-sm p-2 text-sm transition-[color,box-shadow] focus-visible:ring-4 focus-visible:outline-1 [&_svg:not([class*='size-'])]:size-4\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n","import { cn } from '@/lib/cn';\nimport * as NavigationMenuPrimitive from '@radix-ui/react-navigation-menu';\nimport * as React from 'react';\n\nexport function NavigationMenuList({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.List>) {\n\treturn (\n\t\t<NavigationMenuPrimitive.List\n\t\t\tdata-slot=\"navigation-menu-list\"\n\t\t\tclassName={cn('group flex flex-1 list-none items-center justify-center gap-1', className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n","import { cva } from 'class-variance-authority';\n\nexport const badgeVariants = cva(\n\t'inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-auto',\n\t{\n\t\tvariants: {\n\t\t\tvariant: {\n\t\t\t\tdefault: 'border-primary bg-primary/40 text-primary-foreground [a&]:hover:bg-primary/90',\n\t\t\t\tsecondary: 'border-secondary bg-secondary/40 text-secondary-foreground [a&]:hover:bg-secondary/90',\n\t\t\t\twarning: 'border-yellow bg-yellow/40 text-foreground [a&]:hover:bg-yellow/90',\n\t\t\t\tsuccess: 'border-green bg-green/40 text-foreground [a&]:hover:bg-green/90',\n\t\t\t\tdestructive:\n\t\t\t\t\t'border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40',\n\t\t\t\toutline: 'text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground',\n\t\t\t},\n\t\t},\n\t\tdefaultVariants: {\n\t\t\tvariant: 'default',\n\t\t},\n\t},\n);\n","import { badgeVariants } from '@/components/ui/badgeVariants';\nimport { cn } from '@/lib/cn';\n\nexport function Version() {\n\tlet studioVersion = import.meta.env.VITE_STUDIO_VERSION;\n\tconst link = studioVersion?.startsWith('v')\n\t\t? `https://github.com/HarperFast/studio/releases/tag/${studioVersion}`\n\t\t: 'https://github.com/HarperFast/studio/releases';\n\treturn (\n\t\t<a href={link} target=\"_blank\" rel=\"noopener noreferrer\">\n\t\t\t<span className={cn(badgeVariants({ variant: 'default' }), 'text-xs inline-block ml-2 align-text-top')}>\n\t\t\t\t{studioVersion} BETA\n\t\t\t</span>\n\t\t</a>\n\t);\n}\n","import { isLocalStudio } from '@/config/constants';\nimport { getInstanceClient } from '@/config/getInstanceClient';\nimport { InstanceClientConfig, InstanceClientIdConfig, InstanceTypeConfig } from '@/config/instanceClientConfig';\nimport { OverallAppSignIn } from '@/features/auth/store/authStore';\nimport { useParams } from '@tanstack/react-router';\nimport { useMemo } from 'react';\n\ninterface UseParams {\n\tclusterId?: string;\n\tdisableFabricConnect?: boolean;\n\tforceFabricConnect?: boolean;\n\tinstanceId?: string;\n\toperationsUrl?: string | null;\n\tport?: number;\n\tsecure?: boolean;\n}\n\nexport function useInstanceClient(\n\tparams: UseParams = {},\n) {\n\tconst { instanceId, clusterId }: { instanceId?: string; clusterId?: string } = useParams({ strict: false });\n\tconst id = isLocalStudio ? OverallAppSignIn : params.instanceId ?? instanceId ?? params.clusterId ?? clusterId;\n\treturn getInstanceClient({ id, ...params });\n}\n\nexport function useInstanceClientParams(\n\tparams: UseParams = {},\n): InstanceClientConfig & InstanceTypeConfig {\n\tconst { instanceId, clusterId }: { instanceId?: string; clusterId?: string } = useParams({ strict: false });\n\tconst id = isLocalStudio ? OverallAppSignIn : params.instanceId ?? instanceId ?? params.clusterId ?? clusterId;\n\treturn {\n\t\tinstanceClient: getInstanceClient({ id, ...params }),\n\t\tentityType: (isLocalStudio || instanceId) ? 'instance' : 'cluster',\n\t};\n}\n\nexport function useInstanceClientIdParams(\n\tparams: UseParams = {},\n): InstanceClientIdConfig & InstanceTypeConfig {\n\tconst { instanceId, clusterId }: { instanceId?: string; clusterId?: string } = useParams({ strict: false });\n\treturn useMemo(\n\t\t() => getInstanceClientIdFromParams({ instanceId, clusterId, ...params }),\n\t\t[\n\t\t\tparams.instanceId ?? instanceId,\n\t\t\tparams.clusterId ?? clusterId,\n\t\t\tparams.operationsUrl,\n\t\t\tparams.port,\n\t\t\tparams.secure,\n\t\t\tparams.disableFabricConnect,\n\t\t\tparams.forceFabricConnect,\n\t\t],\n\t);\n}\n\nexport function getInstanceClientIdFromParams({\n\tinstanceId,\n\tclusterId,\n\t...params\n}: UseParams): InstanceClientIdConfig & InstanceTypeConfig {\n\tconst id = isLocalStudio ? OverallAppSignIn : instanceId ?? clusterId;\n\tif (!id) {\n\t\tthrow new Error('id could not be automatically calculated in useInstanceClientIdParams');\n\t}\n\treturn {\n\t\tinstanceClient: getInstanceClient({ id, ...params }),\n\t\tentityId: id,\n\t\tentityType: (isLocalStudio || instanceId) ? 'instance' : 'cluster',\n\t};\n}\n","export function clearLocalStorage(): void {\n\tlocalStorage.clear();\n}\n","export function clearSessionStorage(): void {\n\tsessionStorage.clear();\n}\n","import { authStore, OverallAppSignIn } from '@/features/auth/store/authStore';\nimport { clearLocalStorage } from '@/lib/storage/clearLocalStorage';\nimport { clearSessionStorage } from '@/lib/storage/clearSessionStorage';\nimport { queryClient } from '@/react-query/queryClient';\n\nexport async function logoutOnSuccess() {\n\tauthStore.setUserForEntity(OverallAppSignIn, null);\n\tqueryClient.getQueryCache().clear();\n\tclearLocalStorage();\n\tclearSessionStorage();\n\tawait queryClient.invalidateQueries({ refetchType: 'none' });\n}\n","import { apiClient } from '@/config/apiClient';\nimport { isLocalStudio } from '@/config/constants';\nimport { InstanceClientConfig } from '@/config/instanceClientConfig';\nimport { useInstanceClient } from '@/config/useInstanceClient';\nimport { logoutOnSuccess } from '@/features/auth/handlers/logoutOnSuccess';\nimport { authStore, OverallAppSignIn } from '@/features/auth/store/authStore';\nimport { onInstanceLogoutSubmit } from '@/integrations/api/instance/auth/onInstanceLogoutSubmit';\nimport { useMutation } from '@tanstack/react-query';\n\nasync function onLogoutSubmit(instanceClientConfig: InstanceClientConfig) {\n\tawait authStore.signOutFromPotentiallyAuthenticatedInstances();\n\tif (isLocalStudio) {\n\t\tawait onInstanceLogoutSubmit({ ...instanceClientConfig, entityId: OverallAppSignIn });\n\t} else {\n\t\tawait apiClient.post('/Logout/');\n\t}\n}\n\nexport function useLogoutMutation() {\n\tconst instanceClient = useInstanceClient();\n\treturn useMutation({\n\t\tmutationFn: () => onLogoutSubmit({ instanceClient }),\n\t\tonSuccess: logoutOnSuccess,\n\t});\n}\n","import { EntityIds } from '@/features/auth/store/authStore';\nimport { isAdminMode, useCloudAuth, useInstanceAuth } from '@/hooks/useAuth';\nimport {\n\tLocalLegacyRolePermissionTable,\n\tLocalRoleAttributePermissionAction,\n\tLocalRolePermissionAction,\n\tLocalRolePermissionTable,\n\tUser,\n} from '@/integrations/api/api.patch';\nimport { useParams } from '@tanstack/react-router';\n\ninterface UR {\n\tupdate: boolean;\n\tremove: boolean;\n}\n\ninterface CRUV {\n\tcreate: boolean;\n\tremove: boolean;\n\tupdate: boolean;\n\tview: boolean;\n}\n\nexport function useOrganizationPermissions(orgId?: string): UR {\n\tconst { user } = useCloudAuth();\n\tconst { organizationId: orgIdFromRoute }: { organizationId: string } = useParams({ strict: false });\n\n\tif (isAdminMode(user)) {\n\t\treturn { update: true, remove: true };\n\t}\n\n\tconst role = user?.roles?.[orgId ?? orgIdFromRoute];\n\tif (!role || 'oauthProviders' in role) {\n\t\treturn { update: false, remove: false };\n\t}\n\tif (!role.permission && !role.organization) {\n\t\treturn { update: false, remove: false };\n\t}\n\tif (role.permission?.super_user) {\n\t\treturn { update: true, remove: true };\n\t}\n\treturn { update: role.organization.update, remove: role.organization.delete };\n}\n\nexport function useOrganizationRolePermissions(orgId?: string): CRUV {\n\tconst { user } = useCloudAuth();\n\tconst { organizationId: orgIdFromRoute }: { organizationId: string } = useParams({ strict: false });\n\n\tif (isAdminMode(user)) {\n\t\treturn { create: true, remove: true, update: true, view: true };\n\t}\n\n\tconst role = user?.roles?.[orgId ?? orgIdFromRoute];\n\tif (!role || 'oauthProviders' in role) {\n\t\treturn { create: false, remove: false, update: false, view: false };\n\t}\n\tif (!role.permission && !role.organization?.roles) {\n\t\treturn { create: false, remove: false, update: false, view: false };\n\t}\n\tif (role.permission?.super_user) {\n\t\treturn { create: true, remove: true, update: true, view: true };\n\t}\n\tconst roles = role.organization.roles;\n\treturn { create: roles.create, remove: roles.delete, update: roles.update, view: roles.view };\n}\n\nexport function useOrganizationClusterPermissions(orgId?: string, clusterId?: string): CRUV {\n\tconst { user } = useCloudAuth();\n\tconst { organizationId: orgIdFromRoute, clusterId: clusterIdFromRoute }: {\n\t\torganizationId: string;\n\t\tclusterId: string;\n\t} = useParams({ strict: false });\n\n\treturn getOrganizationClusterPermissions(\n\t\tuser,\n\t\torgId ?? orgIdFromRoute,\n\t\tclusterId ?? clusterIdFromRoute,\n\t);\n}\n\nexport function getOrganizationClusterPermissions(user: User | null, orgId: string, clusterId: string): CRUV {\n\tif (isAdminMode(user)) {\n\t\treturn { create: true, remove: true, update: true, view: true };\n\t}\n\n\tconst role = user?.roles?.[orgId];\n\tif (!role || 'oauthProviders' in role) {\n\t\treturn { create: false, remove: false, update: false, view: false };\n\t}\n\tif (!role.permission && !role.organization?.clusters) {\n\t\treturn { create: false, remove: false, update: false, view: false };\n\t}\n\tif (role.permission?.super_user) {\n\t\treturn { create: true, remove: true, update: true, view: true };\n\t}\n\tconst specificRoles = role.organization.clusters.resources?.find(r => r.id === clusterId);\n\tconst genericRoles = role.organization.clusters;\n\treturn {\n\t\tcreate: genericRoles.create,\n\t\tremove: specificRoles ? specificRoles.delete : genericRoles.delete,\n\t\tupdate: specificRoles ? specificRoles.update : genericRoles.update,\n\t\tview: specificRoles ? specificRoles.view : genericRoles.view,\n\t};\n}\n\nexport function useOrganizationClusterInstancePermissions(orgId?: string, clusterId?: string): CRUV {\n\tconst { user } = useCloudAuth();\n\tconst { organizationId: orgIdFromRoute, clusterId: clusterIdFromRoute }: {\n\t\torganizationId: string;\n\t\tclusterId: string;\n\t} = useParams({ strict: false });\n\n\treturn getOrganizationClusterInstancePermissions(\n\t\tuser,\n\t\torgId ?? orgIdFromRoute,\n\t\tclusterId ?? clusterIdFromRoute,\n\t);\n}\n\nexport function getOrganizationClusterInstancePermissions(user: User | null, orgId: string, clusterId: string): CRUV {\n\tif (isAdminMode(user)) {\n\t\treturn { create: true, remove: true, update: true, view: true };\n\t}\n\n\tconst role = user?.roles?.[orgId];\n\tif (!role || 'oauthProviders' in role) {\n\t\treturn { create: false, remove: false, update: false, view: false };\n\t}\n\tif (!role.permission && !role.organization?.clusters) {\n\t\treturn { create: false, remove: false, update: false, view: false };\n\t}\n\tif (role.permission?.super_user) {\n\t\treturn { create: true, remove: true, update: true, view: true };\n\t}\n\tconst specificRoles = role.organization.clusters\n\t\t.resources?.find(r => r.id === clusterId)\n\t\t?.instances;\n\tconst genericRoles = role.organization.clusters;\n\treturn {\n\t\tcreate: specificRoles ? specificRoles.create : genericRoles.create,\n\t\tremove: specificRoles ? specificRoles.delete : genericRoles.delete,\n\t\tupdate: specificRoles ? specificRoles.update : genericRoles.update,\n\t\tview: specificRoles ? specificRoles.view : genericRoles.view,\n\t};\n}\n\nexport function useInstanceManagePermission(entityId?: EntityIds): boolean {\n\tconst { clusterId, instanceId }: { instanceId?: string; clusterId?: string } = useParams({ strict: false });\n\tconst { user } = useInstanceAuth(entityId ?? instanceId ?? clusterId);\n\tconst permission = user?.role?.permission;\n\tif (!permission) {\n\t\t// If we don't yet have record of their permission, deny access.\n\t\t// (We're probably still loading the user.)\n\t\treturn false;\n\t}\n\treturn permission.super_user === true;\n}\n\nexport function useInstanceBrowseManagePermission(entityId?: EntityIds): boolean {\n\tconst { clusterId, instanceId }: { instanceId?: string; clusterId?: string } = useParams({ strict: false });\n\tconst { user } = useInstanceAuth(entityId ?? instanceId ?? clusterId);\n\tconst permission = user?.role?.permission;\n\tif (!permission) {\n\t\t// If we don't yet have record of their permission, deny access.\n\t\t// (We're probably still loading the user.)\n\t\treturn false;\n\t}\n\treturn permission.super_user === true || permission.structure_user === true;\n}\n\nexport function useInstanceSchemaTablePermission(\n\tentityId: EntityIds | undefined,\n\tdatabaseName: string,\n\ttableName: string,\n\taction: LocalRolePermissionAction,\n): boolean {\n\tconst { clusterId, instanceId }: { instanceId?: string; clusterId?: string } = useParams({ strict: false });\n\tconst { user } = useInstanceAuth(entityId ?? instanceId ?? clusterId);\n\tconst permission = user?.role?.permission;\n\tif (!permission) {\n\t\t// If we don't yet have record of their permission, deny access.\n\t\t// (We're probably still loading the user.)\n\t\treturn false;\n\t}\n\tif (permission.super_user === true || permission.structure_user === true) {\n\t\treturn true;\n\t}\n\tconst specificPermission = permission[databaseName];\n\treturn specificPermission?.tables?.[tableName][action] === true;\n}\n\nexport function useInstanceSchemaTableAttributePermission(\n\tentityId: EntityIds | undefined,\n\tdatabaseName: string,\n\ttableName: string,\n\tattributeName: string,\n\taction: LocalRoleAttributePermissionAction,\n): boolean {\n\tconst { clusterId, instanceId }: { instanceId?: string; clusterId?: string } = useParams({ strict: false });\n\tconst { user } = useInstanceAuth(entityId ?? instanceId ?? clusterId);\n\tconst permission = user?.role?.permission;\n\tif (!permission) {\n\t\t// If we don't yet have record of their permission, deny access.\n\t\t// (We're probably still loading the user.)\n\t\treturn false;\n\t}\n\tif (permission.super_user === true || permission.structure_user === true) {\n\t\treturn true;\n\t}\n\tconst specificPermission = permission[databaseName];\n\tif (specificPermission?.tables?.[tableName][action] === true) {\n\t\treturn true;\n\t}\n\tconst table = specificPermission?.tables?.[tableName];\n\tconst attributePermission = ((table as LocalRolePermissionTable).attribute_permissions\n\t\t|| (table as LocalLegacyRolePermissionTable).attribute_restrictions).find(a => a.attribute_name === attributeName);\n\treturn attributePermission?.[action] === true;\n}\n","import { DiscordLogo } from '@/components/DiscordLogo';\nimport { MainLogo } from '@/components/MainLogo';\nimport { ThemeToggle } from '@/components/ThemeToggle';\nimport { NavigationMenu } from '@/components/ui/navigation/NavigationMenu';\nimport { NavigationMenuItem } from '@/components/ui/navigation/NavigationMenuItem';\nimport { NavigationMenuLink } from '@/components/ui/navigation/NavigationMenuLink';\nimport { NavigationMenuList } from '@/components/ui/navigation/NavigationMenuList';\nimport { Version } from '@/components/Version';\nimport { defaultInstanceRoute, isLocalStudio } from '@/config/constants';\nimport { useLogoutMutation } from '@/features/auth/hooks/useLogout';\nimport { useOverallAuth } from '@/hooks/useAuth';\nimport { useOrganizationPermissions, useOrganizationRolePermissions } from '@/hooks/usePermissions';\nimport { excludeFalsy } from '@/lib/arrays/excludeFalsy';\nimport { getDefaultSignedInCloudRouteForUser } from '@/lib/urls/getDefaultSignedInCloudRouteForUser';\nimport { Link, useNavigate, useParams, useRouter } from '@tanstack/react-router';\nimport {\n\tBookOpenTextIcon,\n\tBugIcon,\n\tBuildingIcon,\n\tHandshakeIcon,\n\tLogInIcon,\n\tLogOutIcon,\n\tMenu,\n\tReceiptIcon,\n\tUserIcon,\n\tUsersIcon,\n\tX,\n} from 'lucide-react';\nimport { ReactNode, useCallback, useMemo, useState } from 'react';\nimport { toast } from 'sonner';\n\nconst activeLinkProps = { className: 'text-foreground dark:text-white font-semibold' };\n\nexport function Navbar() {\n\tconst { mutate: signOut } = useLogoutMutation();\n\tconst navigate = useNavigate();\n\tconst { user } = useOverallAuth();\n\tconst router = useRouter();\n\tconst { organizationId }: { organizationId: string } = useParams({ strict: false });\n\tconst { update: canUpdateOrganization } = useOrganizationPermissions(organizationId);\n\tconst { view: showOrgUsersAndRoles } = useOrganizationRolePermissions(organizationId);\n\tconst showBilling = canUpdateOrganization;\n\n\tconst handleSignOut = useCallback(() => {\n\t\tsignOut(undefined, {\n\t\t\tonSuccess: async () => {\n\t\t\t\ttoast.success('Success', {\n\t\t\t\t\tdescription: 'You have been signed out successfully.',\n\t\t\t\t\taction: {\n\t\t\t\t\t\tlabel: 'Dismiss',\n\t\t\t\t\t\tonClick: () => toast.dismiss(),\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tvoid navigate({ to: '/sign-in' });\n\t\t\t\tvoid router.invalidate();\n\t\t\t},\n\t\t});\n\t}, [signOut, router, navigate]);\n\n\tconst menuItems: Array<MenuGroup | MenuItem> = useMemo(\n\t\t() =>\n\t\t\t[\n\t\t\t\t!isLocalStudio && {\n\t\t\t\t\tto: '/',\n\t\t\t\t\ticon: <BuildingIcon />,\n\t\t\t\t\ttext: 'Organizations',\n\t\t\t\t\ttextBreakpoint: 'xl',\n\t\t\t\t},\n\t\t\t\t!isLocalStudio && {\n\t\t\t\t\ttext: 'SubOrganizations',\n\t\t\t\t\titems: [\n\t\t\t\t\t\tshowOrgUsersAndRoles && {\n\t\t\t\t\t\t\tto: `/${organizationId}/roles`,\n\t\t\t\t\t\t\ticon: <HandshakeIcon />,\n\t\t\t\t\t\t\ttext: 'Roles',\n\t\t\t\t\t\t\ttextBreakpoint: 'lg',\n\t\t\t\t\t\t},\n\t\t\t\t\t\tshowOrgUsersAndRoles && {\n\t\t\t\t\t\t\tto: `/${organizationId}/users`,\n\t\t\t\t\t\t\ticon: <UsersIcon />,\n\t\t\t\t\t\t\ttext: 'Users',\n\t\t\t\t\t\t\ttextBreakpoint: 'lg',\n\t\t\t\t\t\t},\n\t\t\t\t\t\tshowBilling && {\n\t\t\t\t\t\t\tto: `/${organizationId}/billing`,\n\t\t\t\t\t\t\ticon: <ReceiptIcon />,\n\t\t\t\t\t\t\ttext: 'Billing',\n\t\t\t\t\t\t\ttextBreakpoint: 'xl',\n\t\t\t\t\t\t},\n\t\t\t\t\t].filter(excludeFalsy),\n\t\t\t\t},\n\t\t\t\t!isLocalStudio && {\n\t\t\t\t\tto: '/profile',\n\t\t\t\t\ticon: <UserIcon />,\n\t\t\t\t\ttext: 'Profile',\n\t\t\t\t\ttextBreakpoint: 'xl',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tto: 'https://docs.harperdb.io/docs',\n\t\t\t\t\ttarget: '_blank',\n\t\t\t\t\ticon: <BookOpenTextIcon />,\n\t\t\t\t\ttext: 'Docs',\n\t\t\t\t\ttextBreakpoint: isLocalStudio ? 'md' : 'xl',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tto: 'https://github.com/HarperFast/studio/issues',\n\t\t\t\t\ttarget: '_blank',\n\t\t\t\t\ticon: <BugIcon />,\n\t\t\t\t\ttext: 'Report an Issue',\n\t\t\t\t\ttextBreakpoint: isLocalStudio ? 'lg' : 'xl',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tto: 'https://discord.gg/VzZuaw3Xay',\n\t\t\t\t\ttarget: '_blank',\n\t\t\t\t\ticon: <DiscordLogo />,\n\t\t\t\t\ttext: 'Discord',\n\t\t\t\t\ttextBreakpoint: isLocalStudio ? 'lg' : 'xl',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tonClick: handleSignOut,\n\t\t\t\t\ticon: <LogOutIcon />,\n\t\t\t\t\ttext: 'Sign Out',\n\t\t\t\t\ttextBreakpoint: isLocalStudio ? 'md' : 'xl',\n\t\t\t\t},\n\t\t\t].filter(excludeFalsy) satisfies Array<MenuGroup | MenuItem>,\n\t\t[organizationId, showBilling, showOrgUsersAndRoles, handleSignOut],\n\t);\n\n\tif (!user) {\n\t\treturn <AnonymousNav />;\n\t}\n\treturn (\n\t\t<>\n\t\t\t<MobileNav menuItems={menuItems} />\n\t\t\t<DesktopNav menuItems={menuItems} />\n\t\t</>\n\t);\n}\n\ninterface MenuGroup {\n\ttext: string;\n\titems: MenuItem[];\n}\n\ninterface MenuItem {\n\tto?: string;\n\tonClick?: () => void;\n\ticon: ReactNode;\n\ttext: string;\n\ttarget?: string;\n\ttextBreakpoint?: string;\n}\n\nfunction isMenuGroup(item: MenuGroup | MenuItem): item is MenuGroup {\n\treturn (item as MenuGroup).items !== undefined;\n}\n\nfunction AnonymousNav() {\n\treturn (\n\t\t<div className=\"flex items-center justify-between\">\n\t\t\t<div className=\"inline-block\">\n\t\t\t\t<Link to=\"/sign-in\">\n\t\t\t\t\t<MainLogo />\n\t\t\t\t</Link>\n\t\t\t\t<Version />\n\t\t\t</div>\n\t\t\t<NavigationMenu>\n\t\t\t\t<NavigationMenuList className=\"text-muted-foreground dark:text-grey-400\">\n\t\t\t\t\t<NavigationMenuItem>\n\t\t\t\t\t\t<NavigationMenuLink asChild>\n\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\tto=\"https://docs.harperdb.io/docs\"\n\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\trel=\"noreferrer noopener\"\n\t\t\t\t\t\t\t\tclassName=\"flex-row items-center\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<BookOpenTextIcon /> <span className=\"hidden md:inline-block\">Docs</span>\n\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t</NavigationMenuLink>\n\t\t\t\t\t</NavigationMenuItem>\n\t\t\t\t\t<NavigationMenuItem>\n\t\t\t\t\t\t<ThemeToggle />\n\t\t\t\t\t</NavigationMenuItem>\n\t\t\t\t\t<NavigationMenuItem>\n\t\t\t\t\t\t<NavigationMenuLink asChild>\n\t\t\t\t\t\t\t<Link to=\"/sign-in\" className=\"flex-row items-center\" activeProps={activeLinkProps}>\n\t\t\t\t\t\t\t\t<LogInIcon /> Sign In\n\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t</NavigationMenuLink>\n\t\t\t\t\t</NavigationMenuItem>\n\t\t\t\t</NavigationMenuList>\n\t\t\t</NavigationMenu>\n\t\t</div>\n\t);\n}\n\nfunction DesktopNav({ menuItems }: { menuItems: Array<MenuGroup | MenuItem> }) {\n\tconst { user } = useOverallAuth();\n\tconst defaultCloudRoute = getDefaultSignedInCloudRouteForUser(user);\n\n\treturn (\n\t\t<div className=\"hidden md:block\">\n\t\t\t<div className=\"flex items-center justify-between\">\n\t\t\t\t<div className=\"inline-block\">\n\t\t\t\t\t<Link to={isLocalStudio ? defaultInstanceRoute : defaultCloudRoute}>\n\t\t\t\t\t\t<MainLogo />\n\t\t\t\t\t</Link>\n\t\t\t\t\t<Version />\n\t\t\t\t</div>\n\t\t\t\t<NavigationMenu>\n\t\t\t\t\t<NavigationMenuList className=\"text-muted-foreground dark:text-grey-400\">\n\t\t\t\t\t\t{menuItems.map(menuItem =>\n\t\t\t\t\t\t\tisMenuGroup(menuItem)\n\t\t\t\t\t\t\t\t? !!menuItem.items.length && (\n\t\t\t\t\t\t\t\t\t<div key={menuItem.text} className=\"bg-muted dark:bg-black rounded-2xl flex\">\n\t\t\t\t\t\t\t\t\t\t{menuItem.items.map(innerMenuItem => (\n\t\t\t\t\t\t\t\t\t\t\t<DesktopNavItem key={innerMenuItem.text} menuItem={innerMenuItem} />\n\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t: <DesktopNavItem key={menuItem.text} menuItem={menuItem} />\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<NavigationMenuItem>\n\t\t\t\t\t\t\t<ThemeToggle />\n\t\t\t\t\t\t</NavigationMenuItem>\n\t\t\t\t\t</NavigationMenuList>\n\t\t\t\t</NavigationMenu>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nfunction DesktopNavItem({ menuItem }: { menuItem: MenuItem }) {\n\treturn (\n\t\t<NavigationMenuItem className=\"text-muted-foreground dark:text-gray-400 hover:text-foreground dark:hover:text-white\">\n\t\t\t<NavigationMenuLink asChild>\n\t\t\t\t<Link\n\t\t\t\t\tto={menuItem.to}\n\t\t\t\t\tonClick={menuItem.onClick}\n\t\t\t\t\tclassName=\"flex-row items-center\"\n\t\t\t\t\ttarget={menuItem.target}\n\t\t\t\t\tactiveProps={menuItem.to ? activeLinkProps : undefined}\n\t\t\t\t>\n\t\t\t\t\t{menuItem.icon}\n\t\t\t\t\t<span className={`hidden ${menuItem.textBreakpoint}:inline-block`}>{menuItem.text}</span>\n\t\t\t\t\t<span className={`${menuItem.textBreakpoint}:hidden`}>&nbsp;</span>\n\t\t\t\t</Link>\n\t\t\t</NavigationMenuLink>\n\t\t</NavigationMenuItem>\n\t);\n}\n\nfunction MobileNav({ menuItems }: { menuItems: Array<MenuGroup | MenuItem> }) {\n\tconst { user } = useOverallAuth();\n\tconst defaultCloudRoute = getDefaultSignedInCloudRouteForUser(user);\n\tconst [isMenuOpen, setIsMenuOpen] = useState(false);\n\tconst toggleMenu = useCallback(() => setIsMenuOpen(open => !open), []);\n\tconst closeMenu = useCallback(() => setIsMenuOpen(false), []);\n\n\treturn (\n\t\t<div className=\"md:hidden\" id=\"mobile-menu\">\n\t\t\t<div className=\"flex items-center justify-between\">\n\t\t\t\t<Link to={isLocalStudio ? defaultInstanceRoute : defaultCloudRoute}>\n\t\t\t\t\t<MainLogo />\n\t\t\t\t</Link>\n\t\t\t\t<Version />\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName=\"shadow-xs text-muted-foreground dark:text-grey-400 hover:text-foreground dark:hover:text-white hover:bg-muted dark:hover:bg-black-dark\"\n\t\t\t\t\tonClick={toggleMenu}\n\t\t\t\t>\n\t\t\t\t\t<span className=\"sr-only\">{isMenuOpen ? 'Close menu' : 'Open menu'}</span>\n\t\t\t\t\t{isMenuOpen ? <X /> : <Menu />}\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t\t<div\n\t\t\t\tclassName={`${\n\t\t\t\t\tisMenuOpen ? 'fixed' : 'hidden'\n\t\t\t\t} top-40 bottom-0 left-0 right-0 bg-foreground/20 dark:bg-black-dark dark:opacity-70`}\n\t\t\t\tonClick={closeMenu}\n\t\t\t>\n\t\t\t</div>\n\t\t\t<div\n\t\t\t\tclassName={`${\n\t\t\t\t\tisMenuOpen ? 'block' : 'hidden'\n\t\t\t\t} md:hidden z-50 space-y-1 pb-3 bg-card border-b border-border dark:bg-black-dark dark:border-none absolute left-0 top-full w-full rounded-b-md`}\n\t\t\t>\n\t\t\t\t<div className=\"flex justify-end px-3 pt-2\">\n\t\t\t\t\t<ThemeToggle />\n\t\t\t\t</div>\n\t\t\t\t{menuItems.map(menuItem =>\n\t\t\t\t\tisMenuGroup(menuItem)\n\t\t\t\t\t\t? !!menuItem.items.length && (\n\t\t\t\t\t\t\t<div key={menuItem.text} className=\"bg-muted dark:bg-black pl-10 pr-2 py-2\">\n\t\t\t\t\t\t\t\t{menuItem.items.map(innerMenuItem => (\n\t\t\t\t\t\t\t\t\t<MobileNavItem key={innerMenuItem.text} menuItem={innerMenuItem} onClick={closeMenu} />\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)\n\t\t\t\t\t\t: <MobileNavItem key={menuItem.text} menuItem={menuItem} onClick={closeMenu} />\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nfunction MobileNavItem({ menuItem, onClick }: { menuItem: MenuItem; onClick: () => void }) {\n\tconst linkOnClick = useCallback(() => {\n\t\tmenuItem.onClick?.();\n\t\tonClick();\n\t}, [menuItem, onClick]);\n\treturn (\n\t\t<Link\n\t\t\tto={menuItem.to}\n\t\t\tonClick={linkOnClick}\n\t\t\ttarget={menuItem.target}\n\t\t\tclassName=\"flex flex-row px-3 py-2 text-base font-medium rounded-md text-muted-foreground dark:text-gray-400 hover:text-foreground dark:hover:text-white\"\n\t\t\tactiveProps={menuItem.to ? activeLinkProps : undefined}\n\t\t>\n\t\t\t{menuItem.icon}\n\t\t\t<span className=\"ml-4\">\n\t\t\t\t{menuItem.text}\n\t\t\t</span>\n\t\t</Link>\n\t);\n}\n","import { Navbar } from '@/components/Navbar';\nimport { Outlet } from '@tanstack/react-router';\n\nexport function AuthLayout() {\n\treturn (\n\t\t<>\n\t\t\t<header className=\"fixed top-0 z-40 w-full h-20 p-4 bg-gradient-to-r from-violet-100 to-white border-b border-violet-200 dark:from-purple-950 dark:to-zinc-900 dark:border-purple-950 md:px-12\">\n\t\t\t\t<Navbar />\n\t\t\t</header>\n\t\t\t<div className=\"pt-20 h-screen grid grid-cols-1 md:grid-cols-2\">\n\t\t\t\t<section\n\t\t\t\t\taria-label=\"Harper Fabric overview\"\n\t\t\t\t\tclassName=\"items-center justify-center hidden text-white md:flex px-6 fabricSignupTextContainer\"\n\t\t\t\t>\n\t\t\t\t\t<img\n\t\t\t\t\t\tclassName=\"object-scale-down max-h-[calc(100vh-80px-40px)] min-h-115\"\n\t\t\t\t\t\tsrc=\"/fabric-signup-text.png\"\n\t\t\t\t\t\talt=\"One Runtime: App, database, Cache and Messaging. Distributed by design, free to deploy, and live in minutes. Deploy!\"\n\t\t\t\t\t/>\n\t\t\t\t</section>\n\t\t\t\t<main className=\"overflow-y-auto px-6 bg-white dark:bg-linear-(--black-dark-gradient) border-l border-border dark:border-none\">\n\t\t\t\t\t<div className=\"min-h-full flex items-start justify-center py-12\">\n\t\t\t\t\t\t<Outlet />\n\t\t\t\t\t</div>\n\t\t\t\t</main>\n\t\t\t</div>\n\t\t</>\n\t);\n}\n","import { useEffect } from 'react';\nimport { loadReoScript, ReoClient } from 'reodotdev';\n\nexport let reoClient: ReoClient | undefined;\n\nexport function useReo() {\n\tuseEffect(() => {\n\t\tif (import.meta.env.VITE_REO_DEV_CLIENT_ID && import.meta.env.VITE_REO_DEV_CLIENT_ID !== '0') {\n\t\t\tloadReoScript({ clientID: import.meta.env.VITE_REO_DEV_CLIENT_ID })\n\t\t\t\t.then((Reo) => {\n\t\t\t\t\tReo?.init?.({ clientID: import.meta.env.VITE_REO_DEV_CLIENT_ID });\n\t\t\t\t\treturn reoClient = Reo;\n\t\t\t\t});\n\t\t}\n\t}, []);\n}\n","const commonProviders = [\n\t'gmail.com',\n\t'yahoo.com',\n\t'hotmail.com',\n\t'outlook.com',\n\t'icloud.com',\n\t'aol.com',\n\t'protonmail.com',\n\t'mail.com',\n\t'zoho.com',\n\t'yandex.com',\n\t'gmx.com',\n\t'live.com',\n\t'msn.com',\n\t'me.com',\n\t'inbox.com',\n];\n\nexport function parseCompanyFromEmail(email: string): string | null {\n\tif (!email || !email.includes('@')) {\n\t\treturn null;\n\t}\n\n\tconst domain = email.split('@').pop() || '';\n\tif (!domain) {\n\t\treturn null;\n\t}\n\n\t// Check if the domain is a common provider or a subdomain of a common provider\n\tfor (const provider of commonProviders) {\n\t\tif (domain === provider || domain.endsWith('.' + provider)) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\treturn domain;\n}\n","import { currentUserQueryKey, getCurrentUser } from '@/features/auth/queries/getCurrentUser';\nimport { authStore, OverallAppSignIn } from '@/features/auth/store/authStore';\nimport { loginSuccessDatadogAction } from '@/integrations/datadog/datadog';\nimport { reoClient } from '@/integrations/reo/reo';\nimport { parseCompanyFromEmail } from '@/lib/string/parseCompanyFromEmail';\nimport { getDefaultSignedInCloudRouteForUser } from '@/lib/urls/getDefaultSignedInCloudRouteForUser';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { Link, useNavigate, useRouter, useSearch } from '@tanstack/react-router';\nimport { useEffect } from 'react';\nimport { toast } from 'sonner';\n\nlet checking: Promise<void> | null = null;\n\nexport function CheckOAuth() {\n\tconst navigate = useNavigate();\n\tconst router = useRouter();\n\tconst queryClient = useQueryClient();\n\tconst { redirect } = useSearch({ strict: false });\n\n\tuseEffect(() => {\n\t\tif (checking) {\n\t\t\treturn;\n\t\t}\n\t\tchecking = (async function() {\n\t\t\tconst user = await getCurrentUser().catch(() => null);\n\t\t\tif (!user) {\n\t\t\t\ttoast.error('We were not able to verify your sign-in. Please try signing in again.', {\n\t\t\t\t\tduration: 10_000,\n\t\t\t\t});\n\t\t\t\tawait navigate({ to: '/sign-in' });\n\t\t\t} else {\n\t\t\t\tauthStore.setUserForEntity(OverallAppSignIn, user);\n\t\t\t\tconst defaultCloudRoute = getDefaultSignedInCloudRouteForUser(user);\n\n\t\t\t\tloginSuccessDatadogAction(user);\n\n\t\t\t\tconst company = parseCompanyFromEmail(user.email);\n\t\t\t\treoClient?.identify?.({\n\t\t\t\t\tusername: user.email,\n\t\t\t\t\ttype: 'email',\n\t\t\t\t\t...(company ? { company } : {}),\n\t\t\t\t});\n\t\t\t\tawait queryClient.invalidateQueries({ queryKey: currentUserQueryKey, refetchType: 'none' });\n\t\t\t\tawait router.invalidate();\n\t\t\t\tawait navigate({ to: redirect?.startsWith('/') ? redirect : defaultCloudRoute });\n\t\t\t}\n\n\t\t\tchecking = null;\n\t\t})();\n\t\t// We only want this to fire once.\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, []);\n\n\treturn (\n\t\t<div role=\"status\" aria-live=\"polite\" className=\"text-foreground dark:text-white w-lg flex flex-col gap-4\">\n\t\t\t<h1 className=\"text-3xl font-light\">\n\t\t\t\t<span\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tclassName=\"text-2xl animate-flower-dance mr-4\"\n\t\t\t\t\ttitle=\"Loading\"\n\t\t\t\t>\n\t\t\t\t\t🌼\n\t\t\t\t</span>\n\t\t\t\tChecking...\n\t\t\t</h1>\n\n\t\t\t<div className=\"underline flex gap-4\">\n\t\t\t\t<Link\n\t\t\t\t\tclassName=\"text-sm opacity-50 text-muted-foreground hover:text-foreground dark:text-inherit dark:hover:text-blue-300\"\n\t\t\t\t\tto=\"/sign-in\"\n\t\t\t\t>\n\t\t\t\t\tTry signing in again\n\t\t\t\t</Link>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n","'use client';\n\nimport * as TooltipPrimitive from '@radix-ui/react-tooltip';\nimport * as React from 'react';\n\nimport { cn } from '@/lib/cn';\n\nfunction TooltipProvider({\n\tdelayDuration = 0,\n\t...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n\treturn (\n\t\t<TooltipPrimitive.Provider\n\t\t\tdata-slot=\"tooltip-provider\"\n\t\t\tdelayDuration={delayDuration}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nfunction Tooltip({\n\t...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n\treturn (\n\t\t<TooltipProvider>\n\t\t\t<TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n\t\t</TooltipProvider>\n\t);\n}\n\nfunction TooltipTrigger({\n\t...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n\treturn <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />;\n}\n\ntype TooltipContentProps = React.ComponentProps<typeof TooltipPrimitive.Content> & {\n\tarrowClassName?: string;\n};\n\nfunction TooltipContent({\n\tclassName,\n\tsideOffset = 0,\n\tarrowClassName,\n\tchildren,\n\t...props\n}: TooltipContentProps) {\n\treturn (\n\t\t<TooltipPrimitive.Portal>\n\t\t\t<TooltipPrimitive.Content\n\t\t\t\tdata-slot=\"tooltip-content\"\n\t\t\t\tsideOffset={sideOffset}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'bg-primary text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance',\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t\t<TooltipPrimitive.Arrow\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t'bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]',\n\t\t\t\t\t\tarrowClassName,\n\t\t\t\t\t)}\n\t\t\t\t/>\n\t\t\t</TooltipPrimitive.Content>\n\t\t</TooltipPrimitive.Portal>\n\t);\n}\n\nexport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };\n","const capitalizedCache = new Map<string, string>();\n\nexport function capitalizeWords(name: string): string {\n\tif (!name) {\n\t\treturn '';\n\t}\n\n\tif (capitalizedCache.has(name)) {\n\t\treturn capitalizedCache.get(name) as string;\n\t}\n\n\t// Normalize separators to single spaces and trim\n\tconst s = name\n\t\t.replace(/[-_]+/g, ' ')\n\t\t.replace(/\\s+/g, ' ')\n\t\t.trim();\n\tif (!s) {\n\t\tcapitalizedCache.set(name, '');\n\t\treturn '';\n\t}\n\n\t// Split into tokens handling camelCase/PascalCase, acronyms, and numbers\n\t// Pattern parts:\n\t// - [A-Z]+(?=[A-Z][a-z]) captures acronym at the start of a PascalCase word (e.g., \"APIResponse\" -> \"API\", \"Response\")\n\t// - [A-Z]?[a-z]+ captures normal words (camel/pascal or lowercase)\n\t// - [A-Z]+ captures remaining all-caps (acronyms)\n\t// - [0-9]+ captures numbers\n\tconst baseTokens = s.match(/([A-Z]+(?=[A-Z][a-z])|[A-Z]?[a-z]+|[A-Z]+|[0-9]+)/g);\n\tif (!baseTokens) {\n\t\tcapitalizedCache.set(name, '');\n\t\treturn '';\n\t}\n\n\t// Merge plural 's' following an acronym (length>=2), e.g., [\"ID\", \"s\"] -> [\"IDs\"]\n\tconst tokens: string[] = [];\n\tfor (let i = 0; i < baseTokens.length; i++) {\n\t\tconst token = baseTokens[i];\n\t\tconst next = i + 1 < baseTokens.length ? baseTokens[i + 1] : undefined;\n\t\tif (\n\t\t\t// Case 1: full acronym then plural 's' as separate token -> merge\n\t\t\t/^[A-Z]{2,}$/.test(token)\n\t\t\t&& next\n\t\t\t&& /[A-Z]*s$/.test(next)\n\t\t) {\n\t\t\ttokens.push(token + next);\n\t\t\ti++; // skip the 's'\n\t\t} else if (\n\t\t\t// Case 2: single leading capital followed by capital + 's' (e.g., 'I' + 'Ds') -> merge to 'IDs'\n\t\t\t/^[A-Z]$/.test(token)\n\t\t\t&& next !== undefined\n\t\t\t&& /^[A-Z]s$/.test(next)\n\t\t) {\n\t\t\ttokens.push(token + next);\n\t\t\ti++; // skip merged next\n\t\t} else {\n\t\t\ttokens.push(token);\n\t\t}\n\t}\n\n\tconst words = tokens.map(capitalizeTokenWordsAppropriately);\n\n\tconst result = words.join(' ');\n\tcapitalizedCache.set(name, result);\n\treturn result;\n}\n\nfunction capitalizeTokenWordsAppropriately(t: string): string {\n\tif (/^[A-Z]{2,3}s?$/.test(t)) {\n\t\t// Acronym (e.g., ID, API) possibly with plural 's' -> keep as is\n\t\treturn t;\n\t}\n\tif (/^[0-9]+$/.test(t)) {\n\t\t// numbers unchanged\n\t\treturn t;\n\t}\n\t// Normal word: capitalize first letter, lowercase rest\n\treturn t.charAt(0).toUpperCase() + t.slice(1).toLowerCase();\n}\n","import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';\nimport { isLocalStudio } from '@/config/constants';\nimport { Cluster, Instance, Organization } from '@/integrations/api/api.patch';\nimport { capitalizeWords } from '@/lib/string/capitalizeWords';\nimport { Link, useLocation, useRouteContext } from '@tanstack/react-router';\nimport { HomeIcon } from 'lucide-react';\nimport { useMemo } from 'react';\n\nexport function Breadcrumbs({ restartRequired }: { restartRequired?: boolean }) {\n\tconst location = useLocation();\n\n\tconst { organization, instance, cluster }: {\n\t\torganization?: Organization;\n\t\tinstance?: Instance;\n\t\tcluster?: Cluster;\n\t} = useRouteContext({ strict: false });\n\tconst targetNoun = (instance || isLocalStudio) ? 'Instance' : 'Cluster';\n\n\tconst breadcrumbs = useMemo(() => {\n\t\tconst routeHistory = location.pathname.split('/')\n\t\t\t.filter((x) => x && x.length > 0);\n\n\t\tconst breadcrumbs = [\n\t\t\t<Link key=\"home\" to=\"/\">\n\t\t\t\t<HomeIcon aria-hidden=\"true\" className=\"size-5 shrink-0\" />\n\t\t\t\t<span className=\"sr-only\">Home</span>\n\t\t\t</Link>,\n\t\t];\n\n\t\tfor (let index = 0; index < routeHistory.length; index++) {\n\t\t\tconst route = routeHistory[index];\n\t\t\tif (route === 'instance') {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlet path = `/${routeHistory.slice(0, index + 1).join('/')}`;\n\t\t\tlet name = capitalizeWords(route);\n\t\t\tif (route === 'databases' && routeHistory.length === index + 3) {\n\t\t\t\tname = routeHistory[index + 2];\n\t\t\t\tindex += 2;\n\t\t\t} else if (name.startsWith('Org ')) {\n\t\t\t\tname = organization?.name || 'Org';\n\t\t\t} else if (name.startsWith('Clu ')) {\n\t\t\t\tname = cluster?.name || 'Cluster';\n\t\t\t\tif (routeHistory[index + 1] === 'instance') {\n\t\t\t\t\tpath += '/instances';\n\t\t\t\t}\n\t\t\t} else if (name.startsWith('Ins ')) {\n\t\t\t\tname = instance?.name?.split('.')?.shift() || 'Instance';\n\t\t\t} else if (name === 'Apis') {\n\t\t\t\tname = 'APIs';\n\t\t\t}\n\n\t\t\tbreadcrumbs.push(\n\t\t\t\t<svg\n\t\t\t\t\tkey={breadcrumbs.length + '-dash'}\n\t\t\t\t\tfill=\"currentColor\"\n\t\t\t\t\tviewBox=\"0 0 20 20\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tclassName=\"size-5 shrink-0 text-grey\"\n\t\t\t\t>\n\t\t\t\t\t<path d=\"M5.555 17.776l8-16 .894.448-8 16-.894-.448z\" />\n\t\t\t\t</svg>,\n\t\t\t\t<Link\n\t\t\t\t\tkey={path}\n\t\t\t\t\tto={path}\n\t\t\t\t\tclassName=\"text-xs md:text-sm font-medium hover:text-grey truncate max-w-48\"\n\t\t\t\t>\n\t\t\t\t\t{name}\n\t\t\t\t</Link>,\n\t\t\t);\n\t\t}\n\n\t\treturn breadcrumbs;\n\t}, [location.pathname, cluster?.name, instance?.name, organization?.name]);\n\n\treturn (\n\t\t<div role=\"list\" className=\"flex items-center space-x-2 xl:space-x-4 sm:max-w-9/10 max-w-[calc(100%-56px)]\">\n\t\t\t{...breadcrumbs}\n\t\t\t{restartRequired && (\n\t\t\t\t<Tooltip>\n\t\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t\t<div className=\"text-xs italic text-muted-foreground\">\n\t\t\t\t\t\t\t* Restart <span className=\"hidden lg:inline-block\">Requested</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</TooltipTrigger>\n\t\t\t\t\t<TooltipContent side=\"bottom\">\n\t\t\t\t\t\tThis {targetNoun} is requesting a restart, when convenient, to apply your latest changes.\n\t\t\t\t\t\t<br />You can do this from the Apps or Config pages.\n\t\t\t\t\t</TooltipContent>\n\t\t\t\t</Tooltip>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","import { FormProvider } from 'react-hook-form';\n\nexport const Form = FormProvider;\n","import { createContext } from 'react';\nimport { FieldPath, FieldValues } from 'react-hook-form';\n\nexport type FormFieldContextValue<\n\tTFieldValues extends FieldValues = FieldValues,\n\tTName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n> = {\n\tname: TName;\n};\nexport const FormFieldContext = createContext<FormFieldContextValue>({} as FormFieldContextValue);\n","import { createContext } from 'react';\n\ntype FormItemContextValue = {\n\tid: string;\n};\nexport const FormItemContext = createContext<FormItemContextValue>({} as FormItemContextValue);\n","import { FormFieldContext } from '@/components/ui/form/formFieldContext';\nimport { FormItemContext } from '@/components/ui/form/formItemContext';\nimport { useContext } from 'react';\nimport { useFormContext, useFormState } from 'react-hook-form';\n\nexport function useFormField() {\n\tconst fieldContext = useContext(FormFieldContext);\n\tconst itemContext = useContext(FormItemContext);\n\tconst { getFieldState } = useFormContext();\n\tconst formState = useFormState({ name: fieldContext.name });\n\tconst fieldState = getFieldState(fieldContext.name, formState);\n\n\tif (!fieldContext) {\n\t\tthrow new Error('useFormField should be used within <FormField>');\n\t}\n\n\tconst { id } = itemContext;\n\n\treturn {\n\t\tid,\n\t\tname: fieldContext.name,\n\t\tformItemId: `${id}-form-item`,\n\t\tformDescriptionId: `${id}-form-item-description`,\n\t\tformMessageId: `${id}-form-item-message`,\n\t\t...fieldState,\n\t};\n}\n","import { useFormField } from '@/components/ui/form/useFormField';\nimport { Slot } from '@radix-ui/react-slot';\nimport { ComponentProps } from 'react';\n\nexport function FormControl({ ...props }: ComponentProps<typeof Slot>) {\n\tconst { error, formItemId, formDescriptionId, formMessageId } = useFormField();\n\n\treturn (\n\t\t<Slot\n\t\t\tdata-slot=\"form-control\"\n\t\t\tid={formItemId}\n\t\t\taria-describedby={!error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`}\n\t\t\taria-invalid={!!error}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n","import { FormFieldContext as FormFieldContext1 } from '@/components/ui/form/formFieldContext';\nimport { Controller, ControllerProps, FieldPath, FieldValues } from 'react-hook-form';\n\nexport function FormField<\n\tTFieldValues extends FieldValues = FieldValues,\n\tTName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n>({\n\t...props\n}: ControllerProps<TFieldValues, TName>) {\n\treturn (\n\t\t<FormFieldContext1 value={{ name: props.name }}>\n\t\t\t<Controller {...props} />\n\t\t</FormFieldContext1>\n\t);\n}\n","import { FormItemContext as FormItemContext1 } from '@/components/ui/form/formItemContext';\nimport { cn } from '@/lib/cn';\nimport { ComponentProps, useId } from 'react';\n\nexport function FormItem({ className, ...props }: ComponentProps<'div'>) {\n\tconst id = useId();\n\n\treturn (\n\t\t<FormItemContext1 value={{ id }}>\n\t\t\t<div data-slot=\"form-item\" className={cn('grid gap-2', className)} {...props} />\n\t\t</FormItemContext1>\n\t);\n}\n","'use client';\n\nimport * as LabelPrimitive from '@radix-ui/react-label';\nimport * as React from 'react';\n\nimport { cn } from '@/lib/cn';\n\nfunction Label({\n\tclassName,\n\t...props\n}: React.ComponentProps<typeof LabelPrimitive.Root>) {\n\treturn (\n\t\t<LabelPrimitive.Root\n\t\t\tdata-slot=\"label\"\n\t\t\tclassName={cn(\n\t\t\t\t'text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport { Label };\n","import { useFormField } from '@/components/ui/form/useFormField';\nimport { Label } from '@/components/ui/label';\nimport { cn } from '@/lib/cn';\nimport * as LabelPrimitive from '@radix-ui/react-label';\nimport { ComponentProps } from 'react';\n\nexport function FormLabel({ className, ...props }: ComponentProps<typeof LabelPrimitive.Root>) {\n\tconst { error, formItemId } = useFormField();\n\n\treturn (\n\t\t<Label\n\t\t\tdata-slot=\"form-label\"\n\t\t\tdata-error={!!error}\n\t\t\tclassName={cn('data-[error=true]:text-destructive', className)}\n\t\t\thtmlFor={formItemId}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n","import { useFormField } from '@/components/ui/form/useFormField';\nimport { cn } from '@/lib/cn';\nimport { ComponentProps } from 'react';\n\nexport function FormMessage({ className, ...props }: ComponentProps<'p'>) {\n\tconst { error, formMessageId } = useFormField();\n\tconst body = error ? String(error?.message) : props.children;\n\n\tif (!body) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<p data-slot=\"form-message\" id={formMessageId} className={cn('text-destructive text-sm', className)} {...props}>\n\t\t\t{body}\n\t\t</p>\n\t);\n}\n","import * as React from 'react';\n\nimport { cn } from '@/lib/cn';\n\nfunction Input({ className, type, ...props }: React.ComponentProps<'input'>) {\n\treturn (\n\t\t<input\n\t\t\ttype={type}\n\t\t\tdata-slot=\"input\"\n\t\t\tclassName={cn(\n\t\t\t\t`border-input file:text-foreground placeholder:text-muted-foreground selection:bg-purple\n selection:text-primary-foreground\n dark:aria-invalid:outline-destructive dark:aria-invalid:ring-destructive/50 ring-ring/10\n dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 aria-invalid:outline-destructive/60\n aria-invalid:ring-destructive/20 aria-invalid:border-destructive/60 dark:aria-invalid:border-destructive\n flex h-9 w-full min-w-0 rounded-md border bg-white text-foreground dark:bg-grey-700 dark:text-white px-3 py-1 text-base\n file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium\n focus-visible:ring-1 focus-visible:outline-none focus-visible:ring-purple disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\n aria-invalid:focus-visible:ring-[1px] aria-invalid:focus-visible:outline-none md:text-sm dark:aria-invalid:focus-visible:ring-1`,\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport { Input };\n","export const activeClusterStatuses = ['RUNNING'];\nexport const deletedClusterStatuses = ['TERMINATING', 'TERMINATED', 'REMOVED'];\n","export function calculateCreateClusterDeepLink() {\n\t// NOTE: This is also embedded in public/running.js\n\treturn 'https://fabric.harper.fast/#/?createCluster=' + encodeURIComponent(JSON.stringify({\n\t\tdeploymentDescription: 'Self-Hosted',\n\t\tperformanceDescription: 'Self Supported and Managed',\n\t\tinstances: [\n\t\t\t{\n\t\t\t\tsecure: String(location.protocol === 'https:'),\n\t\t\t\tfqdn: location.hostname,\n\t\t\t\tport: parseInt(location.port, 10),\n\t\t\t},\n\t\t],\n\t}));\n}\n","import { forceBasicAuth, isLocalStudio } from '@/config/constants';\nimport { getInstanceClient } from '@/config/getInstanceClient';\nimport { InstanceClientIdConfig } from '@/config/instanceClientConfig';\nimport { authStore } from '@/features/auth/store/authStore';\nimport { LocalUser } from '@/integrations/api/api.patch';\nimport { getInstanceUserInfo } from '@/integrations/api/instance/status/getInstanceUserInfo';\nimport { useMutation } from '@tanstack/react-query';\nimport { AxiosInstance } from 'axios';\n\ninterface InstanceLoginCredentials extends InstanceClientIdConfig {\n\tusername: string;\n\tpassword: string;\n}\n\nexport interface LoginInfoResponse {\n\tmessage: string;\n\tuser: LocalUser;\n\tinstanceClient?: AxiosInstance;\n}\n\nexport async function onInstanceLoginSubmit({\n\tusername,\n\tpassword,\n\tinstanceClient,\n\tentityId,\n}: InstanceLoginCredentials): Promise<LoginInfoResponse> {\n\tconst auth = {\n\t\tusername,\n\t\tpassword,\n\t};\n\tif (authStore.checkForBasicAuth(entityId)) {\n\t\tinstanceClient.defaults.auth = auth;\n\t\tinstanceClient.defaults.withCredentials = false;\n\t}\n\n\tconst { data: { message } } = await instanceClient.post('/', {\n\t\toperation: 'login',\n\t\tusername,\n\t\tpassword,\n\t});\n\n\tif (!forceBasicAuth && !authStore.checkForBasicAuth(entityId)) {\n\t\t// Attempt to use the login with session storage only.\n\t\ttry {\n\t\t\tconst user = await getInstanceUserInfo({ instanceClient });\n\t\t\treturn {\n\t\t\t\tmessage,\n\t\t\t\tuser,\n\t\t\t};\n\t\t} catch (err) {\n\t\t\tconsole.error('Failed to get user after login, trying basic auth', err);\n\t\t}\n\t}\n\n\ttry {\n\t\tinstanceClient.defaults.auth = auth;\n\t\tinstanceClient.defaults.withCredentials = false;\n\t\tconst user = await getInstanceUserInfo({\n\t\t\tinstanceClient,\n\t\t\tauth,\n\t\t});\n\t\tauthStore.flagForBasicAuth(entityId, auth);\n\t\treturn {\n\t\t\tmessage,\n\t\t\tuser,\n\t\t};\n\t} catch (err) {\n\t\tinstanceClient.defaults.auth = undefined;\n\t\tinstanceClient.defaults.withCredentials = true;\n\t\tif (isLocalStudio) {\n\t\t\tthrow err;\n\t\t}\n\t\tconsole.error('Failed to get user with basic auth, trying Fabric Connect', err);\n\t}\n\n\tconst fabricInstanceClient = getInstanceClient({\n\t\tid: entityId,\n\t\tforceFabricConnect: true,\n\t});\n\tconst user = await getInstanceUserInfo({\n\t\tinstanceClient: fabricInstanceClient,\n\t});\n\tauthStore.flagForFabricConnect(entityId, true);\n\treturn {\n\t\tmessage,\n\t\tuser,\n\t\tinstanceClient: fabricInstanceClient,\n\t};\n}\n\nexport function useInstanceLoginMutation() {\n\treturn useMutation<LoginInfoResponse, Error, InstanceLoginCredentials>({\n\t\tmutationFn: onInstanceLoginSubmit,\n\t});\n}\n","import { defaultInstanceRoute, defaultInstanceRouteUpOne, isLocalStudio } from '@/config/constants';\nimport { InstanceClientIdConfig, InstanceTypeConfig } from '@/config/instanceClientConfig';\nimport { authStore, OverallAppSignIn } from '@/features/auth/store/authStore';\nimport { SchemaHdbInstance } from '@/integrations/api/api.gen';\nimport { Cluster } from '@/integrations/api/api.patch';\nimport { UsernameSignInSchema } from '@/integrations/api/instance/auth/signInSchema';\nimport { useInstanceLoginMutation } from '@/integrations/api/instance/auth/useInstanceLoginMutation';\nimport { useNavigate, useRouter, useSearch } from '@tanstack/react-router';\nimport { useCallback } from 'react';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\n\nexport function useClusterInstanceSignIn({\n\tcluster,\n\tinstance,\n\tinstanceParams,\n}: {\n\tcluster: Cluster | undefined;\n\tinstance: SchemaHdbInstance | undefined;\n\tinstanceParams: InstanceClientIdConfig & InstanceTypeConfig;\n}) {\n\tconst navigate = useNavigate();\n\tconst router = useRouter();\n\tconst { redirect } = useSearch({ strict: false });\n\n\tconst { mutate: submitInstanceLogin, isPending } = useInstanceLoginMutation();\n\n\tconst submitForm = useCallback(async (formData: z.infer<typeof UsernameSignInSchema>) => {\n\t\tsubmitInstanceLogin(\n\t\t\t{\n\t\t\t\t...formData,\n\t\t\t\t...instanceParams,\n\t\t\t},\n\t\t\t{\n\t\t\t\tonSuccess: async ({ message, user }) => {\n\t\t\t\t\ttoast.success(message);\n\t\t\t\t\t// If we sign in to the cluster, we've authenticated against all of its instances too.\n\t\t\t\t\tif (cluster?.instances?.length && !instance) {\n\t\t\t\t\t\tfor (const clusterInstance of cluster.instances) {\n\t\t\t\t\t\t\tauthStore.setUserForEntity(clusterInstance, user);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconst entity = isLocalStudio ? OverallAppSignIn : instance || cluster;\n\t\t\t\t\tif (!entity) {\n\t\t\t\t\t\tthrow new Error('Sign in failed due to missing cluster or instance.');\n\t\t\t\t\t}\n\t\t\t\t\tauthStore.setUserForEntity(entity, user);\n\t\t\t\t\tvoid router.invalidate();\n\t\t\t\t\tawait navigate({\n\t\t\t\t\t\tto: redirect?.startsWith('/')\n\t\t\t\t\t\t\t? redirect\n\t\t\t\t\t\t\t: isLocalStudio\n\t\t\t\t\t\t\t? defaultInstanceRoute\n\t\t\t\t\t\t\t: defaultInstanceRouteUpOne,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t}, [cluster, instance, instanceParams, navigate, redirect, router, submitInstanceLogin]);\n\n\treturn {\n\t\tisPending,\n\t\tsubmitForm,\n\t};\n}\n","import { apiClient } from '@/config/apiClient';\nimport { Cluster } from '@/integrations/api/api.patch';\nimport { queryOptions } from '@tanstack/react-query';\n\nexport async function getClusterInfo(clusterId: string) {\n\tconst { data } = await apiClient.get(`/Cluster/${clusterId}` as '/Cluster/{id}');\n\treturn data as Cluster;\n}\n\nexport function getClusterInfoQueryOptions(clusterId?: string | false, refetch?: boolean | number) {\n\treturn queryOptions({\n\t\tqueryKey: [clusterId],\n\t\tqueryFn: () => getClusterInfo(clusterId as string),\n\t\tretry: false,\n\t\tstaleTime: 1_900,\n\t\tenabled: !!clusterId,\n\t\trefetchInterval: refetch\n\t\t\t? refetch === true\n\t\t\t\t? 10_000\n\t\t\t\t: refetch\n\t\t\t: undefined,\n\t});\n}\n","import { z } from 'zod';\n\nexport const zodRequireEmail = z\n\t.email({\n\t\terror: 'Please enter a valid email address.',\n\t})\n\t.toLowerCase()\n\t.trim();\n","import { z } from 'zod';\n\nexport const zodRequirePassword = z\n\t.string()\n\t.nonempty({ error: 'Please enter your password.' });\n","import { z } from 'zod';\n\nexport const zodRequireUsername = z\n\t.string()\n\t.nonempty({ error: 'Please enter a username.' });\n","import { zodRequireEmail } from '@/lib/zod/email';\nimport { zodRequirePassword } from '@/lib/zod/password';\nimport { zodRequireUsername } from '@/lib/zod/username';\nimport { z } from 'zod';\n\nexport const UsernameSignInSchema = z.object({\n\tusername: zodRequireUsername,\n\tpassword: zodRequirePassword,\n});\n\nexport const EmailSignInSchema = z.object({\n\temail: zodRequireEmail,\n\tpassword: zodRequirePassword,\n});\n","import { InstanceClientIdConfig } from '@/config/instanceClientConfig';\nimport { queryOptions } from '@tanstack/react-query';\n\nexport function getInstanceHealthQueryOptions({\n\tentityId,\n\tinstanceClient,\n}: InstanceClientIdConfig) {\n\treturn queryOptions({\n\t\tqueryKey: [entityId, 'health'] as const,\n\t\tqueryFn: async () => {\n\t\t\ttry {\n\t\t\t\tawait instanceClient.get('/health');\n\t\t\t\treturn true;\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\tretry: 2,\n\t\trefetchInterval: 5000,\n\t});\n}\n","const localHostnames = [\n\t'localhost',\n\t'127.0.0.1',\n];\n\nexport const enum CrossLocalhostIssueType {\n\tMixedLoopback = 'MixedLoopback',\n\tInsecureCookieOutsideChromeAndFirefox = 'InsecureCookieOutsideChromeAndFirefox',\n}\n\nexport function detectCrossLocalhostUrls(\n\tuserAgent: string | undefined,\n\tbrowserHostname: string | undefined,\n\toperationsUrl: string | undefined | null,\n): CrossLocalhostIssueType | null {\n\tif (!operationsUrl || !browserHostname || !userAgent) {\n\t\treturn null;\n\t}\n\tconst serverHostname = new URL(operationsUrl).hostname;\n\tconst browserIsLocal = localHostnames.includes(browserHostname);\n\tconst serverIsLocal = localHostnames.includes(serverHostname);\n\n\tif (browserIsLocal && serverIsLocal && serverHostname !== browserHostname) {\n\t\t// When running Studio locally and self-managing locally, warn when we mix localhost and 127.0.0.1.\n\t\treturn CrossLocalhostIssueType.MixedLoopback;\n\t}\n\n\tif (!browserIsLocal && serverIsLocal) {\n\t\tconst isChromium = userAgent.indexOf('Chrome') >= 0;\n\t\tconst isFirefox = userAgent.indexOf('Firefox') >= 0;\n\t\tif (!isChromium && !isFirefox) {\n\t\t\t// When running Studio in the cloud, and signing in to a local instance, Chrome and Firefox allow the\n\t\t\t// cookies to cross to the insecure localhost because they consider it to be secure enough.\n\t\t\t// https://github.com/httpwg/http-extensions/issues/2605\n\t\t\treturn CrossLocalhostIssueType.InsecureCookieOutsideChromeAndFirefox;\n\t\t}\n\t}\n\n\treturn null;\n}\n","import { Breadcrumbs } from '@/components/Breadcrumbs';\nimport { Button } from '@/components/ui/button';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { activeClusterStatuses } from '@/config/clusterStatuses';\nimport { isLocalStudio } from '@/config/constants';\nimport { calculateCreateClusterDeepLink } from '@/config/deepLinks';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { useClusterInstanceSignIn } from '@/features/auth/hooks/useClusterInstanceSignIn';\nimport { authStore } from '@/features/auth/store/authStore';\nimport { getClusterInfoQueryOptions } from '@/features/cluster/queries/getClusterInfoQuery';\nimport { SchemaHdbInstance } from '@/integrations/api/api.gen';\nimport { UsernameSignInSchema } from '@/integrations/api/instance/auth/signInSchema';\nimport { getInstanceHealthQueryOptions } from '@/integrations/api/instance/status/getInstanceHealth';\nimport { CrossLocalhostIssueType, detectCrossLocalhostUrls } from '@/lib/urls/detectCrossLocalhostUrls';\nimport { getOperationsUrlForCluster } from '@/lib/urls/getOperationsUrlForCluster';\nimport { getOperationsUrlForInstance } from '@/lib/urls/getOperationsUrlForInstance';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useQuery } from '@tanstack/react-query';\nimport { Link, Navigate, useParams } from '@tanstack/react-router';\nimport { cx } from 'class-variance-authority';\nimport { useMemo } from 'react';\nimport { useForm } from 'react-hook-form';\n\nexport function ClusterInstanceSignIn() {\n\tconst { clusterId, instanceId }: { instanceId?: string; clusterId?: string } = useParams({ strict: false });\n\tconst { data: cluster } = useQuery(\n\t\tgetClusterInfoQueryOptions(clusterId, true),\n\t);\n\n\tconst instance: SchemaHdbInstance | undefined = useMemo(\n\t\t() => instanceId && cluster && cluster?.instances?.find(i => i.id === instanceId) || undefined,\n\t\t[cluster, instanceId],\n\t);\n\tconst isActive = useMemo(() => cluster?.status && activeClusterStatuses.includes(cluster.status), [cluster?.status]);\n\n\tconst properNoun = isLocalStudio ? 'Local' : instanceId ? 'Instance' : 'Cluster';\n\tconst commonNoun = isLocalStudio ? 'instance' : instanceId ? 'instance' : 'cluster';\n\n\tconst operationsUrl = useMemo(() => {\n\t\tif (cluster) {\n\t\t\tif (instance) {\n\t\t\t\tauthStore.flagForFabricConnect(instance.id, false);\n\t\t\t\treturn getOperationsUrlForInstance(instance);\n\t\t\t} else {\n\t\t\t\tauthStore.flagForFabricConnect(cluster.id, false);\n\t\t\t\treturn getOperationsUrlForCluster(cluster);\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}, [cluster, instance]);\n\n\tconst instanceParams = useInstanceClientIdParams({ operationsUrl });\n\tconst warnAboutLocalDeviceAccess = useMemo(\n\t\t() => operationsUrl?.includes('localhost') || operationsUrl?.includes('127.0.0.1'),\n\t\t[operationsUrl],\n\t);\n\tconst warnAboutLoginCookieIssues = useMemo(\n\t\t() => detectCrossLocalhostUrls(navigator.userAgent, location.hostname, operationsUrl),\n\t\t[operationsUrl],\n\t);\n\tconst { data: healthy } = useQuery(\n\t\tgetInstanceHealthQueryOptions(instanceParams),\n\t);\n\n\tconst methods = useForm({\n\t\tresolver: zodResolver(UsernameSignInSchema),\n\t\tdefaultValues: {\n\t\t\tusername: '',\n\t\t\tpassword: '',\n\t\t},\n\t});\n\tconst { control, handleSubmit } = methods;\n\n\tconst { submitForm, isPending } = useClusterInstanceSignIn({\n\t\tcluster,\n\t\tinstance,\n\t\tinstanceParams,\n\t});\n\n\tif (!instanceId && cluster && !cluster?.fqdn) {\n\t\treturn <Navigate to=\"../instances\" replace={true} />;\n\t}\n\n\tif (isActive && cluster?.resetPassword) {\n\t\treturn <Navigate to={`/${cluster.organizationId}/${cluster.id}/finish-setup`} replace={true} />;\n\t}\n\tif (!isActive && cluster?.resetPassword) {\n\t\treturn <Navigate to={`/${cluster.organizationId}/${cluster.id}/starting-up`} replace={true} />;\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t{!isLocalStudio && (\n\t\t\t\t<nav\n\t\t\t\t\taria-label=\"Breadcrumb\"\n\t\t\t\t\tclassName=\"fixed top-20 w-full h-12 z-39 px-4 md:px-12 bg-violet-50 border-b border-violet-100 dark:bg-grey-700 dark:border-none flex items-center\"\n\t\t\t\t>\n\t\t\t\t\t<Breadcrumbs />\n\t\t\t\t</nav>\n\t\t\t)}\n\t\t\t<div\n\t\t\t\tclassName={cx(\n\t\t\t\t\tisLocalStudio ? 'min-h-screen' : 'mt-32 min-h-[calc(100vh-(--spacing(32)))]',\n\t\t\t\t\t'items-center justify-center flex',\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t<div className=\"text-foreground w-xs py-8\">\n\t\t\t\t\t<h1 className=\"text-2xl font-light\">\n\t\t\t\t\t\tSign in to Harper {properNoun}\n\t\t\t\t\t</h1>\n\t\t\t\t\t<Form {...methods}>\n\t\t\t\t\t\t<form\n\t\t\t\t\t\t\tid={`auth-${commonNoun}-signin-form`}\n\t\t\t\t\t\t\tname={`auth-${commonNoun}-signin-form`}\n\t\t\t\t\t\t\tonSubmit={handleSubmit(submitForm)}\n\t\t\t\t\t\t\tclassName=\"my-4\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\t\t\tname=\"username\"\n\t\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t\t<FormItem className=\"my-4\">\n\t\t\t\t\t\t\t\t\t\t<FormLabel>Username</FormLabel>\n\t\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\t\tautoComplete=\"username\"\n\t\t\t\t\t\t\t\t\t\t\t\tautoFocus={true}\n\t\t\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\t\t\tname=\"password\"\n\t\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t\t<FormItem className=\"my-4\">\n\t\t\t\t\t\t\t\t\t\t<FormLabel>Password</FormLabel>\n\t\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<Button disabled={isPending} type=\"submit\" variant=\"submit\" className=\"w-full my-2 rounded-full\">\n\t\t\t\t\t\t\t\tSign In\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t{healthy === false && (\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tclassName=\"p-4 mt-4 text-sm text-yellow-800 rounded-lg bg-yellow-50 dark:bg-gray-800 dark:text-yellow-300\"\n\t\t\t\t\t\t\t\t\trole=\"alert\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<span className=\"font-medium\">Warning!</span> This {commonNoun} is not responding to GET{' '}\n\t\t\t\t\t\t\t\t\t<a href={`${operationsUrl}health`} className=\"underline\" target=\"_blank\">{operationsUrl}health</a>\n\t\t\t\t\t\t\t\t\t{' '}\n\t\t\t\t\t\t\t\t\tchecks.\n\t\t\t\t\t\t\t\t\t<ol className=\"list-decimal ml-8 mt-2\">\n\t\t\t\t\t\t\t\t\t\t<li>Is the server running?</li>\n\t\t\t\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t\t\t\tHave you{' '}\n\t\t\t\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\t\t\t\thref=\"https://docs.harperdb.io/docs/developers/security/configuration#cors\"\n\t\t\t\t\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\t\t\t\t\trel=\"noreferrer\"\n\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"underline\"\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\tenabled CORS\n\t\t\t\t\t\t\t\t\t\t\t</a>{' '}\n\t\t\t\t\t\t\t\t\t\t\tfor the operations API?\n\t\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t\t\t{warnAboutLocalDeviceAccess && (\n\t\t\t\t\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t\t\t\t\tHave you allowed{' '}\n\t\t\t\t\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\t\t\t\t\thref=\"https://www.google.com/search?q=How+do+I+enable+local+network+access+in+my+browser%3F\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"underline\"\n\t\t\t\t\t\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\t\t\t\t\t\trel=\"noreferrer\"\n\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\tlocal network access\n\t\t\t\t\t\t\t\t\t\t\t\t</a>{' '}\n\t\t\t\t\t\t\t\t\t\t\t\tin your browser?\n\t\t\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t</ol>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{warnAboutLoginCookieIssues === CrossLocalhostIssueType.MixedLoopback && (\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tclassName=\"p-4 mt-4 text-sm text-yellow-800 rounded-lg bg-yellow-50 dark:bg-gray-800 dark:text-yellow-300\"\n\t\t\t\t\t\t\t\t\trole=\"alert\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<span className=\"font-medium\">Warning!</span>{' '}\n\t\t\t\t\t\t\t\t\tYour login might not work because you're mixing 127.0.0.1 and localhost. Pick one or the other.\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{warnAboutLoginCookieIssues === CrossLocalhostIssueType.InsecureCookieOutsideChromeAndFirefox && (\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tclassName=\"p-4 mt-4 text-sm text-yellow-800 rounded-lg bg-yellow-50 dark:bg-gray-800 dark:text-yellow-300\"\n\t\t\t\t\t\t\t\t\trole=\"alert\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<span className=\"font-medium\">Warning!</span>{' '}\n\t\t\t\t\t\t\t\t\tYour login might not work because your browser doesn't consider localhost to be secure, so it doesn't\n\t\t\t\t\t\t\t\t\tpass the cookies along. Firefox or Chromium based browsers should pass the cookies properly.\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t{isLocalStudio && (\n\t\t\t\t\t\t\t\t<div className=\"p-4 mt-4 text-sm rounded-lg bg-purple-950\" role=\"alert\">\n\t\t\t\t\t\t\t\t\t<span className=\"font-medium\">Did you know?</span>{' '}\n\t\t\t\t\t\t\t\t\tYou can add this instance to your Harper account to manage it remotely.\n\t\t\t\t\t\t\t\t\t<div className=\"text-center pt-2\">\n\t\t\t\t\t\t\t\t\t\t<Link to={calculateCreateClusterDeepLink()} target=\"_blank\">\n\t\t\t\t\t\t\t\t\t\t\t<Button type=\"button\" variant=\"positive\">\n\t\t\t\t\t\t\t\t\t\t\t\tConnect to Harper Fabric\n\t\t\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</form>\n\t\t\t\t\t</Form>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</>\n\t);\n}\n","import { apiClient } from '@/config/apiClient';\nimport { useMutation } from '@tanstack/react-query';\n\nexport type ForgotPasswordCredential = {\n\temail: string;\n};\n\ntype ForgotPasswordResponse = {\n\temail: string;\n};\n\nexport async function onResetPasswordSubmit({ email }: ForgotPasswordCredential): Promise<ForgotPasswordResponse> {\n\tconst { data } = await apiClient.post('/ForgotPassword/', {\n\t\temail,\n\t});\n\tif (data) {\n\t\t// TODO: The OpenAPI description isn't accurate.\n\t\treturn data as ForgotPasswordResponse;\n\t} else {\n\t\tthrow new Error('Something went wrong');\n\t}\n}\n\nexport function useForgotPasswordMutation() {\n\treturn useMutation<ForgotPasswordResponse, Error, ForgotPasswordCredential>({\n\t\tmutationFn: (loginData) => onResetPasswordSubmit(loginData),\n\t});\n}\n","import { Button } from '@/components/ui/button';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { zodRequireEmail } from '@/lib/zod/email';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { Link, useNavigate, useSearch } from '@tanstack/react-router';\nimport { useEffect } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\nimport { useForgotPasswordMutation } from './hooks/useForgotPassword';\n\nconst ForgotPasswordSchema = z.object({\n\temail: zodRequireEmail,\n});\n\nexport function ForgotPassword() {\n\tconst navigate = useNavigate();\n\tconst { me: formPersistenceEmail } = useSearch({ strict: false });\n\tconst methods = useForm({\n\t\tresolver: zodResolver(ForgotPasswordSchema),\n\t\tdefaultValues: {\n\t\t\temail: formPersistenceEmail || '',\n\t\t},\n\t});\n\tconst email = methods.watch('email');\n\tconst { setFocus, control, handleSubmit } = methods;\n\n\tuseEffect(() => {\n\t\tsetFocus('email');\n\t}, [setFocus]);\n\n\tconst { mutate: submitForgotPasswordData, isPending } = useForgotPasswordMutation();\n\n\tconst submitForm = async (formData: z.infer<typeof ForgotPasswordSchema>) => {\n\t\tsubmitForgotPasswordData(formData, {\n\t\t\tonSuccess: (message) => {\n\t\t\t\ttoast.success('Success', {\n\t\t\t\t\tdescription: `${message}`,\n\t\t\t\t\taction: {\n\t\t\t\t\t\tlabel: 'Dismiss',\n\t\t\t\t\t\tonClick: () => toast.dismiss(),\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tnavigate({ to: '/sign-in', search: { me: email } });\n\t\t\t},\n\t\t});\n\t};\n\n\treturn (\n\t\t<div className=\"text-foreground dark:text-white w-xs\">\n\t\t\t<h1 className=\"text-2xl font-light\">Enter your account email</h1>\n\t\t\t<p className=\"text-sm pt-1\">If a matching account exists, we'll send you a password reset link.</p>\n\t\t\t<Form {...methods}>\n\t\t\t\t<form\n\t\t\t\t\tid=\"auth-forgot-password-form\"\n\t\t\t\t\tname=\"auth-forgot-password-form\"\n\t\t\t\t\tonSubmit={handleSubmit(submitForm)}\n\t\t\t\t\tclassName=\"my-4\"\n\t\t\t\t>\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\tname=\"email\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem className=\"my-2\">\n\t\t\t\t\t\t\t\t<FormLabel>Email</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\tdisabled={isPending}\n\t\t\t\t\t\t\t\t\t\ttype=\"email\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\t\t\t\t\t<Button type=\"submit\" variant=\"submit\" disabled={isPending} className=\"w-full my-2 rounded-full\">\n\t\t\t\t\t\tSend Password Reset Email\n\t\t\t\t\t</Button>\n\t\t\t\t</form>\n\t\t\t</Form>\n\t\t\t<div className=\"flex px-4 mt-4 underline place-content-between\">\n\t\t\t\t<Link className=\"text-sm hover:text-blue-300\" to=\"/sign-in\" search={{ me: email }}>\n\t\t\t\t\tSign in to your account\n\t\t\t\t</Link>\n\t\t\t\t<Link className=\"text-sm hover:text-blue-300\" to=\"/sign-up\" search={{ me: email }}>\n\t\t\t\t\tSign up for free\n\t\t\t\t</Link>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n","import { apiClient } from '@/config/apiClient';\nimport { useMutation } from '@tanstack/react-query';\n\ntype ResetPasswordRequest = {\n\ttoken: string;\n\tpassword: string;\n};\n\ntype ResetPasswordResponse = {\n\tuserId: string;\n\temail: string;\n};\n\nconst onResetPasswordSubmit = async ({ token, password }: ResetPasswordRequest): Promise<ResetPasswordResponse> => {\n\t// TODO: The SchemaResetPassword is also not descriptive: Record<string, never> (which is really \"unknown\").\n\tconst { data } = await apiClient.put('/ResetPassword/', {\n\t\ttoken,\n\t\tnewPassword: password,\n\t});\n\t// TODO: The OpenAPI response for this endpoint isn't very good.\n\treturn data as ResetPasswordResponse;\n};\n\nexport function useResetPasswordMutation() {\n\treturn useMutation<ResetPasswordResponse, Error, ResetPasswordRequest>({\n\t\tmutationFn: (formData) => onResetPasswordSubmit(formData),\n\t});\n}\n","import { Button } from '@/components/ui/button';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { zodRequirePassword } from '@/lib/zod/password';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useNavigate, useSearch } from '@tanstack/react-router';\nimport { useCallback, useEffect } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\nimport { useResetPasswordMutation } from './hooks/useResetPassword';\n\nconst ResetPasswordSchema = z\n\t.object({\n\t\tpassword: zodRequirePassword\n\t\t\t.min(8, { error: 'Password must be at least 8 characters long.' })\n\t\t\t.max(50, { error: 'Password cannot be longer than 50 characters.' }),\n\t\tconfirmPassword: z.string(),\n\t})\n\t.refine((data) => data.password === data.confirmPassword, {\n\t\terror: 'Passwords do not match.',\n\t\tpath: ['confirmPassword'],\n\t});\n\nexport function ResetPassword() {\n\tconst { token } = useSearch({ strict: false });\n\tconst navigate = useNavigate();\n\n\tuseEffect(() => {\n\t\tif (!token) {\n\t\t\tvoid navigate({ to: '/sign-in' });\n\t\t}\n\t}, [token, navigate]);\n\n\tconst methods = useForm({\n\t\tresolver: zodResolver(ResetPasswordSchema),\n\t\tdefaultValues: {\n\t\t\tpassword: '',\n\t\t\tconfirmPassword: '',\n\t\t},\n\t});\n\tconst { setFocus, control, handleSubmit } = methods;\n\n\tuseEffect(() => {\n\t\tsetFocus('password');\n\t}, [setFocus]);\n\n\tconst { mutate: submitResetPasswordData, isPending } = useResetPasswordMutation();\n\n\tconst submitForm = useCallback(async (formData: { password: string; confirmPassword: string }) => {\n\t\tsubmitResetPasswordData(\n\t\t\t{ token: token as string, password: formData.password },\n\t\t\t{\n\t\t\t\tonSuccess: () => {\n\t\t\t\t\ttoast.success('Success', {\n\t\t\t\t\t\tdescription: 'Your password has been reset successfully.',\n\t\t\t\t\t\taction: {\n\t\t\t\t\t\t\tlabel: 'Dismiss',\n\t\t\t\t\t\t\tonClick: () => toast.dismiss(),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t\tnavigate({ to: '/sign-in' });\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t}, [navigate, submitResetPasswordData, token]);\n\n\treturn (\n\t\t<div className=\"text-foreground dark:text-white w-xs\">\n\t\t\t<h1 className=\"text-2xl font-light\">Reset Password</h1>\n\t\t\t<Form {...methods}>\n\t\t\t\t<form\n\t\t\t\t\tid=\"auth-reset-password-form\"\n\t\t\t\t\tname=\"auth-reset-password-form\"\n\t\t\t\t\tclassName=\"my-4\"\n\t\t\t\t\tonSubmit={handleSubmit(submitForm)}\n\t\t\t\t>\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\tname=\"password\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem className=\"my-2\">\n\t\t\t\t\t\t\t\t<FormLabel>New Password</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\tdisabled={isPending}\n\t\t\t\t\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\t\t\t\t\tautoComplete=\"new-password\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\tname=\"confirmPassword\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem className=\"my-2\">\n\t\t\t\t\t\t\t\t<FormLabel>Confirm Password</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\tdisabled={isPending}\n\t\t\t\t\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\t\t\t\t\tautoComplete=\"new-password\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\t\t\t\t\t<Button variant=\"submit\" type=\"submit\" disabled={isPending} className=\"w-full my-2 rounded-full\">\n\t\t\t\t\t\tSubmit New Password\n\t\t\t\t\t</Button>\n\t\t\t\t</form>\n\t\t\t</Form>\n\t\t</div>\n\t);\n}\n","import './GitHubAuthenticationButton.css';\nimport { cx } from 'class-variance-authority';\nimport { MouseEventHandler } from 'react';\n\nexport function GitHubAuthenticationButton({\n\ttext,\n\tdisabled,\n\tonClick,\n}: {\n\ttext: 'Sign in with GitHub' | 'Sign up with GitHub';\n\tdisabled?: boolean;\n\tonClick?: MouseEventHandler<HTMLAnchorElement>;\n}) {\n\treturn (\n\t\t<a\n\t\t\thref=\"/oauth/github/login?redirect=%2F%23%2Fcheck-oauth\"\n\t\t\tonClick={onClick}\n\t\t\taria-disabled={disabled || undefined}\n\t\t\tclassName={cx('github-signin-btn', disabled && 'opacity-50 cursor-default')}\n\t\t>\n\t\t\t<img src=\"/github/GitHub_Invertocat_White.svg\" alt=\"\" className=\"github-icon\" />\n\t\t\t{text}\n\t\t</a>\n\t);\n}\n","import './GoogleAuthenticationButton.css';\nimport { cx } from 'class-variance-authority';\nimport { MouseEventHandler } from 'react';\n\nexport function GoogleAuthenticationButton({\n\ttext,\n\tdisabled,\n\tonClick,\n}: {\n\ttext: 'Sign in with Google' | 'Sign up with Google';\n\tdisabled?: boolean;\n\tonClick?: MouseEventHandler<HTMLAnchorElement>;\n}) {\n\treturn (\n\t\t<a\n\t\t\thref=\"/oauth/google/login?redirect=%2F%23%2Fcheck-oauth\"\n\t\t\tonClick={onClick}\n\t\t\taria-disabled={disabled || undefined}\n\t\t\tclassName={cx('gsi-material-button', disabled && 'opacity-50 cursor-default')}\n\t\t>\n\t\t\t<div aria-hidden=\"true\" className=\"gsi-material-button-state\"></div>\n\t\t\t<div className=\"gsi-material-button-content-wrapper\">\n\t\t\t\t<div aria-hidden=\"true\" className=\"gsi-material-button-icon\">\n\t\t\t\t\t<svg\n\t\t\t\t\t\tversion=\"1.1\"\n\t\t\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\t\t\tviewBox=\"0 0 48 48\"\n\t\t\t\t\t\txmlnsXlink=\"http://www.w3.org/1999/xlink\"\n\t\t\t\t\t\tclassName=\"block\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<path\n\t\t\t\t\t\t\tfill=\"#EA4335\"\n\t\t\t\t\t\t\td=\"M24 9.5c3.54 0 6.71 1.22 9.21 3.6l6.85-6.85C35.9 2.38 30.47 0 24 0 14.62 0 6.51 5.38 2.56 13.22l7.98 6.19C12.43 13.72 17.74 9.5 24 9.5z\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t</path>\n\t\t\t\t\t\t<path\n\t\t\t\t\t\t\tfill=\"#4285F4\"\n\t\t\t\t\t\t\td=\"M46.98 24.55c0-1.57-.15-3.09-.38-4.55H24v9.02h12.94c-.58 2.96-2.26 5.48-4.78 7.18l7.73 6c4.51-4.18 7.09-10.36 7.09-17.65z\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t</path>\n\t\t\t\t\t\t<path\n\t\t\t\t\t\t\tfill=\"#FBBC05\"\n\t\t\t\t\t\t\td=\"M10.53 28.59c-.48-1.45-.76-2.99-.76-4.59s.27-3.14.76-4.59l-7.98-6.19C.92 16.46 0 20.12 0 24c0 3.88.92 7.54 2.56 10.78l7.97-6.19z\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t</path>\n\t\t\t\t\t\t<path\n\t\t\t\t\t\t\tfill=\"#34A853\"\n\t\t\t\t\t\t\td=\"M24 48c6.48 0 11.93-2.13 15.89-5.81l-7.73-6c-2.15 1.45-4.92 2.3-8.16 2.3-6.26 0-11.57-4.22-13.47-9.91l-7.98 6.19C6.51 42.62 14.62 48 24 48z\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t</path>\n\t\t\t\t\t\t<path fill=\"none\" d=\"M0 0h48v48H0z\"></path>\n\t\t\t\t\t</svg>\n\t\t\t\t</div>\n\t\t\t\t<span className=\"gsi-material-button-contents\">{text}</span>\n\t\t\t\t<span className=\"hidden\">{text}</span>\n\t\t\t</div>\n\t\t</a>\n\t);\n}\n","import { apiClient } from '@/config/apiClient';\nimport { currentUserQueryKey } from '@/features/auth/queries/getCurrentUser';\nimport { authStore, OverallAppSignIn } from '@/features/auth/store/authStore';\nimport { User } from '@/integrations/api/api.patch';\nimport { EmailSignInSchema } from '@/integrations/api/instance/auth/signInSchema';\nimport { loginSuccessDatadogAction } from '@/integrations/datadog/datadog';\nimport { reoClient } from '@/integrations/reo/reo';\nimport { parseCompanyFromEmail } from '@/lib/string/parseCompanyFromEmail';\nimport { getDefaultSignedInCloudRouteForUser } from '@/lib/urls/getDefaultSignedInCloudRouteForUser';\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useNavigate, useRouter, useSearch } from '@tanstack/react-router';\nimport { useCallback } from 'react';\nimport { z } from 'zod';\n\nexport function useCloudSignIn() {\n\tconst navigate = useNavigate();\n\tconst queryClient = useQueryClient();\n\tconst router = useRouter();\n\tconst { redirect } = useSearch({ strict: false });\n\n\tconst { mutate: submitLoginData, isPending } = useLoginMutation();\n\n\tconst submitForm = useCallback((formData: z.infer<typeof EmailSignInSchema>) => {\n\t\tsubmitLoginData(formData, {\n\t\t\tonSuccess: async (data) => {\n\t\t\t\tauthStore.setUserForEntity(OverallAppSignIn, data);\n\t\t\t\tconst defaultCloudRoute = getDefaultSignedInCloudRouteForUser(data);\n\n\t\t\t\tloginSuccessDatadogAction(data);\n\n\t\t\t\tconst company = parseCompanyFromEmail(data.email);\n\t\t\t\treoClient?.identify?.({\n\t\t\t\t\tusername: data.email,\n\t\t\t\t\ttype: 'email',\n\t\t\t\t\t...(company ? { company } : {}),\n\t\t\t\t});\n\t\t\t\tawait queryClient.invalidateQueries({ queryKey: currentUserQueryKey, refetchType: 'none' });\n\t\t\t\tvoid router.invalidate();\n\t\t\t\tawait navigate({ to: redirect?.startsWith('/') ? redirect : defaultCloudRoute });\n\t\t\t},\n\t\t});\n\t}, [navigate, queryClient, redirect, router, submitLoginData]);\n\n\treturn {\n\t\tisPending,\n\t\tsubmitForm,\n\t};\n}\n\nfunction useLoginMutation() {\n\treturn useMutation<User, Error, z.infer<typeof EmailSignInSchema>>({\n\t\tmutationFn: (loginData) => onLoginSubmit(loginData),\n\t});\n}\n\nasync function onLoginSubmit({ email, password }: z.infer<typeof EmailSignInSchema>) {\n\t// TODO: The OpenAPI request body for this endpoint isn't defined.\n\tconst { data } = await apiClient.post('/Login/', {\n\t\temail,\n\t\tpassword,\n\t});\n\tif (data) {\n\t\t// TODO: The OpenAPI response for this endpoint isn't defined.\n\t\treturn data as unknown as User;\n\t} else {\n\t\tthrow new Error('Something went wrong');\n\t}\n}\n","import { Button } from '@/components/ui/button';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { EmailSignInSchema } from '@/integrations/api/instance/auth/signInSchema';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { Link, useSearch } from '@tanstack/react-router';\nimport { useForm } from 'react-hook-form';\nimport { GitHubAuthenticationButton } from './components/GitHubAuthenticationButton';\nimport { GoogleAuthenticationButton } from './components/GoogleAuthenticationButton';\nimport { useCloudSignIn } from './hooks/useCloudSignIn';\n\nexport function SignIn() {\n\tconst { me: formPersistenceEmail } = useSearch({ strict: false });\n\n\tconst methods = useForm({\n\t\tresolver: zodResolver(EmailSignInSchema),\n\t\tdefaultValues: {\n\t\t\temail: formPersistenceEmail || '',\n\t\t\tpassword: '',\n\t\t},\n\t});\n\tconst { handleSubmit, control } = methods;\n\tconst email = methods.watch('email');\n\n\tconst { submitForm, isPending } = useCloudSignIn();\n\n\treturn (\n\t\t<div className=\"text-foreground dark:text-white w-xs\">\n\t\t\t<h1 className=\"text-2xl font-light text-center\">Sign in to Harper Fabric</h1>\n\t\t\t<Form {...methods}>\n\t\t\t\t<form\n\t\t\t\t\tid=\"auth-signin-form\"\n\t\t\t\t\tname=\"auth-signin-form\"\n\t\t\t\t\tonSubmit={handleSubmit(submitForm)}\n\t\t\t\t\tclassName=\"my-4\"\n\t\t\t\t>\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\tname=\"email\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem className=\"my-4\">\n\t\t\t\t\t\t\t\t<FormLabel>Email</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\ttype=\"email\"\n\t\t\t\t\t\t\t\t\t\tautoFocus={true}\n\t\t\t\t\t\t\t\t\t\tautoComplete=\"email\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\tname=\"password\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem className=\"my-4\">\n\t\t\t\t\t\t\t\t<FormLabel>Password</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\t\t\t\t\tautoComplete=\"current-password\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\t\t\t\t\t<Button type=\"submit\" variant=\"submit\" className=\"w-full my-2 rounded-full\" disabled={isPending}>\n\t\t\t\t\t\tSign In\n\t\t\t\t\t</Button>\n\t\t\t\t\t<div className=\"flex px-4 mt-4 underline place-content-between\">\n\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\tclassName=\"text-sm text-muted-foreground hover:text-foreground dark:text-inherit dark:hover:text-blue-300\"\n\t\t\t\t\t\t\tto=\"/sign-up\"\n\t\t\t\t\t\t\tsearch={{ me: email }}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tSign up for free\n\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\tclassName=\"text-sm text-muted-foreground hover:text-foreground dark:text-inherit dark:hover:text-blue-300\"\n\t\t\t\t\t\t\tto=\"/forgot-password\"\n\t\t\t\t\t\t\tsearch={{ me: email }}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tForgot password?\n\t\t\t\t\t\t</Link>\n\t\t\t\t\t</div>\n\t\t\t\t</form>\n\t\t\t</Form>\n\n\t\t\t<hr aria-hidden=\"true\" className=\"border-border dark:border-gray-600 my-6\" />\n\n\t\t\t<div className=\"flex flex-col gap-2\">\n\t\t\t\t<GoogleAuthenticationButton text=\"Sign in with Google\" />\n\t\t\t\t<GitHubAuthenticationButton text=\"Sign in with GitHub\" />\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n","export const personNameRegex =\n\t/^[a-zA-ZàáâäãåąčćęèéêëėįìíîïłńòóôöõøùúûüųūÿýżźñçčšžæÀÁÂÄÃÅĄĆČĖĘÈÉÊËÌÍÎÏĮŁŃÒÓÔÖÕØÙÚÛÜŲŪŸÝŻŹÑßÇŒÆČŠŽ∂ð ,'-]+$/u;\n","import { apiClient } from '@/config/apiClient';\nimport { SchemaUser } from '@/integrations/api/api.gen';\nimport { useMutation } from '@tanstack/react-query';\n\nexport interface SignUpCredentials extends Omit<SchemaUser, 'id'> {\n\temail: string;\n\tpassword: string;\n\tfirstname: string;\n\tlastname: string;\n}\n\nexport async function onSignUpSubmit(signUpCredentials: SignUpCredentials) {\n\t// TODO: The types in our OpenAPI for this endpoint aren't defined.\n\tconst { data } = await apiClient.post('/User/', signUpCredentials);\n\tif (data) {\n\t\treturn data;\n\t} else {\n\t\tthrow new Error('Something went wrong');\n\t}\n}\n\nexport function useSignUpMutation() {\n\treturn useMutation<SchemaUser, Error, SignUpCredentials>({\n\t\tmutationFn: (loginData) => onSignUpSubmit(loginData),\n\t});\n}\n","import { Button } from '@/components/ui/button';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { reoClient } from '@/integrations/reo/reo';\nimport { parseCompanyFromEmail } from '@/lib/string/parseCompanyFromEmail';\nimport { personNameRegex } from '@/lib/string/regex/personNameRegex';\nimport { zodRequireEmail } from '@/lib/zod/email';\nimport { zodRequirePassword } from '@/lib/zod/password';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { Link, useNavigate, useSearch } from '@tanstack/react-router';\nimport { MouseEvent, useCallback, useEffect, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { z } from 'zod';\nimport { GitHubAuthenticationButton } from './components/GitHubAuthenticationButton';\nimport { GoogleAuthenticationButton } from './components/GoogleAuthenticationButton';\nimport { useSignUpMutation } from './hooks/useSignUp';\n\nconst SignUpSchema = z.object({\n\temail: zodRequireEmail\n\t\t.max(80, { error: 'Email cannot be longer than 80 characters.' }),\n\tfirstname: z\n\t\t.string()\n\t\t.trim()\n\t\t.min(2, { error: 'Please enter your first name.' })\n\t\t.regex(\n\t\t\tpersonNameRegex,\n\t\t\t{ error: 'First name can only contain letters, spaces, and hyphens.' },\n\t\t)\n\t\t.max(40, { error: 'First name cannot be longer than 40 characters.' }),\n\tlastname: z\n\t\t.string()\n\t\t.trim()\n\t\t.min(2, { error: 'Please enter your last name.' })\n\t\t.regex(\n\t\t\tpersonNameRegex,\n\t\t\t{ error: 'Last name can only contain letters, spaces, and hyphens.' },\n\t\t)\n\t\t.max(80, { error: 'Last name cannot be longer than 80 characters.' }),\n\tpassword: zodRequirePassword\n\t\t.min(8, { error: 'Password must be at least 8 characters long.' }),\n\tconfirmPassword: z.string(),\n\tacceptTerms: z.boolean().refine(val => val === true, {\n\t\tmessage: 'You must accept the Privacy Policy and Terms of Service.',\n\t}),\n})\n\t.refine((data) => data.password === data.confirmPassword, {\n\t\terror: 'Passwords do not match.',\n\t\tpath: ['confirmPassword'],\n\t});\n\nexport function SignUp() {\n\tconst navigate = useNavigate();\n\tconst { email: searchEmail, me: formPersistenceEmail } = useSearch({ strict: false });\n\tconst [flashTerms, setFlashTerms] = useState(false);\n\n\tconst methods = useForm({\n\t\tresolver: zodResolver(SignUpSchema),\n\t\tdefaultValues: {\n\t\t\tfirstname: '',\n\t\t\tlastname: '',\n\t\t\temail: formPersistenceEmail || searchEmail || '',\n\t\t\tpassword: '',\n\t\t\tconfirmPassword: '',\n\t\t\tacceptTerms: false,\n\t\t},\n\t});\n\n\tconst email = methods.watch('email');\n\tconst acceptTerms = methods.watch('acceptTerms');\n\tconst { setFocus, control, handleSubmit } = methods;\n\n\tuseEffect(() => {\n\t\tsetFocus('firstname');\n\t}, [setFocus]);\n\n\tconst { mutate: submitSignUpData } = useSignUpMutation();\n\n\tconst submitForm = useCallback(async (formData: z.infer<typeof SignUpSchema>) => {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\t\tconst { confirmPassword, acceptTerms, ...userData } = formData;\n\t\tsubmitSignUpData(userData, {\n\t\t\tonSuccess: () => {\n\t\t\t\tconst company = parseCompanyFromEmail(userData.email);\n\t\t\t\treoClient?.identify?.({\n\t\t\t\t\tusername: userData.email,\n\t\t\t\t\ttype: 'email',\n\t\t\t\t\tfirstname: userData.firstname,\n\t\t\t\t\tlastname: userData.lastname,\n\t\t\t\t\t...(company ? { company } : {}),\n\t\t\t\t});\n\t\t\t\tvoid navigate({ to: '/verifying?email=' + encodeURIComponent(userData.email) });\n\t\t\t},\n\t\t});\n\t}, [navigate, submitSignUpData]);\n\n\tconst onOAuthClick = useCallback((e: MouseEvent) => {\n\t\tif (!acceptTerms) {\n\t\t\tsetFlashTerms(true);\n\t\t\tsetTimeout(() => setFlashTerms(false), 1000);\n\t\t\te.preventDefault();\n\t\t\treturn false;\n\t\t}\n\t}, [acceptTerms]);\n\n\tconst termsCheckbox = (\n\t\t<FormField\n\t\t\tcontrol={control}\n\t\t\tname=\"acceptTerms\"\n\t\t\trender={({ field }) => (\n\t\t\t\t<FormItem\n\t\t\t\t\tclassName={`flex flex-row items-start space-x-3 space-y-0 p-1 transition-colors duration-300 ${\n\t\t\t\t\t\tflashTerms ? 'bg-red-500/20 animate-pulse rounded' : ''\n\t\t\t\t\t}`}\n\t\t\t\t>\n\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\tclassName=\"size-4 rounded border-gray-300 bg-white text-purple-600 focus:ring-purple-500\"\n\t\t\t\t\t\t\tchecked={field.value}\n\t\t\t\t\t\t\tonChange={field.onChange}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</FormControl>\n\t\t\t\t\t<div className=\"space-y-1 leading-none\">\n\t\t\t\t\t\t<FormLabel className=\"text-xs font-normal\">\n\t\t\t\t\t\t\tI accept the{' '}\n\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\thref=\"https://www.harper.fast/resources/privacy-policy\"\n\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\trel=\"noreferrer\"\n\t\t\t\t\t\t\t\tclassName=\"underline hover:text-blue-300\"\n\t\t\t\t\t\t\t\taria-label=\"Privacy Policy (opens in new tab)\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tPrivacy Policy\n\t\t\t\t\t\t\t</a>{' '}\n\t\t\t\t\t\t\tand{' '}\n\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\thref=\"https://www.harper.fast/resources/paas-terms-of-service\"\n\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\trel=\"noreferrer\"\n\t\t\t\t\t\t\t\tclassName=\"underline hover:text-blue-300\"\n\t\t\t\t\t\t\t\taria-label=\"Terms of Service (opens in new tab)\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tTerms of Service\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</FormLabel>\n\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t</div>\n\t\t\t\t</FormItem>\n\t\t\t)}\n\t\t/>\n\t);\n\n\treturn (\n\t\t<div className=\"text-foreground dark:text-white w-xs\">\n\t\t\t<h1 className=\"text-2xl font-light text-center\">Sign up for Harper Fabric</h1>\n\n\t\t\t<Form {...methods}>\n\t\t\t\t<div className=\"flex flex-col gap-2 my-6\">\n\t\t\t\t\t{termsCheckbox}\n\t\t\t\t\t<GoogleAuthenticationButton\n\t\t\t\t\t\ttext=\"Sign up with Google\"\n\t\t\t\t\t\tdisabled={!acceptTerms}\n\t\t\t\t\t\tonClick={onOAuthClick}\n\t\t\t\t\t/>\n\t\t\t\t\t<GitHubAuthenticationButton\n\t\t\t\t\t\ttext=\"Sign up with GitHub\"\n\t\t\t\t\t\tdisabled={!acceptTerms}\n\t\t\t\t\t\tonClick={onOAuthClick}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\n\t\t\t\t<hr className=\"border-gray-600\" />\n\n\t\t\t\t<form\n\t\t\t\t\tid=\"auth-signup-form\"\n\t\t\t\t\tname=\"auth-signup-form\"\n\t\t\t\t\tonSubmit={handleSubmit(submitForm)}\n\t\t\t\t\tclassName=\"grid gap-4 my-4\"\n\t\t\t\t>\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\tname=\"firstname\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">First Name</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"words\"\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\tname=\"lastname\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Last Name</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"words\"\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\tname=\"email\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Email</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\ttype=\"email\"\n\t\t\t\t\t\t\t\t\t\treadOnly={!!searchEmail}\n\t\t\t\t\t\t\t\t\t\tdisabled={!!searchEmail}\n\t\t\t\t\t\t\t\t\t\tclassName=\"dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t\tautoComplete=\"email\"\n\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"none\"\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\tname=\"password\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Password</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\t\t\t\t\tautoComplete=\"new-password\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\tname=\"confirmPassword\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Confirm Password</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\t\t\t\t\tautoComplete=\"new-password\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\t\t\t\t\t{termsCheckbox}\n\n\t\t\t\t\t<Button type=\"submit\" variant=\"submit\" className=\"w-full rounded-full my-4\">\n\t\t\t\t\t\tSign Up For Free\n\t\t\t\t\t</Button>\n\t\t\t\t</form>\n\t\t\t</Form>\n\t\t\t<div className=\"flex px-4 mt-4 underline place-content-between\">\n\t\t\t\t<Link className=\"m-auto text-sm hover:text-blue-300\" to=\"/sign-in\" search={{ me: email }}>\n\t\t\t\t\tAlready have an account? Sign in instead.\n\t\t\t\t</Link>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n","import { apiClient } from '@/config/apiClient';\nimport { useMutation } from '@tanstack/react-query';\n\nexport type ResendEmailVerificationRequest = {\n\temail: string;\n};\n\ntype ResendVerificationEmailResponse = {\n\temail: string;\n};\n\nconst onResendEmailVerificationSubmit = async ({\n\temail,\n}: ResendEmailVerificationRequest): Promise<ResendVerificationEmailResponse> => {\n\t// TODO: The OpenAPI request body for this endpoint isn't very descriptive.\n\tconst { data } = await apiClient.post<ResendEmailVerificationRequest>('/ResendVerificationEmail/', {\n\t\temail,\n\t});\n\treturn data;\n};\n\nexport function useResendEmailVerification() {\n\treturn useMutation<ResendVerificationEmailResponse, Error, ResendEmailVerificationRequest>({\n\t\tmutationFn: (loginData) => onResendEmailVerificationSubmit(loginData),\n\t});\n}\n","import { apiClient } from '@/config/apiClient';\nimport { useMutation } from '@tanstack/react-query';\n\ntype VerifyEmailToken = {\n\ttoken: string;\n};\n\ntype VerifyEmailResponse = {\n\tuseId: string;\n\temail: string;\n};\n\nconst onVerifyEmailTokenSubmit = async (token: VerifyEmailToken): Promise<VerifyEmailResponse> => {\n\t// TODO: The OpenAPI types don't describe the request body, either; Record<string, never>\n\tconst { data } = await apiClient.put<VerifyEmailToken>('/VerifyEmail/', {\n\t\ttoken: token.toString(),\n\t});\n\treturn data as VerifyEmailResponse;\n};\n\nfunction useVerifyEmailMutation() {\n\treturn useMutation<VerifyEmailResponse, Error, VerifyEmailToken>({\n\t\tmutationFn: (emailToken) => onVerifyEmailTokenSubmit(emailToken),\n\t});\n}\n\nexport type { VerifyEmailResponse, VerifyEmailToken };\nexport { useVerifyEmailMutation };\n","import { Button } from '@/components/ui/button';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { zodRequireEmail } from '@/lib/zod/email';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useNavigate, useSearch } from '@tanstack/react-router';\nimport { useCallback, useEffect } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\nimport { useResendEmailVerification } from './hooks/useResendEmailVerification';\nimport { useVerifyEmailMutation, VerifyEmailToken } from './hooks/useVerifyEmail';\n\nconst VerifyEmailSchema = z.object({\n\temail: zodRequireEmail,\n});\n\nfunction SendEmailVerification() {\n\tconst navigate = useNavigate();\n\tconst { mutate: submitResendEmailVerification, isPending } = useResendEmailVerification();\n\tconst methods = useForm({\n\t\tresolver: zodResolver(VerifyEmailSchema),\n\t\tdefaultValues: {\n\t\t\temail: '',\n\t\t},\n\t});\n\tconst email = methods.watch('email');\n\tconst { setFocus, control, handleSubmit } = methods;\n\n\tuseEffect(() => {\n\t\tsetFocus('email');\n\t}, [setFocus]);\n\n\tconst submitForm = useCallback(async (formData: z.infer<typeof VerifyEmailSchema>) => {\n\t\tsubmitResendEmailVerification(formData, {\n\t\t\tonSuccess: (message) => {\n\t\t\t\ttoast.success('Success', {\n\t\t\t\t\tdescription: `${message}`,\n\t\t\t\t\taction: {\n\t\t\t\t\t\tlabel: 'Dismiss',\n\t\t\t\t\t\tonClick: () => toast.dismiss(),\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tnavigate({ to: '/sign-in', search: { me: email } });\n\t\t\t},\n\t\t});\n\t}, [email, navigate, submitResendEmailVerification]);\n\n\treturn (\n\t\t<Form {...methods}>\n\t\t\t<p className=\"text-sm py-2\">Please Enter an Email</p>\n\t\t\t<form\n\t\t\t\tid=\"auth-verify-email-form\"\n\t\t\t\tname=\"auth-verify-email-form\"\n\t\t\t\tonSubmit={handleSubmit(submitForm)}\n\t\t\t\tclassName=\"my-4\"\n\t\t\t>\n\t\t\t\t<FormField\n\t\t\t\t\tcontrol={control}\n\t\t\t\t\tname=\"email\"\n\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t<FormItem className=\"my-2\">\n\t\t\t\t\t\t\t<FormLabel>Email</FormLabel>\n\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\tdisabled={isPending}\n\t\t\t\t\t\t\t\t\ttype=\"email\"\n\t\t\t\t\t\t\t\t\tclassName=\"dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t)}\n\t\t\t\t/>\n\t\t\t\t<Button type=\"submit\" variant=\"submit\" disabled={isPending} className=\"w-full my-2 rounded-full\">\n\t\t\t\t\tSend Verification Email\n\t\t\t\t</Button>\n\t\t\t</form>\n\t\t</Form>\n\t);\n}\n\nexport function VerifyEmail() {\n\tconst { token } = useSearch({ strict: false });\n\tconst navigate = useNavigate();\n\n\tconst { mutate: submitEmailVerificationToken, isPending } = useVerifyEmailMutation();\n\n\tconst submitEmailToken = useCallback(\n\t\t(emailToken: VerifyEmailToken) => {\n\t\t\tsubmitEmailVerificationToken(emailToken, {\n\t\t\t\tonSuccess: () => {\n\t\t\t\t\ttoast.success('Success', {\n\t\t\t\t\t\tdescription: 'Email verified successfully',\n\t\t\t\t\t\taction: {\n\t\t\t\t\t\t\tlabel: 'Dismiss',\n\t\t\t\t\t\t\tonClick: () => toast.dismiss(),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t\tvoid navigate({ to: '/sign-in' });\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t\t[submitEmailVerificationToken, navigate],\n\t);\n\n\tuseEffect(() => {\n\t\tif (token) {\n\t\t\tsubmitEmailToken(token);\n\t\t}\n\t}, [submitEmailToken, token]);\n\n\treturn (\n\t\t<div className=\"text-foreground dark:text-white w-xs\">\n\t\t\t<h1 className=\"text-3xl font-light\">Verify Email</h1>\n\t\t\t{!isPending ? <SendEmailVerification /> : <p className=\"text-sm pt-1\">Verifying email...</p>}\n\t\t</div>\n\t);\n}\n","import { Link, useSearch } from '@tanstack/react-router';\nimport { MouseEvent, useCallback } from 'react';\nimport { toast } from 'sonner';\nimport { useResendEmailVerification } from './hooks/useResendEmailVerification';\n\nexport function Verifying() {\n\tconst { email }: { email?: string } = useSearch({ strict: false });\n\n\tconst { mutate: resendEmailVerification, isPending } = useResendEmailVerification();\n\n\tconst resendCode = useCallback((e: MouseEvent) => {\n\t\te.preventDefault();\n\t\tif (email) {\n\t\t\tresendEmailVerification({ email }, {\n\t\t\t\tonSuccess: (message) => {\n\t\t\t\t\ttoast.success('Code Sent', {\n\t\t\t\t\t\tdescription: `${message}`,\n\t\t\t\t\t\taction: {\n\t\t\t\t\t\t\tlabel: 'Dismiss',\n\t\t\t\t\t\t\tonClick: () => toast.dismiss(),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t\treturn false;\n\t}, [email, resendEmailVerification]);\n\n\treturn (\n\t\t<div className=\"text-foreground dark:text-white w-lg flex flex-col gap-4\">\n\t\t\t<h1 className=\"text-3xl font-light\">\n\t\t\t\t<span\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tclassName=\"text-2xl animate-flower-dance mr-4\"\n\t\t\t\t\ttitle=\"Loading\"\n\t\t\t\t>\n\t\t\t\t\t🌼\n\t\t\t\t</span>\n\t\t\t\tCheck your email!\n\t\t\t</h1>\n\t\t\t<p>\n\t\t\t\tYour account has been created! You should receive an email with a link to <strong>[Verify My Email]</strong>!\n\t\t\t</p>\n\t\t\t<p>\n\t\t\t\tFrom: <strong>harper@notifications.harperfabric.com</strong>\n\t\t\t</p>\n\t\t\t<p>\n\t\t\t\tTo: <strong>{email || 'your email'}</strong>\n\t\t\t</p>\n\t\t\t<p>Can you click it? Then we can carry on to more fun things!</p>\n\n\t\t\t<div className=\"underline flex gap-4\">\n\t\t\t\t<Link\n\t\t\t\t\tclassName=\"text-sm text-muted-foreground hover:text-foreground dark:text-inherit dark:hover:text-blue-300\"\n\t\t\t\t\tto=\"/sign-in\"\n\t\t\t\t\tsearch={{ me: email }}\n\t\t\t\t>\n\t\t\t\t\tI did it, let me sign in!\n\t\t\t\t</Link>\n\t\t\t\t<Link\n\t\t\t\t\tclassName=\"text-sm opacity-50 text-muted-foreground hover:text-foreground dark:text-inherit dark:hover:text-blue-300\"\n\t\t\t\t\tto={undefined}\n\t\t\t\t\tonClick={resendCode}\n\t\t\t\t\tdisabled={isPending}\n\t\t\t\t>\n\t\t\t\t\tSend me another code, please.\n\t\t\t\t</Link>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n","import { defaultInstanceRoute } from '@/config/constants';\nimport { getDefaultSignedInCloudRouteForUser } from '@/lib/urls/getDefaultSignedInCloudRouteForUser';\nimport { rootRoute } from '@/router/rootRoute';\nimport { createRoute, redirect } from '@tanstack/react-router';\nimport { AuthLayout } from './AuthLayout';\nimport { CheckOAuth } from './CheckOAuth';\nimport { ClusterInstanceSignIn } from './ClusterInstanceSignIn';\nimport { ForgotPassword } from './ForgotPassword';\nimport { ResetPassword } from './ResetPassword';\nimport { SignIn } from './SignIn';\nimport { SignUp } from './SignUp';\nimport { OverallAppSignIn } from './store/authStore';\nimport { VerifyEmail } from './VerifyEmail';\nimport { Verifying } from './Verifying';\n\nconst authLayout = createRoute({\n\tgetParentRoute: () => rootRoute,\n\tid: '_authLayout',\n\tcomponent: AuthLayout,\n});\n\nconst signInRoute = createRoute({\n\tgetParentRoute: () => authLayout,\n\tpath: 'sign-in',\n\thead: () => ({ meta: [{ title: 'Sign In — Harper Fabric' }] }),\n\tcomponent: SignIn,\n\tbeforeLoad: ({ context, location }) => {\n\t\tconst user = context.authentication[OverallAppSignIn]?.user;\n\t\tif (user) {\n\t\t\tconst search: Record<string, string> = location?.search;\n\t\t\tconst defaultRoute = getDefaultSignedInCloudRouteForUser(user);\n\t\t\tthrow redirect({ to: search?.redirect?.startsWith('/') ? search.redirect : defaultRoute });\n\t\t}\n\t},\n});\n\nconst localSignInRoute = createRoute({\n\tgetParentRoute: () => rootRoute,\n\tpath: 'sign-in',\n\thead: () => ({ meta: [{ title: 'Sign In — Harper Fabric' }] }),\n\tcomponent: ClusterInstanceSignIn,\n\tbeforeLoad: ({ context, location }) => {\n\t\tif (context.authentication[OverallAppSignIn]?.user) {\n\t\t\tconst search: Record<string, string> = location?.search;\n\t\t\tthrow redirect({ to: search?.redirect?.startsWith('/') ? search.redirect : defaultInstanceRoute });\n\t\t}\n\t},\n});\n\nconst signUpRoute = createRoute({\n\tgetParentRoute: () => authLayout,\n\tpath: 'sign-up',\n\thead: () => ({ meta: [{ title: 'Sign Up — Harper Fabric' }] }),\n\tcomponent: SignUp,\n});\nconst forgotPasswordRoute = createRoute({\n\tgetParentRoute: () => authLayout,\n\tpath: 'forgot-password',\n\thead: () => ({ meta: [{ title: 'Forgot Password — Harper Fabric' }] }),\n\tcomponent: ForgotPassword,\n});\n\nconst verifyEmailRoute = createRoute({\n\tgetParentRoute: () => authLayout,\n\tpath: 'verify-email',\n\thead: () => ({ meta: [{ title: 'Verify Email — Harper Fabric' }] }),\n\tcomponent: VerifyEmail,\n});\n\nconst verifyingEmailRoute = createRoute({\n\tgetParentRoute: () => authLayout,\n\tpath: 'verifying',\n\thead: () => ({ meta: [{ title: 'Check Your Email — Harper Fabric' }] }),\n\tcomponent: Verifying,\n});\n\nconst checkOAuthRoute = createRoute({\n\tgetParentRoute: () => authLayout,\n\tpath: 'check-oauth',\n\thead: () => ({ meta: [{ title: 'Signing In — Harper Fabric' }] }),\n\tcomponent: CheckOAuth,\n});\n\nconst resetPasswordRoute = createRoute({\n\tgetParentRoute: () => authLayout,\n\tpath: 'reset-password',\n\thead: () => ({ meta: [{ title: 'Reset Password — Harper Fabric' }] }),\n\tcomponent: ResetPassword,\n});\n\nexport const authRouteTree = authLayout.addChildren([\n\tsignInRoute,\n\tsignUpRoute,\n\tcheckOAuthRoute,\n\tforgotPasswordRoute,\n\tverifyEmailRoute,\n\tverifyingEmailRoute,\n\tresetPasswordRoute,\n]);\n\nexport const localAuthRoutes = [\n\tlocalSignInRoute,\n];\n","import { Breadcrumbs } from '@/components/Breadcrumbs';\nimport { ReactNode } from 'react';\n\nexport function SubNavMenu({ children }: { children?: ReactNode }) {\n\treturn (\n\t\t<nav className=\"fixed top-20 w-full h-12 z-39 py-2 px-4 md:px-12 bg-violet-50 border-b border-violet-100 dark:bg-grey-700 dark:border-none\">\n\t\t\t<div className=\"flex items-center h-full space-x-2\">\n\t\t\t\t<Breadcrumbs />\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t</nav>\n\t);\n}\n","export type BadgeStatusVariant =\n\t| string\n\t| 'PROVISIONING'\n\t| 'CLONE_PENDING'\n\t| 'PENDING_UPGRADE'\n\t| 'UPDATING_HDB_NODES'\n\t| 'DRAINING'\n\t| 'UPDATING'\n\t| 'CLONE_READY'\n\t| 'RUNNING'\n\t| 'UPDATED'\n\t| 'STOPPED'\n\t| 'FAILED'\n\t| 'TERMINATED'\n\t| 'TERMINATING'\n\t| 'ERROR'\n\t| 'REMOVED';\n\nexport type BadgeStatusVariantValues = 'warning' | 'success' | 'secondary' | 'destructive' | 'outline' | 'default';\n\nexport function renderBadgeStatusVariant(value: BadgeStatusVariant): BadgeStatusVariantValues {\n\tif (isPendingUpdate(value) || isBeingUpdated(value)) {\n\t\treturn 'warning';\n\t}\n\tif (isRunning(value)) {\n\t\treturn 'success';\n\t}\n\tswitch (value) {\n\t\tcase 'STOPPED':\n\t\t\treturn 'secondary';\n\t\tcase 'TERMINATING':\n\t\tcase 'TERMINATED':\n\t\tcase 'FAILED':\n\t\tcase 'REMOVED':\n\t\tcase 'ERROR':\n\t\t\treturn 'destructive';\n\t\tdefault:\n\t\t\treturn 'default';\n\t}\n}\n\nexport function isRunning(value: string | undefined): value is 'RUNNING' | 'UPDATED' {\n\tswitch (value) {\n\t\tcase 'RUNNING':\n\t\tcase 'UPDATED':\n\t\t\treturn true;\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\nexport function isFailed(value: string | undefined): value is 'FAILED' {\n\tswitch (value) {\n\t\tcase 'FAILED':\n\t\t\treturn true;\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\nexport function isTerminated(value: string | undefined): value is 'TERMINATED' {\n\tswitch (value) {\n\t\tcase 'TERMINATED':\n\t\t\treturn true;\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\nexport function isPendingUpdate(value: string | undefined): value is 'CLONE_PENDING' | 'PENDING_UPGRADE' {\n\tswitch (value) {\n\t\tcase 'CLONE_PENDING':\n\t\tcase 'PENDING_UPGRADE':\n\t\t\treturn true;\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\nexport function isBeingUpdated(\n\tvalue: string | undefined,\n): value is 'PROVISIONING' | 'CLONING' | 'CLONE_READY' | 'UPDATING_HDB_NODES' | 'DRAINING' | 'UPDATING' {\n\tswitch (value) {\n\t\tcase 'PROVISIONING':\n\t\tcase 'CLONING':\n\t\tcase 'CLONE_READY':\n\t\tcase 'UPDATING_HDB_NODES':\n\t\tcase 'DRAINING':\n\t\tcase 'UPDATING':\n\t\t\treturn true;\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n","import * as DialogPrimitive from '@radix-ui/react-dialog';\nimport { XIcon } from 'lucide-react';\nimport * as React from 'react';\n\nimport { cn } from '@/lib/cn';\n\nfunction Dialog({ ...props }: React.ComponentProps<typeof DialogPrimitive.Root>) {\n\treturn <DialogPrimitive.Root data-slot=\"dialog\" {...props} />;\n}\n\nfunction DialogTrigger({ ...props }: React.ComponentProps<typeof DialogPrimitive.Trigger>) {\n\treturn <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />;\n}\n\nfunction DialogPortal({ ...props }: React.ComponentProps<typeof DialogPrimitive.Portal>) {\n\treturn <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />;\n}\n\nfunction DialogClose({ ...props }: React.ComponentProps<typeof DialogPrimitive.Close>) {\n\treturn <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />;\n}\n\nfunction DialogOverlay({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n\treturn (\n\t\t<DialogPrimitive.Overlay\n\t\t\tdata-slot=\"dialog-overlay\"\n\t\t\tclassName={cn(\n\t\t\t\t'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-white/80 backdrop-blur-xs dark:bg-black-dark/90 dark:backdrop-blur-none',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nfunction DialogContent({ className, children, ...props }: React.ComponentProps<typeof DialogPrimitive.Content>) {\n\treturn (\n\t\t<DialogPortal data-slot=\"dialog-portal\">\n\t\t\t<DialogOverlay />\n\t\t\t<DialogPrimitive.Content\n\t\t\t\tdata-slot=\"dialog-content\"\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'bg-popover '\n\t\t\t\t\t\t+ 'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 '\n\t\t\t\t\t\t+ 'fixed top-[50%] left-[50%] z-50 grid '\n\t\t\t\t\t\t+ 'w-full max-w-[calc(100%-2rem)] lg:max-w-2xl '\n\t\t\t\t\t\t+ 'max-h-screen overflow-y-auto '\n\t\t\t\t\t\t+ 'translate-x-[-50%] translate-y-[-50%] '\n\t\t\t\t\t\t+ 'gap-4 rounded-md border p-6 shadow-2xl '\n\t\t\t\t\t\t+ 'duration-200',\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t\t<DialogPrimitive.Close className=\"ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\">\n\t\t\t\t\t<XIcon className=\"text-popover-foreground\" />\n\t\t\t\t\t<span className=\"sr-only\">Close</span>\n\t\t\t\t</DialogPrimitive.Close>\n\t\t\t</DialogPrimitive.Content>\n\t\t</DialogPortal>\n\t);\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<'div'>) {\n\treturn (\n\t\t<div\n\t\t\tdata-slot=\"dialog-header\"\n\t\t\tclassName={cn('flex flex-col gap-2 text-center sm:text-left', className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nfunction DialogFooter({ className, ...props }: React.ComponentProps<'div'>) {\n\treturn (\n\t\t<div\n\t\t\tdata-slot=\"dialog-footer\"\n\t\t\tclassName={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nfunction DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>) {\n\treturn (\n\t\t<DialogPrimitive.Title\n\t\t\tdata-slot=\"dialog-title\"\n\t\t\tclassName={cn('text-lg leading-none text-popover-foreground font-semibold', className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nfunction DialogDescription({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Description>) {\n\treturn (\n\t\t<DialogPrimitive.Description\n\t\t\tdata-slot=\"dialog-description\"\n\t\t\tclassName={cn('text-muted-foreground text-sm', className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport {\n\tDialog,\n\tDialogClose,\n\tDialogContent,\n\tDialogDescription,\n\tDialogFooter,\n\tDialogHeader,\n\tDialogOverlay,\n\tDialogPortal,\n\tDialogTitle,\n\tDialogTrigger,\n};\n","import { Button } from '@/components/ui/button';\nimport {\n\tDialog,\n\tDialogContent,\n\tDialogDescription,\n\tDialogFooter,\n\tDialogHeader,\n\tDialogTitle,\n\tDialogTrigger,\n} from '@/components/ui/dialog';\nimport { ArrowLeft, Trash, TriangleAlert } from 'lucide-react';\nimport { ReactNode } from 'react';\n\nexport function ConfirmDeletionModal({\n\ttypeOfThingBeingDeleted,\n\tnameOfThingBeingDeleted,\n\tisModalOpen,\n\thideDataLossWarning,\n\tsetIsModalOpen,\n\tdeletionConfirmed,\n\tdeletionPending,\n\ttrigger,\n\tpresentParticiple = 'Deleting',\n\ttransitiveVerb = 'Delete',\n}: {\n\ttypeOfThingBeingDeleted: string;\n\tnameOfThingBeingDeleted?: string;\n\tisModalOpen: boolean;\n\thideDataLossWarning?: boolean;\n\tsetIsModalOpen: (isOpen: boolean) => void;\n\tdeletionConfirmed: () => void;\n\tdeletionPending: boolean;\n\ttrigger?: ReactNode;\n\tpresentParticiple?: 'Deleting' | 'Terminating' | string;\n\ttransitiveVerb?: 'Delete' | 'Terminate' | string;\n}) {\n\treturn (\n\t\t<Dialog open={isModalOpen} onOpenChange={setIsModalOpen}>\n\t\t\t{trigger && (\n\t\t\t\t<DialogTrigger asChild>\n\t\t\t\t\t{trigger}\n\t\t\t\t</DialogTrigger>\n\t\t\t)}\n\t\t\t<DialogContent className=\"sm:max-w-[750px]\">\n\t\t\t\t<DialogHeader>\n\t\t\t\t\t<DialogTitle>\n\t\t\t\t\t\tAre you sure you want to {transitiveVerb.toLowerCase()} this {typeOfThingBeingDeleted}?\n\t\t\t\t\t</DialogTitle>\n\t\t\t\t\t<DialogDescription>This action cannot be undone.</DialogDescription>\n\t\t\t\t</DialogHeader>\n\t\t\t\t{!hideDataLossWarning && (\n\t\t\t\t\t<div className=\"p-3 my-5 text-white rounded-md bg-amber-600\">\n\t\t\t\t\t\t<p className=\"flex space-x-1 font-semibold align-baseline\">\n\t\t\t\t\t\t\t<TriangleAlert className=\"inline-block size-5\" /> <span>Warning</span>\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<p className=\"pt-2 text-base\">\n\t\t\t\t\t\t\tBy {presentParticiple.toLowerCase()} {typeOfThingBeingDeleted}{' '}\n\t\t\t\t\t\t\t<span className=\"font-semibold\">{nameOfThingBeingDeleted}</span>{' '}\n\t\t\t\t\t\t\tyou will lose the data stored in it permanently.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t\t<DialogFooter>\n\t\t\t\t\t<div className=\"flex justify-center space-x-5\">\n\t\t\t\t\t\t<Button type=\"button\" className=\"rounded-full\" onClick={() => setIsModalOpen(false)}>\n\t\t\t\t\t\t\t<ArrowLeft /> Cancel\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tvariant=\"destructive\"\n\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\tonClick={deletionConfirmed}\n\t\t\t\t\t\t\tdisabled={deletionPending}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Trash /> {transitiveVerb}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</div>\n\t\t\t\t</DialogFooter>\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n}\n","import { badgeVariants } from '@/components/ui/badgeVariants';\nimport { cn } from '@/lib/cn';\nimport { Slot } from '@radix-ui/react-slot';\nimport { type VariantProps } from 'class-variance-authority';\nimport * as React from 'react';\n\nexport function Badge({\n\tclassName,\n\tvariant,\n\tasChild = false,\n\t...props\n}: React.ComponentProps<'span'> & VariantProps<typeof badgeVariants> & { asChild?: boolean }) {\n\tconst Comp = asChild ? Slot : 'span';\n\n\treturn <Comp data-slot=\"badge\" className={cn(badgeVariants({ variant }), className)} {...props} />;\n}\n","import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from 'lucide-react';\nimport * as React from 'react';\n\nimport { cn } from '@/lib/cn';\n\nfunction DropdownMenu({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n\treturn <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />;\n}\n\nfunction DropdownMenuPortal({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n\treturn <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />;\n}\n\nfunction DropdownMenuTrigger({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n\treturn <DropdownMenuPrimitive.Trigger data-slot=\"dropdown-menu-trigger\" {...props} />;\n}\n\nfunction DropdownMenuContent({\n\tclassName,\n\tsideOffset = 4,\n\t...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n\treturn (\n\t\t<DropdownMenuPrimitive.Portal>\n\t\t\t<DropdownMenuPrimitive.Content\n\t\t\t\tdata-slot=\"dropdown-menu-content\"\n\t\t\t\tsideOffset={sideOffset}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border border-border p-1 shadow-md',\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t</DropdownMenuPrimitive.Portal>\n\t);\n}\n\nfunction DropdownMenuGroup({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n\treturn <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />;\n}\n\nfunction DropdownMenuItem({\n\tclassName,\n\tinset,\n\tvariant = 'default',\n\t...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n\tinset?: boolean;\n\tvariant?: 'default' | 'destructive';\n}) {\n\treturn (\n\t\t<DropdownMenuPrimitive.Item\n\t\t\tdata-slot=\"dropdown-menu-item\"\n\t\t\tdata-inset={inset}\n\t\t\tdata-variant={variant}\n\t\t\tclassName={cn(\n\t\t\t\t'focus:bg-accent focus:text-grey',\n\t\t\t\t'data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10',\n\t\t\t\t'dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive',\n\t\t\t\t\"data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground\",\n\t\t\t\t'relative flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm',\n\t\t\t\t'outline-hidden select-none',\n\t\t\t\t'data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8',\n\t\t\t\t\"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nfunction DropdownMenuCheckboxItem({\n\tclassName,\n\tchildren,\n\tchecked,\n\t...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n\treturn (\n\t\t<DropdownMenuPrimitive.CheckboxItem\n\t\t\tdata-slot=\"dropdown-menu-checkbox-item\"\n\t\t\tclassName={cn(\n\t\t\t\t'focus:bg-accent focus:text-accent-foreground relative flex cursor-pointer items-center gap-2 rounded-sm',\n\t\t\t\t'py-1.5 pr-2 pl-8',\n\t\t\t\t'text-sm outline-hidden',\n\t\t\t\t'select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n\t\t\t\t\"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\tchecked={checked}\n\t\t\t{...props}\n\t\t>\n\t\t\t<span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n\t\t\t\t<DropdownMenuPrimitive.ItemIndicator>\n\t\t\t\t\t<CheckIcon className=\"size-4\" />\n\t\t\t\t</DropdownMenuPrimitive.ItemIndicator>\n\t\t\t</span>\n\t\t\t{children}\n\t\t</DropdownMenuPrimitive.CheckboxItem>\n\t);\n}\n\nfunction DropdownMenuRadioGroup({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n\treturn <DropdownMenuPrimitive.RadioGroup data-slot=\"dropdown-menu-radio-group\" {...props} />;\n}\n\nfunction DropdownMenuRadioItem({\n\tclassName,\n\tchildren,\n\t...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n\treturn (\n\t\t<DropdownMenuPrimitive.RadioItem\n\t\t\tdata-slot=\"dropdown-menu-radio-item\"\n\t\t\tclassName={cn(\n\t\t\t\t\"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n\t\t\t\t<DropdownMenuPrimitive.ItemIndicator>\n\t\t\t\t\t<CircleIcon className=\"size-2 fill-current\" />\n\t\t\t\t</DropdownMenuPrimitive.ItemIndicator>\n\t\t\t</span>\n\t\t\t{children}\n\t\t</DropdownMenuPrimitive.RadioItem>\n\t);\n}\n\nfunction DropdownMenuLabel({\n\tclassName,\n\tinset,\n\t...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n\tinset?: boolean;\n}) {\n\treturn (\n\t\t<DropdownMenuPrimitive.Label\n\t\t\tdata-slot=\"dropdown-menu-label\"\n\t\t\tdata-inset={inset}\n\t\t\tclassName={cn('px-2 py-1.5 text-sm font-medium data-[inset]:pl-8', className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nfunction DropdownMenuSeparator({ className, ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n\treturn (\n\t\t<DropdownMenuPrimitive.Separator\n\t\t\tdata-slot=\"dropdown-menu-separator\"\n\t\t\tclassName={cn('bg-border -mx-1 my-1 h-px', className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nfunction DropdownMenuShortcut({ className, ...props }: React.ComponentProps<'span'>) {\n\treturn (\n\t\t<span\n\t\t\tdata-slot=\"dropdown-menu-shortcut\"\n\t\t\tclassName={cn('text-muted-foreground ml-auto text-xs tracking-widest', className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nfunction DropdownMenuSub({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n\treturn <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />;\n}\n\nfunction DropdownMenuSubTrigger({\n\tclassName,\n\tinset,\n\tchildren,\n\t...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n\tinset?: boolean;\n}) {\n\treturn (\n\t\t<DropdownMenuPrimitive.SubTrigger\n\t\t\tdata-slot=\"dropdown-menu-sub-trigger\"\n\t\t\tdata-inset={inset}\n\t\t\tclassName={cn(\n\t\t\t\t'focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground',\n\t\t\t\t'flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none',\n\t\t\t\t'data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0',\n\t\t\t\t\"[&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t\t<ChevronRightIcon className=\"ml-auto size-4\" />\n\t\t</DropdownMenuPrimitive.SubTrigger>\n\t);\n}\n\nfunction DropdownMenuSubContent({\n\tclassName,\n\t...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n\treturn (\n\t\t<DropdownMenuPrimitive.SubContent\n\t\t\tdata-slot=\"dropdown-menu-sub-content\"\n\t\t\tclassName={cn(\n\t\t\t\t'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport {\n\tDropdownMenu,\n\tDropdownMenuCheckboxItem,\n\tDropdownMenuContent,\n\tDropdownMenuGroup,\n\tDropdownMenuItem,\n\tDropdownMenuLabel,\n\tDropdownMenuPortal,\n\tDropdownMenuRadioGroup,\n\tDropdownMenuRadioItem,\n\tDropdownMenuSeparator,\n\tDropdownMenuShortcut,\n\tDropdownMenuSub,\n\tDropdownMenuSubContent,\n\tDropdownMenuSubTrigger,\n\tDropdownMenuTrigger,\n};\n","import { Cluster } from '@/integrations/api/api.patch';\n\nexport function clusterIsSelfManaged(cluster: Cluster | undefined): boolean {\n\treturn !!cluster?.plans?.[0]?.planId?.startsWith('self-hosted');\n}\n","import { Button } from '@/components/ui/button';\nimport { defaultInstanceRoute } from '@/config/constants';\nimport { authStore } from '@/features/auth/store/authStore';\nimport { useInstanceAuth } from '@/hooks/useAuth';\nimport { useOrganizationClusterPermissions } from '@/hooks/usePermissions';\nimport { Cluster } from '@/integrations/api/api.patch';\nimport { clusterIsSelfManaged } from '@/integrations/api/clusterIsSelfManaged';\nimport { Link } from '@tanstack/react-router';\nimport { ArrowRight } from 'lucide-react';\nimport { useCallback } from 'react';\n\nexport function ClusterCardAction({ cluster }: { cluster: Cluster }) {\n\tconst auth = useInstanceAuth(cluster.id);\n\tconst { view, update } = useOrganizationClusterPermissions(cluster.organizationId, cluster.id);\n\tconst isFabricConnect = authStore.checkForFabricConnect(cluster.id);\n\tconst isDirectConnect = !isFabricConnect && !!auth.user;\n\tconst prepareForDirectSignIn = useCallback(() => {\n\t\tauthStore.setUserForEntity(cluster, null);\n\t\tauthStore.flagForFabricConnect(cluster.id, false);\n\t}, [cluster]);\n\n\tif (!view) {\n\t\treturn undefined;\n\t}\n\n\tif (!cluster.fqdn) {\n\t\treturn (\n\t\t\t<Link\n\t\t\t\tto={`/${cluster.organizationId}/${cluster.id}/instances`}\n\t\t\t\tclassName=\"text-sm text-nowrap\"\n\t\t\t\taria-label={`View ${cluster.name}`}\n\t\t\t\ttitle={`View ${cluster.name}`}\n\t\t\t>\n\t\t\t\t<span className=\"py-2 hover:border-b-2\">\n\t\t\t\t\tInstances <ArrowRight className=\"inline-block\" />\n\t\t\t\t</span>\n\t\t\t</Link>\n\t\t);\n\t}\n\n\tif (cluster.resetPassword) {\n\t\tif (update) {\n\t\t\treturn (\n\t\t\t\t<Link\n\t\t\t\t\tto={`/${cluster.organizationId}/${cluster.id}/finish-setup`}\n\t\t\t\t\tclassName=\"text-sm text-nowrap\"\n\t\t\t\t\taria-label={`Set Password on ${cluster.name}`}\n\t\t\t\t\ttitle={`Set Password on ${cluster.name}`}\n\t\t\t\t>\n\t\t\t\t\t<Button variant=\"positive\" className=\"py-2 hover:border-b-2 animate-glow-pulse\">\n\t\t\t\t\t\tFinish Setup <ArrowRight className=\"inline-block\" />\n\t\t\t\t\t</Button>\n\t\t\t\t</Link>\n\t\t\t);\n\t\t}\n\t\treturn (\n\t\t\t<span className=\"py-2 text-nowrap\">\n\t\t\t\tPending Owner Setup\n\t\t\t</span>\n\t\t);\n\t}\n\n\tif (auth.isLoading) {\n\t\treturn undefined;\n\t}\n\n\tif (isDirectConnect) {\n\t\treturn (\n\t\t\t<Link\n\t\t\t\tto={`/${cluster.organizationId}/${cluster.id}${defaultInstanceRoute}`}\n\t\t\t\tclassName=\"text-sm text-nowrap\"\n\t\t\t\taria-label={`View ${cluster.name}`}\n\t\t\t\ttitle={`View ${cluster.name}`}\n\t\t\t>\n\t\t\t\t<span className=\"py-2 hover:border-b-2\">\n\t\t\t\t\tDirect Connect <ArrowRight className=\"inline-block\" />\n\t\t\t\t</span>\n\t\t\t</Link>\n\t\t);\n\t}\n\n\tif (update && !clusterIsSelfManaged(cluster)) {\n\t\treturn (\n\t\t\t<Link\n\t\t\t\tto={`/${cluster.organizationId}/${cluster.id}${defaultInstanceRoute}`}\n\t\t\t\tclassName=\"text-sm text-nowrap\"\n\t\t\t\taria-label={`Connect to ${cluster.name}`}\n\t\t\t\ttitle={`Connect to ${cluster.name}`}\n\t\t\t>\n\t\t\t\t<span className=\"py-2 hover:border-b-2\">\n\t\t\t\t\tFabric Connect <ArrowRight className=\"inline-block\" />\n\t\t\t\t</span>\n\t\t\t</Link>\n\t\t);\n\t}\n\n\treturn (\n\t\t<Link\n\t\t\tto={`/${cluster.organizationId}/${cluster.id}/sign-in`}\n\t\t\tclassName=\"text-sm text-nowrap\"\n\t\t\taria-label={`Sign In to ${cluster.name}`}\n\t\t\ttitle={`Sign In to ${cluster.name}`}\n\t\t\tonClick={prepareForDirectSignIn}\n\t\t>\n\t\t\t<span className=\"py-2 hover:border-b-2\">\n\t\t\t\tDirect Sign In <ArrowRight className=\"inline-block\" />\n\t\t\t</span>\n\t\t</Link>\n\t);\n}\n","export function mapBy<T, F extends keyof T>(array: T[], fieldName: F): T[F][] {\n\tconst values: T[F][] = [];\n\tif (array) {\n\t\tfor (const element of array) {\n\t\t\tvalues.push(element[fieldName]);\n\t\t}\n\t}\n\treturn values;\n}\n","import { isBeingUpdated, isFailed, isPendingUpdate, isRunning, isTerminated } from '@/components/ui/utils/badgeStatus';\nimport { getClusterInfoQueryOptions } from '@/features/cluster/queries/getClusterInfoQuery';\nimport { Cluster } from '@/integrations/api/api.patch';\nimport { mapBy } from '@/lib/arrays/mapBy';\nimport { capitalizeWords } from '@/lib/string/capitalizeWords';\nimport { useQuery } from '@tanstack/react-query';\nimport { useEffect, useMemo, useState } from 'react';\n\n/**\n * Displays a triple segment progress bar to the user which will let them watch their instance(s) progress through:\n * \t1. Pending (Clone Pending or Clone Ready)\n * \t2. Updating (Provisioning or Cloning)\n * \t3. Running (Running or Updated)\n */\nexport function ClusterProgress({ cluster, forceProgressBarVisible }: {\n\tcluster: Pick<Cluster, 'status' | 'id'>;\n\tforceProgressBarVisible?: boolean;\n}) {\n\tconst [showProgress, setShowProgress] = useState(forceProgressBarVisible || false);\n\n\tconst { data: clusterById } = useQuery(\n\t\tgetClusterInfoQueryOptions(showProgress && cluster.id, 2_000),\n\t);\n\n\tuseEffect(function showProgressIfPendingOrUpdating() {\n\t\tif (isPendingUpdate(cluster.status) || isBeingUpdated(cluster.status)) {\n\t\t\t// If the cluster is ever pending or updating, we want the progress bar to stick open for that card until they\n\t\t\t// navigate away or refresh. So we can setShowProgress to true safely.\n\t\t\t// eslint-disable-next-line react-hooks/set-state-in-effect\n\t\t\tsetShowProgress(true);\n\t\t}\n\t}, [showProgress, cluster.status, clusterById?.instances]);\n\n\tconst updating = useMemo(() => {\n\t\tconst activePlanIds = mapBy(clusterById?.plans ?? [], 'planId');\n\t\tconst instances = clusterById?.instances ?? [];\n\t\tlet pending = 0;\n\t\tconst pendingTexts: Record<string, string> = {};\n\t\tlet updating = 0;\n\t\tconst updatingTexts: Record<string, string> = {};\n\t\tlet running = 0;\n\t\tconst runningTexts: Record<string, string> = {};\n\t\tlet failed = 0;\n\t\tconst failedTexts: Record<string, string> = {};\n\t\tfor (const instance of instances) {\n\t\t\tconst status = instance.status;\n\t\t\tif (!status || isTerminated(status)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (isPendingUpdate(status)) {\n\t\t\t\tpending += 1;\n\t\t\t\tpendingTexts[status] = `${pending} ${capitalizeWords(status)}`;\n\t\t\t} else if (isBeingUpdated(status)) {\n\t\t\t\tupdating += 1;\n\t\t\t\tupdatingTexts[status] = `${updating} ${capitalizeWords(status)}`;\n\t\t\t} else if (isFailed(status)) {\n\t\t\t\tfailed += 1;\n\t\t\t\tfailedTexts[status] = `${failed} ${capitalizeWords(status)}`;\n\t\t\t} else if (!instance.planId || !activePlanIds.includes(instance.planId)) {\n\t\t\t\tupdating += 1;\n\t\t\t\tupdatingTexts['DRAINING_TRAFFIC'] = `${updating} ${capitalizeWords('Draining Traffic')}`;\n\t\t\t} else if (isRunning(status)) {\n\t\t\t\trunning += 1;\n\t\t\t\trunningTexts[status] = `${running} ${capitalizeWords(status)}`;\n\t\t\t}\n\t\t\t// We'll ignore terminated or non-updated instances from the totals.\n\t\t}\n\t\tconst total = pending + updating + running;\n\t\treturn {\n\t\t\tpendingWidth: `${total === 0 ? 100 : pending === 0 ? 0 : (pending / total * 100)}%`,\n\t\t\tupdatingWidth: `${updating === 0 ? 0 : (updating / total * 100)}%`,\n\t\t\tfailedWidth: `${failed === 0 ? 0 : (failed / total * 100)}%`,\n\t\t\trunningWidth: `${running === 0 ? 0 : (running / total * 100)}%`,\n\t\t\ttext: [\n\t\t\t\t...Object.values(runningTexts).sort(),\n\t\t\t\t...Object.values(failedTexts).sort(),\n\t\t\t\t...Object.values(updatingTexts).sort(),\n\t\t\t\t...Object.values(pendingTexts).sort(),\n\t\t\t].join(' · '),\n\t\t};\n\t}, [clusterById]);\n\n\tif (!showProgress) {\n\t\treturn null;\n\t}\n\treturn (\n\t\t<div className=\"w-full text-center\">\n\t\t\t<div className=\"w-full h-2.5 rounded-full overflow-clip flex shadow\">\n\t\t\t\t{/*Running*/}\n\t\t\t\t<div\n\t\t\t\t\tstyle={{ width: updating.runningWidth }}\n\t\t\t\t\tclassName=\"grow bg-green/80 transition-[width] duration-1000 ease-in-out motion-reduce:transition-none\"\n\t\t\t\t>\n\t\t\t\t</div>\n\t\t\t\t{/*Failed*/}\n\t\t\t\t<div\n\t\t\t\t\tstyle={{ width: updating.failedWidth }}\n\t\t\t\t\tclassName=\"grow bg-red/80 transition-[width] duration-1000 ease-in-out motion-reduce:transition-none\"\n\t\t\t\t>\n\t\t\t\t</div>\n\t\t\t\t{/*Updating*/}\n\t\t\t\t<div\n\t\t\t\t\tstyle={{ width: updating.updatingWidth }}\n\t\t\t\t\tclassName=\"grow animate-pulse bg-yellow/80 transition-[width] duration-1000 ease-in-out motion-reduce:transition-none\"\n\t\t\t\t>\n\t\t\t\t</div>\n\t\t\t\t{/*Pending*/}\n\t\t\t\t<div\n\t\t\t\t\tstyle={{ width: updating.pendingWidth }}\n\t\t\t\t\tclassName=\"grow bg-gray-600 transition-[width] duration-1000 ease-in-out motion-reduce:transition-none\"\n\t\t\t\t>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t{updating.text && <div className=\"text-xs text-muted-foreground font-light mt-2\">{updating.text}</div>}\n\t\t</div>\n\t);\n}\n","import { apiClient } from '@/config/apiClient';\nimport { useMutation } from '@tanstack/react-query';\n\nexport async function terminateCluster(clusterId: string) {\n\tconst { data } = await apiClient.delete(`/Cluster/${clusterId}` as '/Cluster/{id}', { timeout: 0 });\n\treturn data;\n}\n\nexport function useTerminateClusterMutation() {\n\treturn useMutation({\n\t\tmutationFn: (clusterId: string) => terminateCluster(clusterId),\n\t});\n}\n","import { ClipboardCheckIcon } from 'lucide-react';\nimport { useMemo } from 'react';\nimport { toast } from 'sonner';\n\nexport function useCopyToClipboard(...texts: string[]): Array<() => void> {\n\treturn useMemo(() => {\n\t\treturn texts.map(text => (() => {\n\t\t\tvoid navigator.clipboard.writeText(text);\n\t\t\ttoast.info('Copied to clipboard!', {\n\t\t\t\ticon: <ClipboardCheckIcon />,\n\t\t\t\tduration: 1000,\n\t\t\t});\n\t\t}));\n\t\t// We can override the linting here because we know we're providing an accurate list of dependencies that will only\n\t\t// change and trigger a re-render of the memo when the text contents change.\n\t\t// eslint-disable-next-line react-hooks/use-memo,react-hooks/exhaustive-deps\n\t}, texts);\n}\n","import { ConfirmDeletionModal } from '@/components/ConfirmDeletionModal';\nimport { Badge } from '@/components/ui/badge';\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';\nimport {\n\tDropdownMenu,\n\tDropdownMenuContent,\n\tDropdownMenuItem,\n\tDropdownMenuSeparator,\n\tDropdownMenuTrigger,\n} from '@/components/ui/dropdownMenu';\nimport { isFailed, renderBadgeStatusVariant } from '@/components/ui/utils/badgeStatus';\nimport { activeClusterStatuses, deletedClusterStatuses } from '@/config/clusterStatuses';\nimport { isLocalStudio } from '@/config/constants';\nimport { useInstanceClient } from '@/config/useInstanceClient';\nimport { authStore } from '@/features/auth/store/authStore';\nimport { getClusterInfo } from '@/features/cluster/queries/getClusterInfoQuery';\nimport { ClusterCardAction } from '@/features/clusters/components/ClusterCardAction';\nimport { ClusterProgress } from '@/features/clusters/components/ClusterProgress';\nimport { useTerminateClusterMutation } from '@/features/clusters/mutations/terminateCluster';\nimport { useInstanceAuth } from '@/hooks/useAuth';\nimport { useCopyToClipboard } from '@/hooks/useCopyToClipboard';\nimport { useLocalStorage } from '@/hooks/useLocalStorage';\nimport { useOrganizationClusterPermissions } from '@/hooks/usePermissions';\nimport { Cluster } from '@/integrations/api/api.patch';\nimport { clusterIsSelfManaged } from '@/integrations/api/clusterIsSelfManaged';\nimport { onInstanceLogoutSubmit } from '@/integrations/api/instance/auth/onInstanceLogoutSubmit';\nimport { excludeFalsy } from '@/lib/arrays/excludeFalsy';\nimport { LocalStorageKeys } from '@/lib/storage/localStorageKeys';\nimport { capitalizeWords } from '@/lib/string/capitalizeWords';\nimport { getOperationsUrlForCluster } from '@/lib/urls/getOperationsUrlForCluster';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { Link, useRouter } from '@tanstack/react-router';\nimport {\n\tClipboardIcon,\n\tCopyIcon,\n\tEllipsis,\n\tGitGraphIcon,\n\tGlobeIcon,\n\tKeyIcon,\n\tScaleIcon,\n\tServerIcon,\n\tTrashIcon,\n} from 'lucide-react';\nimport { useCallback, useMemo, useState } from 'react';\nimport { toast } from 'sonner';\n\nexport function ClusterCard({ cluster }: { cluster: Cluster }) {\n\tconst router = useRouter();\n\tconst queryClient = useQueryClient();\n\tconst operationsUrl = useMemo(() => getOperationsUrlForCluster(cluster), [cluster]);\n\tconst instanceClient = useInstanceClient({ operationsUrl });\n\tconst auth = useInstanceAuth(cluster.id);\n\tconst [, setSavedClusterState] = useLocalStorage<unknown | null>(LocalStorageKeys.SavedClusterState, null);\n\n\tconst { view, update, remove, create } = useOrganizationClusterPermissions(cluster.organizationId, cluster.id);\n\tconst { mutate: terminateCluster, isPending: isTerminateClusterPending } = useTerminateClusterMutation();\n\n\tconst [signingOut, setSigningOut] = useState(false);\n\tconst [isTerminateClusterModalOpen, setIsTerminateClusterModalOpen] = useState(false);\n\n\tconst isActive = useMemo(() => cluster.status && activeClusterStatuses.includes(cluster.status), [cluster.status]);\n\tconst isSelfManaged = clusterIsSelfManaged(cluster);\n\tconst isFabricConnect = authStore.checkForFabricConnect(cluster.id);\n\tconst isDirectConnect = !isFabricConnect && !!auth.user;\n\tconst isTerminated = useMemo(\n\t\t() => cluster.status && deletedClusterStatuses.includes(cluster.status),\n\t\t[cluster.status],\n\t);\n\tconst clusterHasFailed = useMemo(\n\t\t() => cluster.status && isFailed(cluster.status),\n\t\t[cluster.status],\n\t);\n\n\tconst onSignOutClick = useCallback(async () => {\n\t\tsetSigningOut(true);\n\t\tconst fullCluster = await getClusterInfo(cluster.id).catch((err) => {\n\t\t\tconsole.error('Failed to lookup cluster details, proceeding without checking instances.', err);\n\t\t\treturn null;\n\t\t});\n\t\tawait onInstanceLogoutSubmit({ entityId: cluster.id, instanceClient });\n\t\tif (fullCluster?.instances?.length) {\n\t\t\t// Flag all cluster instances as signed out as well.\n\t\t\tfor (const instance of fullCluster.instances) {\n\t\t\t\tauthStore.setUserForEntity(instance, null);\n\t\t\t}\n\t\t}\n\t\tauthStore.setUserForEntity(cluster, null);\n\t}, [cluster, instanceClient]);\n\n\tconst onTryAgainClick = useCallback(() => {\n\t\tsetSavedClusterState(cluster);\n\t\tvoid router.navigate({ to: `/${cluster.organizationId}/new-cluster` });\n\t}, [cluster, router, setSavedClusterState]);\n\n\tconst onTerminateClick = useCallback(() => setIsTerminateClusterModalOpen(true), []);\n\n\tconst handleTerminatedCluster = useCallback(() => {\n\t\tconst organizationId = cluster.organizationId;\n\t\tterminateCluster(cluster.id, {\n\t\t\tonSuccess: async () => {\n\t\t\t\tawait queryClient.invalidateQueries({\n\t\t\t\t\tqueryKey: [organizationId],\n\t\t\t\t\trefetchType: 'active',\n\t\t\t\t});\n\t\t\t\tawait router.invalidate();\n\t\t\t\ttoast.success('Success', {\n\t\t\t\t\tdescription: isSelfManaged\n\t\t\t\t\t\t? `Cluster successfully removed.`\n\t\t\t\t\t\t: `Cluster successfully terminated.`,\n\t\t\t\t\tduration: 5000,\n\t\t\t\t\taction: {\n\t\t\t\t\t\tlabel: 'Dismiss',\n\t\t\t\t\t\tonClick: () => toast.dismiss(),\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tsetIsTerminateClusterModalOpen(false);\n\t\t\t},\n\t\t\tonError: () => {\n\t\t\t\ttoast.error('Error', {\n\t\t\t\t\tdescription: isSelfManaged\n\t\t\t\t\t\t? `Failed to remove cluster: ${cluster.name}`\n\t\t\t\t\t\t: `Failed to terminate cluster: ${cluster.name}.`,\n\t\t\t\t\tduration: 5000,\n\t\t\t\t\taction: {\n\t\t\t\t\t\tlabel: 'Dismiss',\n\t\t\t\t\t\tonClick: () => toast.dismiss(),\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tsetIsTerminateClusterModalOpen(false);\n\t\t\t},\n\t\t});\n\t}, [router, cluster.organizationId, cluster.id, cluster.name, terminateCluster, isSelfManaged, queryClient]);\n\n\tconst clusterFQDN = cluster.domains?.[0]?.domain || cluster.fqdn;\n\tconst [onCopyFQDNClick, onCopyAPIClick] = useCopyToClipboard(\n\t\t`${clusterFQDN}`,\n\t\t`https://${clusterFQDN}`,\n\t);\n\n\tconst menuItems = [\n\t\tisActive && update && !auth.isLoading && (!isDirectConnect || isFabricConnect) && (\n\t\t\t<Link key=\"sign-in\" to={`${cluster.id}/sign-in`} disabled={signingOut}>\n\t\t\t\t<DropdownMenuItem>\n\t\t\t\t\t<KeyIcon className=\"text-green\" /> Direct Sign In\n\t\t\t\t</DropdownMenuItem>\n\t\t\t</Link>\n\t\t),\n\t\tisActive && view && !!operationsUrl && !auth.isLoading && isDirectConnect && (\n\t\t\t<DropdownMenuItem key=\"direct-sign-out\" onClick={onSignOutClick} disabled={signingOut}>\n\t\t\t\tDirect Sign Out\n\t\t\t</DropdownMenuItem>\n\t\t),\n\t\tisActive && update && (\n\t\t\t<Link key=\"edit\" to={`${cluster.id}/edit`} disabled={signingOut}>\n\t\t\t\t<DropdownMenuItem>\n\t\t\t\t\t<ScaleIcon className=\"text-purple-600\" /> {isSelfManaged ? 'Edit' : 'Edit Scaling'}\n\t\t\t\t</DropdownMenuItem>\n\t\t\t</Link>\n\t\t),\n\t\tisActive && update && !isSelfManaged && (\n\t\t\t<Link key=\"edit-version\" to={`${cluster.id}/edit/version`} disabled={signingOut}>\n\t\t\t\t<DropdownMenuItem>\n\t\t\t\t\t<GitGraphIcon className=\"text-fuchsia-300\" /> Edit Version\n\t\t\t\t</DropdownMenuItem>\n\t\t\t</Link>\n\t\t),\n\t\tisActive && update && !isLocalStudio && !clusterIsSelfManaged(cluster) && (\n\t\t\t<Link key=\"domains\" to={`${cluster.id}/domains`} disabled={signingOut}>\n\t\t\t\t<DropdownMenuItem>\n\t\t\t\t\t<GlobeIcon className=\"text-cyan-400\" /> Domains\n\t\t\t\t</DropdownMenuItem>\n\t\t\t</Link>\n\t\t),\n\t\tisActive && view && (\n\t\t\t<Link key=\"instances\" to={`${cluster.id}/instances`} disabled={signingOut}>\n\t\t\t\t<DropdownMenuItem>\n\t\t\t\t\t<ServerIcon className=\"text-orange-300\" /> Instances\n\t\t\t\t</DropdownMenuItem>\n\t\t\t</Link>\n\t\t),\n\n\t\tisActive && view && cluster.fqdn && <DropdownMenuSeparator key=\"copy-separator\" />,\n\t\tisActive && view && cluster.fqdn && (\n\t\t\t<DropdownMenuItem key=\"copy-host-name\" onClick={onCopyFQDNClick} disabled={signingOut}>\n\t\t\t\t<ClipboardIcon /> Copy Host Name\n\t\t\t</DropdownMenuItem>\n\t\t),\n\t\tisActive && view && cluster.fqdn && (\n\t\t\t<DropdownMenuItem key=\"copy-api-url\" onClick={onCopyAPIClick} disabled={signingOut}>\n\t\t\t\t<ClipboardIcon /> Copy API URL\n\t\t\t</DropdownMenuItem>\n\t\t),\n\n\t\tclusterHasFailed && create && (\n\t\t\t<DropdownMenuItem key=\"try-again\" className=\"focus:bg-green/70 focus:text-white\" onClick={onTryAgainClick}>\n\t\t\t\tTry Again\n\t\t\t</DropdownMenuItem>\n\t\t),\n\t\t!isTerminated && remove && isActive && <DropdownMenuSeparator key=\"remove-separator\" />,\n\t\t!isTerminated && remove && (\n\t\t\t<DropdownMenuItem key=\"remove\" className=\"focus:bg-red/70 focus:text-white\" onClick={onTerminateClick}>\n\t\t\t\t<TrashIcon className=\"text-red-300\" /> {isSelfManaged ? 'Remove' : 'Terminate'}\n\t\t\t</DropdownMenuItem>\n\t\t),\n\t].filter(excludeFalsy);\n\n\treturn (\n\t\t<Card className=\"relative h-full justify-between hover:shadow-lg transition-shadow duration-200\">\n\t\t\t<CardHeader>\n\t\t\t\t<CardDescription className=\"flex items-center justify-between\">\n\t\t\t\t\t{clusterFQDN\n\t\t\t\t\t\t? (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<span className=\"truncate max-w-48\">{clusterFQDN}</span>\n\t\t\t\t\t\t\t\t<CopyIcon onClick={onCopyFQDNClick} size={16} className=\"cursor-pointer\" />\n\t\t\t\t\t\t\t\t<span className=\"grow\"></span>\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)\n\t\t\t\t\t\t: <span>Self-Hosted</span>}\n\t\t\t\t\t{!isTerminated && (\n\t\t\t\t\t\t<DropdownMenu>\n\t\t\t\t\t\t\t<DropdownMenuTrigger>\n\t\t\t\t\t\t\t\t<Ellipsis aria-label=\"Cluster options\" />\n\t\t\t\t\t\t\t</DropdownMenuTrigger>\n\t\t\t\t\t\t\t<DropdownMenuContent>\n\t\t\t\t\t\t\t\t{...menuItems}\n\t\t\t\t\t\t\t</DropdownMenuContent>\n\t\t\t\t\t\t</DropdownMenu>\n\t\t\t\t\t)}\n\t\t\t\t</CardDescription>\n\t\t\t\t<CardTitle>\n\t\t\t\t\t<h2>{cluster.name}</h2>\n\t\t\t\t</CardTitle>\n\t\t\t</CardHeader>\n\t\t\t<CardContent className=\"flex items-center justify-between gap-2\">\n\t\t\t\t<ClusterProgress cluster={cluster} />\n\t\t\t\t{isActive && view && <ClusterCardAction cluster={cluster} />}\n\t\t\t\t{clusterHasFailed && cluster.status && (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<Badge variant={renderBadgeStatusVariant(cluster.status)}>{capitalizeWords(cluster.status)}</Badge>\n\t\t\t\t\t\t<span className=\"text-xs\">Click \"...\" to choose how to proceed.</span>\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</CardContent>\n\n\t\t\t<ConfirmDeletionModal\n\t\t\t\ttypeOfThingBeingDeleted=\"cluster\"\n\t\t\t\ttransitiveVerb={isSelfManaged ? 'Remove' : 'Terminate'}\n\t\t\t\tpresentParticiple={isSelfManaged ? 'Removing' : 'Terminating'}\n\t\t\t\tnameOfThingBeingDeleted={cluster.name}\n\t\t\t\tisModalOpen={isTerminateClusterModalOpen}\n\t\t\t\thideDataLossWarning={isSelfManaged}\n\t\t\t\tsetIsModalOpen={(isOpen: boolean) => setIsTerminateClusterModalOpen(isOpen)}\n\t\t\t\tdeletionConfirmed={handleTerminatedCluster}\n\t\t\t\tdeletionPending={isTerminateClusterPending}\n\t\t\t/>\n\t\t</Card>\n\t);\n}\n","export function ContactUs({ overEmail }: { readonly overEmail?: boolean }) {\n\treturn (\n\t\t<a\n\t\t\thref={overEmail\n\t\t\t\t? 'mailto:support@harperdb.io'\n\t\t\t\t: 'https://discord.com/channels/1415002037439041710/1415002038286286994'}\n\t\t\ttarget=\"_blank\"\n\t\t\trel=\"noreferrer\"\n\t\t\tclassName=\"underline\"\n\t\t>\n\t\t\tContact us\n\t\t</a>\n\t);\n}\n","import { ComponentProps, ReactNode } from 'react';\n\ninterface LoadingProps extends ComponentProps<'div'> {\n\ttext?: ReactNode;\n\tcentered?: boolean;\n}\n\nexport function Loading({ className, text, centered, ...props }: LoadingProps) {\n\tconst additionalClassName = centered ? 'flex flex-col items-center justify-center' : '';\n\treturn (\n\t\t<div className={`text-foreground h-full w-full ${className || ''} ${additionalClassName}`} {...props}>\n\t\t\t<img src=\"/HDBDogOnly.svg\" width=\"100px\" height=\"100px\" alt=\"HDB Dog Logo Loading\" className=\"inline-block\" />\n\t\t\t<p className=\"pt-4\">{!text ? 'Loading...' : text}</p>\n\t\t</div>\n\t);\n}\n","import { SubNavMenu } from '@/components/SubNavMenu';\nimport { ReactNode } from 'react';\n\nexport function SubNavSimpleLayout({ children, className }: { children: ReactNode; className?: string }) {\n\treturn (\n\t\t<>\n\t\t\t<SubNavMenu />\n\t\t\t<div className={`mt-32 px-4 pt-4 md:px-12 min-h-[calc(100vh-(--spacing(32)))] relative ${className ?? ''}`}>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t</>\n\t);\n}\n","import { apiClient } from '@/config/apiClient';\nimport { queryOptions } from '@tanstack/react-query';\n\nasync function getPlanTypes(organizationId: string) {\n\tconst { data } = await apiClient.get(`/Plan/`, {\n\t\tparams: {\n\t\t\torganizationId,\n\t\t},\n\t});\n\treturn data;\n}\n\nexport function getPlanTypesOptions(organizationId: string) {\n\treturn queryOptions({\n\t\tqueryKey: [organizationId, 'instancePlan'],\n\t\tqueryFn: () => getPlanTypes(organizationId),\n\t\tretry: false,\n\t});\n}\n","import { apiClient } from '@/config/apiClient';\nimport { queryOptions } from '@tanstack/react-query';\n\nexport interface HarperVersionsResponse {\n\tname: string;\n\tdescription: string;\n\tvalue: HarperVersion[];\n}\n\ninterface HarperVersion {\n\tname: 'stable' | 'next' | 'current';\n\tversion: string;\n}\n\nasync function getHarperVersions() {\n\t// TODO: OpenAPI from CM is erroring, so this new endpoint isn't described.\n\tconst { data } = await apiClient.get(`/HarperVersions/` as any);\n\treturn data as HarperVersionsResponse;\n}\n\nexport function getHarperVersionsOptions() {\n\treturn queryOptions({\n\t\tqueryKey: ['HarperVersions'],\n\t\tqueryFn: getHarperVersions,\n\t\tstaleTime: 60_000,\n\t\tretry: false,\n\t});\n}\n","import { apiClient } from '@/config/apiClient';\nimport { queryOptions } from '@tanstack/react-query';\n\nexport interface GetRegionLocationsParams {\n\torganizationId?: string;\n\tavailableHosts?: boolean;\n}\n\nasync function getRegionLocations({ organizationId, availableHosts }: GetRegionLocationsParams = {}) {\n\tconst { data } = await apiClient.get(`/Region/`, {\n\t\tparams: {\n\t\t\tavailableHosts,\n\t\t\torganizationId,\n\t\t},\n\t});\n\treturn data;\n}\n\nexport function getRegionLocationsOptions({ organizationId, availableHosts }: GetRegionLocationsParams = {}) {\n\treturn queryOptions({\n\t\tqueryKey: [organizationId, 'regionLocations', availableHosts],\n\t\tqueryFn: () => getRegionLocations({ organizationId, availableHosts }),\n\t\tretry: false,\n\t});\n}\n","export function sortByField<T>(fieldName: keyof T): (a: T, b: T) => number {\n\treturn (a: T, b: T): number => {\n\t\tif (a[fieldName] === b[fieldName]) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn a[fieldName] > b[fieldName] ? 1 : -1;\n\t};\n}\n","export function ipAddressToNumber(ipAddress: string): number {\n\tconst parts = ipAddress.split('.').map(Number);\n\t// Coerce result to an unsigned 32-bit integer to avoid negative values for >= 128.0.0.0\n\treturn (((parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8) | parts[3]) >>> 0);\n}\n","export function isIpAddress(value: string | unknown): boolean {\n\tif (typeof value !== 'string') {\n\t\treturn false;\n\t}\n\t// Strict IPv4 check: exactly four octets, each 0–255; no extra chars\n\tconst ipv4 = /^(?:25[0-5]|2[0-4]\\d|1?\\d?\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1?\\d?\\d)){3}$/;\n\treturn ipv4.test(value);\n}\n","import { SchemaHdbInstance } from '@/integrations/api/api.gen';\nimport { ipAddressToNumber } from '@/lib/numbers/ipAddressToNumber';\nimport { isIpAddress } from '@/lib/string/isIpAddress';\n\nexport function byInstanceFqdnThenPort(\n\ta: Pick<SchemaHdbInstance, 'instanceFqdn' | 'operationsApiPort'>,\n\tb: Pick<SchemaHdbInstance, 'instanceFqdn' | 'operationsApiPort'>,\n) {\n\tif (a.instanceFqdn === b.instanceFqdn) {\n\t\treturn a.operationsApiPort - b.operationsApiPort;\n\t}\n\tif (isIpAddress(a.instanceFqdn) && isIpAddress(b.instanceFqdn)) {\n\t\treturn ipAddressToNumber(a.instanceFqdn) - ipAddressToNumber(b.instanceFqdn);\n\t}\n\treturn a.instanceFqdn > b.instanceFqdn ? 1 : -1;\n}\n","export function groupBy<T extends object>(items: T[], property: keyof T): Record<string, T[]> {\n\tconst retVal: Record<string, T[]> = {};\n\n\tfor (const item of items) {\n\t\tconst key = item[property] as string;\n\t\tif (key === undefined) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (Array.isArray(key)) {\n\t\t\tfor (const k of key) {\n\t\t\t\tif (!retVal[k]) {\n\t\t\t\t\tretVal[k] = [];\n\t\t\t\t}\n\t\t\t\tretVal[k].push(item);\n\t\t\t}\n\t\t} else {\n\t\t\tif (!retVal[key]) {\n\t\t\t\tretVal[key] = [];\n\t\t\t}\n\t\t\tretVal[key].push(item);\n\t\t}\n\t}\n\n\treturn retVal as Record<string, T[]>;\n}\n","export function keyBy<T extends object>(items: T[], property: keyof T): Record<string, T> {\n\tconst retVal: Record<string, T> = {};\n\n\tfor (const item of items) {\n\t\tconst key = item[property] as string;\n\t\tif (key === undefined) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (Array.isArray(key)) {\n\t\t\tfor (const k of key) {\n\t\t\t\tretVal[k] = item;\n\t\t\t}\n\t\t} else {\n\t\t\tretVal[key] = item;\n\t\t}\n\t}\n\n\treturn retVal;\n}\n","import { groupBy } from '@/lib/groupBy';\nimport { keyBy } from '@/lib/keyBy';\n\nexport function groupThenKeyBy<T extends object>(\n\titems: T[],\n\tgroupByKey: keyof T,\n\tkeyByKey: keyof T,\n): Record<string, Record<string, T>> {\n\tconst grouped = groupBy(items, groupByKey);\n\tconst keyed: Record<string, Record<string, T>> = {};\n\tfor (const groupName in grouped) {\n\t\tkeyed[groupName] = keyBy(grouped[groupName], keyByKey);\n\t}\n\treturn keyed;\n}\n","/**\n * Compare two semver strings according to SemVer 2.0.0 rules.\n * Returns true if \"b\" (second argument) is greater than or equal to \"a\" (first argument).\n * @param a The base version\n * @param b The potentially greater version\n * @example compareSemVer('4.7.0-beta.7', '4.7.0') => true\n * @example compareSemVer('4.7.0', '4.7.0-beta.7') => false\n */\nexport function wasAReleasedBeforeB(a: string, b: string): boolean {\n\tconst pa = parseSemVer(a);\n\tconst pb = parseSemVer(b);\n\n\tif (!pa || !pb) {\n\t\treturn false;\n\t}\n\n\treturn semverCompare(pb, pa) >= 0; // is b >= a ?\n}\n\n/**\n * Compare two semver strings according to SemVer 2.0.0 rules.\n * Returns -1 if a < b, 0 if a == b, 1 if a > b.\n */\nexport function compareVersions(a: string, b: string): number {\n\tconst pa = parseSemVer(a);\n\tconst pb = parseSemVer(b);\n\n\tif (!pa && !pb) { return 0; }\n\tif (!pa) { return -1; }\n\tif (!pb) { return 1; }\n\n\treturn semverCompare(pa, pb);\n}\n\n// Internal representation of a semver\ninterface SemVerParts {\n\tmajor: number;\n\tminor: number;\n\tpatch: number;\n\tpre: (number | string)[]; // numeric identifiers stay numbers, others as strings\n}\n\nfunction parseSemVer(input: string): SemVerParts | null {\n\tif (typeof input !== 'string') {\n\t\treturn null;\n\t}\n\n\t// Strip build metadata (+...) as it has no effect on precedence\n\tconst [versionAndPre] = input.split('+', 1).concat('');\n\n\t// Separate core and pre-release\n\tconst firstDash = versionAndPre.indexOf('-');\n\tconst core = firstDash === -1 ? versionAndPre : versionAndPre.slice(0, firstDash);\n\tconst pre = firstDash === -1 ? '' : versionAndPre.slice(firstDash + 1);\n\n\tconst coreParts = core.split('.');\n\tif (coreParts.length === 0) {\n\t\treturn null;\n\t}\n\n\tconst major = toInt(coreParts[0]);\n\tconst minor = toInt(coreParts[1] ?? '0');\n\tconst patch = toInt(coreParts[2] ?? '0');\n\n\tif (major == null || minor == null || patch == null) {\n\t\treturn null;\n\t}\n\n\tconst preParts: (number | string)[] = pre\n\t\t? pre.split('.').map((id) => (isNumeric(id) ? Number(id) : id))\n\t\t: [];\n\n\treturn { major, minor, patch, pre: preParts };\n}\n\nfunction toInt(s?: string): number | null {\n\tif (s == null || s === '') {\n\t\treturn null;\n\t}\n\tif (!/^\\d+$/.test(s)) {\n\t\treturn null;\n\t}\n\treturn Number(s);\n}\n\nfunction isNumeric(s: string): boolean {\n\treturn /^\\d+$/.test(s);\n}\n\n// Returns -1 if a<b, 0 if a==b, 1 if a>b\nfunction semverCompare(a: SemVerParts, b: SemVerParts): number {\n\tif (a.major !== b.major) {\n\t\treturn a.major < b.major ? -1 : 1;\n\t}\n\tif (a.minor !== b.minor) {\n\t\treturn a.minor < b.minor ? -1 : 1;\n\t}\n\tif (a.patch !== b.patch) {\n\t\treturn a.patch < b.patch ? -1 : 1;\n\t}\n\n\tconst aHasPre = a.pre.length > 0;\n\tconst bHasPre = b.pre.length > 0;\n\tif (!aHasPre && !bHasPre) {\n\t\treturn 0;\n\t}\n\t// A version without pre-release is greater than one with pre-release\n\tif (!aHasPre && bHasPre) {\n\t\treturn 1;\n\t}\n\tif (aHasPre && !bHasPre) {\n\t\treturn -1;\n\t}\n\n\tconst len = Math.min(a.pre.length, b.pre.length);\n\tfor (let i = 0; i < len; i++) {\n\t\tconst idA = a.pre[i];\n\t\tconst idB = b.pre[i];\n\t\tconst aNum = typeof idA === 'number';\n\t\tconst bNum = typeof idB === 'number';\n\n\t\tif (aNum && bNum) {\n\t\t\tif (idA !== (idB as number)) {\n\t\t\t\treturn (idA as number) < (idB as number) ? -1 : 1;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (aNum && !bNum) {\n\t\t\treturn -1; // numeric identifiers have lower precedence than non-numeric\n\t\t}\n\t\tif (!aNum && bNum) {\n\t\t\treturn 1;\n\t\t}\n\n\t\t// both strings: ASCII lexicographic compare\n\t\tif (idA !== idB) {\n\t\t\treturn String(idA) < String(idB) ? -1 : 1;\n\t\t}\n\t}\n\n\t// If all identifiers equal so far, longer set has higher precedence\n\tif (a.pre.length !== b.pre.length) {\n\t\treturn a.pre.length < b.pre.length ? -1 : 1;\n\t}\n\n\treturn 0;\n}\n","import { cx } from 'class-variance-authority';\n\nexport function ProgressBar({ width, className, animated, placeholder }: {\n\twidth: string | undefined;\n\tclassName?: string;\n\tanimated?: boolean;\n\tplaceholder?: string;\n}) {\n\treturn (\n\t\t<div className={cx('w-full bg-gray-200 rounded-full relative', placeholder ? 'h-6' : 'h-2.5')}>\n\t\t\t{placeholder && (\n\t\t\t\t<div className=\"absolute top-0 h-full w-full font-bold text-xs flex flex-col items-center justify-center text-black/60 text-shadow-2xs\">\n\t\t\t\t\t{placeholder}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t<div\n\t\t\t\tclassName={cx(\n\t\t\t\t\t'rounded-full',\n\t\t\t\t\tplaceholder ? 'h-6' : 'h-2.5',\n\t\t\t\t\t!className?.includes('bg-') && 'bg-purple/40',\n\t\t\t\t\tanimated && 'transition-[width] duration-1000 ease-in-out motion-reduce:transition-none',\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tstyle={{\n\t\t\t\t\twidth,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n","import { ProgressBar } from '@/components/ProgressBar';\nimport { ReactNode, useCallback, useEffect, useRef, useState } from 'react';\n\nexport function EstimatedProgressBar({ duration, message, lateMessage }: {\n\tduration: number;\n\tmessage: ReactNode;\n\tlateMessage: ReactNode;\n}) {\n\tconst animationFrameId = useRef<number>(0);\n\tconst previousTimeRef = useRef<number>(0);\n\tconst [finished, setFinished] = useState(false);\n\tconst minPercentage = 5;\n\tconst [width, setWidth] = useState(`${minPercentage}%`);\n\n\tconst animate = useCallback(function animate(time: number) {\n\t\tif (!previousTimeRef.current) {\n\t\t\tpreviousTimeRef.current = time;\n\t\t}\n\t\tconst timeElapsed = time - previousTimeRef.current;\n\t\tconst percentage = Math.min(timeElapsed / duration, 1);\n\t\tsetWidth(Math.max(minPercentage, percentage * 100) + '%');\n\n\t\tif (percentage < 1) {\n\t\t\tanimationFrameId.current = requestAnimationFrame(animate);\n\t\t} else {\n\t\t\tsetFinished(true);\n\t\t}\n\t}, [duration]);\n\n\tuseEffect(() => {\n\t\tanimationFrameId.current = requestAnimationFrame(animate);\n\t\treturn () => cancelAnimationFrame(animationFrameId.current);\n\t}, [animate]);\n\n\treturn (\n\t\t<>\n\t\t\t{!finished ? message : lateMessage}\n\t\t\t<ProgressBar width={width} animated={false}></ProgressBar>\n\t\t</>\n\t);\n}\n","import { apiClient } from '@/config/apiClient';\nimport { SchemaCluster } from '@/integrations/api/api.gen';\nimport { ClusterUpsert } from '@/integrations/api/api.patch';\nimport { useMutation } from '@tanstack/react-query';\n\nasync function onNewClusterSubmit(\n\tclusterInfo: ClusterUpsert,\n): Promise<SchemaCluster> {\n\tconst { data } = await apiClient.post(\n\t\t'/Cluster/',\n\t\tclusterInfo,\n\t\t{ timeout: 0 },\n\t);\n\treturn data;\n}\n\nexport function useCreateNewClusterMutation() {\n\treturn useMutation<SchemaCluster, Error, ClusterUpsert>({\n\t\tmutationFn: (clusterInfo) => onNewClusterSubmit(clusterInfo),\n\t});\n}\n","import { apiClient } from '@/config/apiClient';\nimport { SchemaCluster } from '@/integrations/api/api.gen';\nimport { ClusterUpsert } from '@/integrations/api/api.patch';\nimport { useMutation } from '@tanstack/react-query';\n\ntype EditRegionPlan = Pick<SchemaCluster, 'id'> & Pick<ClusterUpsert, 'regionPlans' | 'skipGtmWait'>;\ntype EditVersion = Pick<SchemaCluster, 'id'> & Pick<ClusterUpsert, 'version' | 'skipGtmWait'>;\n\nasync function onEditClusterSubmit(\n\tclusterInfo: EditRegionPlan | EditVersion,\n): Promise<SchemaCluster> {\n\tconst { id, ...changes } = clusterInfo;\n\tconst { data } = await apiClient.put(\n\t\t`/Cluster/${id}` as '/Cluster/{id}',\n\t\tchanges,\n\t\t{ timeout: 0 },\n\t);\n\treturn data;\n}\n\nexport function useEditClusterMutation() {\n\treturn useMutation<SchemaCluster, Error, EditRegionPlan | EditVersion>({\n\t\tmutationFn: (clusterInfo) => onEditClusterSubmit(clusterInfo),\n\t});\n}\n","import { apiClient } from '@/config/apiClient';\nimport { Organization } from '@/integrations/api/api.patch';\nimport { queryOptions } from '@tanstack/react-query';\n\n// `useParams({ strict: false })` can yield `undefined`, and a navigation that\n// interpolates a missing id into a path produces the literal string\n// `\"undefined\"`/`\"null\"` — both would otherwise build a request to\n// `/Organization/undefined`. Treat all of these as \"no organization id\".\nexport function isValidOrganizationId(orgId: string | undefined | null): orgId is string {\n\treturn !!orgId && orgId !== 'undefined' && orgId !== 'null';\n}\n\nexport async function getOrganization(orgId: string): Promise<Organization> {\n\tif (!isValidOrganizationId(orgId)) {\n\t\t// Fail fast instead of issuing a doomed `/Organization/undefined` request.\n\t\t// Guards the call paths that ignore react-query's `enabled` flag:\n\t\t// `ensureQueryData` (route beforeLoad), `useSuspenseQuery`, and direct callers.\n\t\tthrow new Error(`getOrganization called without a valid organization id (got: ${orgId})`);\n\t}\n\tconst { data } = await apiClient.get(`/Organization/${orgId}` as '/Organization/{id}');\n\treturn data as Organization;\n}\n\nexport function getOrganizationQueryOptions(orgId: string | undefined) {\n\treturn queryOptions({\n\t\tqueryKey: [orgId],\n\t\tqueryFn: () => getOrganization(orgId as string),\n\t\tretry: false,\n\t\tenabled: isValidOrganizationId(orgId),\n\t\trefetchInterval: 10000,\n\t});\n}\n","export const ENTERPRISE = 'ENTERPRISE';\nexport const SELF_SERVICE = 'SELF_SERVICE';\n","/**\n * Collapses a kebab-case string to meet a maximum length restriction.\n * It shortens segments one by one starting from the end, keeping the first character of each segment.\n *\n * @param str - The kebab-case string to collapse\n * @param maxLength - The maximum length the resulting string should have\n * @returns The collapsed string that meets the max length restriction\n *\n * @example\n * collapseKebabsToMaxLength('one-two-three', 8) // 'one-t-t'\n * collapseKebabsToMaxLength('hello-world', 7) // 'hello-w'\n * collapseKebabsToMaxLength('a-b-c-d', 5) // 'a-b-c'\n * collapseKebabsToMaxLength('short', 10) // 'short' (already within max length)\n */\nexport function collapseKebabsToMaxLength(str: string, maxLength: number): string {\n\t// Handle edge cases with zero or negative max length\n\tif (maxLength <= 0) {\n\t\treturn '';\n\t}\n\n\t// If the string is already within the max length, return it as is\n\tif (str.length <= maxLength) {\n\t\treturn str;\n\t}\n\n\t// Split the string by hyphens to get individual segments\n\tconst segments = str.split('-');\n\n\t// If there's only one segment, just truncate it\n\tif (segments.length === 1) {\n\t\treturn segments[0].slice(0, maxLength);\n\t}\n\n\t// First, collapse all segments except the first one to their first character\n\tconst collapsedSegments = [\n\t\tsegments[0],\n\t\t...segments.slice(1).map(segment => segment.charAt(0)),\n\t];\n\n\t// Check if the collapsed string now meets the max length\n\tconst result = collapsedSegments.join('-');\n\tif (result.length <= maxLength) {\n\t\treturn result;\n\t}\n\n\t// If we still exceed the max length, we need to truncate the first segment\n\t// Calculate how much space we have for the first segment\n\tconst otherSegmentsLength = collapsedSegments.slice(1).join('').length;\n\tconst hyphensLength = collapsedSegments.length - 1; // Number of hyphens\n\tconst maxFirstSegmentLength = maxLength - otherSegmentsLength - hyphensLength;\n\n\tif (maxFirstSegmentLength > 0) {\n\t\t// We have some space for the first segment\n\t\tcollapsedSegments[0] = collapsedSegments[0].slice(0, maxFirstSegmentLength);\n\t\treturn collapsedSegments.join('-');\n\t} else {\n\t\t// We don't have space for all segments, so we need to remove segments from the end\n\t\t// Keep as many segments as possible, starting from the beginning\n\t\tconst finalSegments = [];\n\t\tlet currentLength = 0;\n\n\t\t// Always include at least the first character of the first segment if possible\n\t\tif (maxLength > 0) {\n\t\t\tfinalSegments.push(segments[0].charAt(0));\n\t\t\tcurrentLength = 1;\n\t\t}\n\n\t\t// Add as many collapsed segments as we can fit\n\t\tfor (let i = 1; i < collapsedSegments.length; i++) {\n\t\t\t// +1 for the hyphen\n\t\t\tconst segmentLength = 1 + 1; // 1 for the collapsed segment, 1 for the hyphen\n\n\t\t\tif (currentLength + segmentLength <= maxLength) {\n\t\t\t\tfinalSegments.push(collapsedSegments[i]);\n\t\t\t\tcurrentLength += segmentLength;\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn finalSegments.join('-');\n\t}\n}\n","export function stringsShareAPrefix(haystacks: string[], needle: string, delimiter = '-'): boolean {\n\tconst prefix = needle.split(delimiter)[0];\n\treturn -1 !== haystacks.findIndex(haystack => haystack.startsWith(prefix));\n}\n","/**\n * Converts a string to kebab-case.\n *\n * @param str - The string to convert\n * @returns The kebab-cased string\n *\n * @example\n * toKebabCase('Hello World') // 'hello-world'\n * toKebabCase('camelCase') // 'camel-case'\n * toKebabCase('PascalCase') // 'pascal-case'\n * toKebabCase('snake_case') // 'snake-case'\n * toKebabCase('with spaces and_underscores') // 'with-spaces-and-underscores'\n */\nexport function toKebabCase(str: string): string {\n\treturn str\n\t\t// Replace any non-alphanumeric characters with hyphens\n\t\t.replace(/[^a-zA-Z0-9]/g, '-')\n\t\t// Insert a hyphen before any uppercase letter that follows a lowercase letter\n\t\t.replace(/([a-z])([A-Z])/g, '$1-$2')\n\t\t// Convert to lowercase\n\t\t.toLowerCase()\n\t\t// Replace multiple consecutive hyphens with a single hyphen\n\t\t.replace(/-+/g, '-')\n\t\t// Remove leading and trailing hyphens\n\t\t.replace(/^-+|-+$/g, '');\n}\n\n// Easter egg: I know this file doesn't follow our convention (it should be toKebabCase.ts), but I thought it would\n// be funny if it was itself in kebab-case\n// - <3 Dawson\n","export function isPositive(value: number | undefined): value is number {\n\treturn value !== undefined && value > 0;\n}\n","import { apiClient } from '@/config/apiClient';\nimport { useMutation } from '@tanstack/react-query';\n\ninterface Params {\n\torganizationId: string;\n\tpaymentMethodId: string;\n}\n\nexport async function onAttachPaymentMethodToOrganization(params: Params): Promise<void> {\n\t// TODO: PUT /Payment/ isn't describing itself from the API.\n\tawait apiClient.put(`/Payment/`, params);\n}\n\nexport function useAttachPaymentMethodToOrganization() {\n\treturn useMutation<void, Error, Params>({\n\t\tmutationFn: (params: Params) => onAttachPaymentMethodToOrganization(params),\n\t});\n}\n","import {\n\tuseAttachPaymentMethodToOrganization,\n} from '@/features/organization/mutations/payments/attachPaymentMethodToOrganization';\nimport { PaymentMethod } from '@stripe/stripe-js/dist/api/payment-methods';\nimport { useCallback } from 'react';\nimport { toast } from 'sonner';\n\nexport function useProcessStripePaymentMethod(organizationId: string) {\n\tconst { mutate: attachPaymentMethodToOrganization } = useAttachPaymentMethodToOrganization();\n\n\treturn useCallback((paymentMethod: string | PaymentMethod, onFinished: (added: boolean) => void) => {\n\t\tattachPaymentMethodToOrganization({\n\t\t\tpaymentMethodId: typeof paymentMethod === 'string' ? paymentMethod : paymentMethod.id,\n\t\t\torganizationId,\n\t\t}, {\n\t\t\tonSuccess: () => {\n\t\t\t\ttoast.success('Success! Your payment method has been saved.');\n\t\t\t\tonFinished(true);\n\t\t\t},\n\t\t\tonError: () => {\n\t\t\t\ttoast.error('Failed to process payment method details. Please try another payment method.');\n\t\t\t\tonFinished(false);\n\t\t\t},\n\t\t});\n\t}, [attachPaymentMethodToOrganization, organizationId]);\n}\n","import { StripeElementsOptions } from '@stripe/stripe-js';\nimport { createContext, useContext } from 'react';\n\nexport const StripeContext = createContext<StripeElementsOptions | null>(null);\n\nexport function useStripeOptions() {\n\treturn useContext(StripeContext) as StripeElementsOptions;\n}\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\nvar ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';\n\nmodule.exports = ReactPropTypesSecret;\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\nvar ReactPropTypesSecret = require('./lib/ReactPropTypesSecret');\n\nfunction emptyFunction() {}\nfunction emptyFunctionWithReset() {}\nemptyFunctionWithReset.resetWarningCache = emptyFunction;\n\nmodule.exports = function() {\n function shim(props, propName, componentName, location, propFullName, secret) {\n if (secret === ReactPropTypesSecret) {\n // It is still safe when called from React.\n return;\n }\n var err = new Error(\n 'Calling PropTypes validators directly is not supported by the `prop-types` package. ' +\n 'Use PropTypes.checkPropTypes() to call them. ' +\n 'Read more at http://fb.me/use-check-prop-types'\n );\n err.name = 'Invariant Violation';\n throw err;\n };\n shim.isRequired = shim;\n function getShim() {\n return shim;\n };\n // Important!\n // Keep this list in sync with production version in `./factoryWithTypeCheckers.js`.\n var ReactPropTypes = {\n array: shim,\n bigint: shim,\n bool: shim,\n func: shim,\n number: shim,\n object: shim,\n string: shim,\n symbol: shim,\n\n any: shim,\n arrayOf: getShim,\n element: shim,\n elementType: shim,\n instanceOf: getShim,\n node: shim,\n objectOf: getShim,\n oneOf: getShim,\n oneOfType: getShim,\n shape: getShim,\n exact: getShim,\n\n checkPropTypes: emptyFunctionWithReset,\n resetWarningCache: emptyFunction\n };\n\n ReactPropTypes.PropTypes = ReactPropTypes;\n\n return ReactPropTypes;\n};\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nif (process.env.NODE_ENV !== 'production') {\n var ReactIs = require('react-is');\n\n // By explicitly using `prop-types` you are opting into new development behavior.\n // http://fb.me/prop-types-in-prod\n var throwOnDirectAccess = true;\n module.exports = require('./factoryWithTypeCheckers')(ReactIs.isElement, throwOnDirectAccess);\n} else {\n // By explicitly using `prop-types` you are opting into new production behavior.\n // http://fb.me/prop-types-in-prod\n module.exports = require('./factoryWithThrowingShims')();\n}\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nfunction ownKeys(object, enumerableOnly) {\n var keys = Object.keys(object);\n\n if (Object.getOwnPropertySymbols) {\n var symbols = Object.getOwnPropertySymbols(object);\n\n if (enumerableOnly) {\n symbols = symbols.filter(function (sym) {\n return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n });\n }\n\n keys.push.apply(keys, symbols);\n }\n\n return keys;\n}\n\nfunction _objectSpread2(target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i] != null ? arguments[i] : {};\n\n if (i % 2) {\n ownKeys(Object(source), true).forEach(function (key) {\n _defineProperty(target, key, source[key]);\n });\n } else if (Object.getOwnPropertyDescriptors) {\n Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n } else {\n ownKeys(Object(source)).forEach(function (key) {\n Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n });\n }\n }\n\n return target;\n}\n\nfunction _typeof(obj) {\n \"@babel/helpers - typeof\";\n\n if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") {\n _typeof = function (obj) {\n return typeof obj;\n };\n } else {\n _typeof = function (obj) {\n return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n };\n }\n\n return _typeof(obj);\n}\n\nfunction asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {\n try {\n var info = gen[key](arg);\n var value = info.value;\n } catch (error) {\n reject(error);\n return;\n }\n\n if (info.done) {\n resolve(value);\n } else {\n Promise.resolve(value).then(_next, _throw);\n }\n}\n\nfunction _asyncToGenerator(fn) {\n return function () {\n var self = this,\n args = arguments;\n return new Promise(function (resolve, reject) {\n var gen = fn.apply(self, args);\n\n function _next(value) {\n asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"next\", value);\n }\n\n function _throw(err) {\n asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"throw\", err);\n }\n\n _next(undefined);\n });\n };\n}\n\nfunction _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}\n\nfunction _objectWithoutPropertiesLoose(source, excluded) {\n if (source == null) return {};\n var target = {};\n var sourceKeys = Object.keys(source);\n var key, i;\n\n for (i = 0; i < sourceKeys.length; i++) {\n key = sourceKeys[i];\n if (excluded.indexOf(key) >= 0) continue;\n target[key] = source[key];\n }\n\n return target;\n}\n\nfunction _objectWithoutProperties(source, excluded) {\n if (source == null) return {};\n\n var target = _objectWithoutPropertiesLoose(source, excluded);\n\n var key, i;\n\n if (Object.getOwnPropertySymbols) {\n var sourceSymbolKeys = Object.getOwnPropertySymbols(source);\n\n for (i = 0; i < sourceSymbolKeys.length; i++) {\n key = sourceSymbolKeys[i];\n if (excluded.indexOf(key) >= 0) continue;\n if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;\n target[key] = source[key];\n }\n }\n\n return target;\n}\n\nfunction _slicedToArray(arr, i) {\n return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();\n}\n\nfunction _arrayWithHoles(arr) {\n if (Array.isArray(arr)) return arr;\n}\n\nfunction _iterableToArrayLimit(arr, i) {\n var _i = arr && (typeof Symbol !== \"undefined\" && arr[Symbol.iterator] || arr[\"@@iterator\"]);\n\n if (_i == null) return;\n var _arr = [];\n var _n = true;\n var _d = false;\n\n var _s, _e;\n\n try {\n for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {\n _arr.push(_s.value);\n\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i[\"return\"] != null) _i[\"return\"]();\n } finally {\n if (_d) throw _e;\n }\n }\n\n return _arr;\n}\n\nfunction _unsupportedIterableToArray(o, minLen) {\n if (!o) return;\n if (typeof o === \"string\") return _arrayLikeToArray(o, minLen);\n var n = Object.prototype.toString.call(o).slice(8, -1);\n if (n === \"Object\" && o.constructor) n = o.constructor.name;\n if (n === \"Map\" || n === \"Set\") return Array.from(o);\n if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);\n}\n\nfunction _arrayLikeToArray(arr, len) {\n if (len == null || len > arr.length) len = arr.length;\n\n for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];\n\n return arr2;\n}\n\nfunction _nonIterableRest() {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}\n\nvar useAttachEvent = function useAttachEvent(element, event, cb) {\n var cbDefined = !!cb;\n var cbRef = React.useRef(cb); // In many integrations the callback prop changes on each render.\n // Using a ref saves us from calling element.on/.off every render.\n\n React.useEffect(function () {\n cbRef.current = cb;\n }, [cb]);\n React.useEffect(function () {\n if (!cbDefined || !element) {\n return function () {};\n }\n\n var decoratedCb = function decoratedCb() {\n if (cbRef.current) {\n return cbRef.current.apply(cbRef, arguments);\n }\n\n return undefined;\n };\n\n element.on(event, decoratedCb);\n return function () {\n element.off(event, decoratedCb);\n };\n }, [cbDefined, event, element, cbRef]);\n};\n\nvar usePrevious = function usePrevious(value) {\n var ref = React.useRef(value);\n React.useEffect(function () {\n ref.current = value;\n }, [value]);\n return ref.current;\n};\n\nvar isUnknownObject = function isUnknownObject(raw) {\n return raw !== null && _typeof(raw) === 'object';\n};\nvar isPromise = function isPromise(raw) {\n return isUnknownObject(raw) && typeof raw.then === 'function';\n}; // We are using types to enforce the `stripe` prop in this lib,\n// but in an untyped integration `stripe` could be anything, so we need\n// to do some sanity validation to prevent type errors.\n\nvar isStripe = function isStripe(raw) {\n return isUnknownObject(raw) && typeof raw.elements === 'function' && typeof raw.createToken === 'function' && typeof raw.createPaymentMethod === 'function' && typeof raw.confirmCardPayment === 'function';\n};\n\nvar PLAIN_OBJECT_STR = '[object Object]';\nvar isEqual = function isEqual(left, right) {\n if (!isUnknownObject(left) || !isUnknownObject(right)) {\n return left === right;\n }\n\n var leftArray = Array.isArray(left);\n var rightArray = Array.isArray(right);\n if (leftArray !== rightArray) return false;\n var leftPlainObject = Object.prototype.toString.call(left) === PLAIN_OBJECT_STR;\n var rightPlainObject = Object.prototype.toString.call(right) === PLAIN_OBJECT_STR;\n if (leftPlainObject !== rightPlainObject) return false; // not sure what sort of special object this is (regexp is one option), so\n // fallback to reference check.\n\n if (!leftPlainObject && !leftArray) return left === right;\n var leftKeys = Object.keys(left);\n var rightKeys = Object.keys(right);\n if (leftKeys.length !== rightKeys.length) return false;\n var keySet = {};\n\n for (var i = 0; i < leftKeys.length; i += 1) {\n keySet[leftKeys[i]] = true;\n }\n\n for (var _i = 0; _i < rightKeys.length; _i += 1) {\n keySet[rightKeys[_i]] = true;\n }\n\n var allKeys = Object.keys(keySet);\n\n if (allKeys.length !== leftKeys.length) {\n return false;\n }\n\n var l = left;\n var r = right;\n\n var pred = function pred(key) {\n return isEqual(l[key], r[key]);\n };\n\n return allKeys.every(pred);\n};\n\nvar extractAllowedOptionsUpdates = function extractAllowedOptionsUpdates(options, prevOptions, immutableKeys) {\n if (!isUnknownObject(options)) {\n return null;\n }\n\n return Object.keys(options).reduce(function (newOptions, key) {\n var isUpdated = !isUnknownObject(prevOptions) || !isEqual(options[key], prevOptions[key]);\n\n if (immutableKeys.includes(key)) {\n if (isUpdated) {\n console.warn(\"Unsupported prop change: options.\".concat(key, \" is not a mutable property.\"));\n }\n\n return newOptions;\n }\n\n if (!isUpdated) {\n return newOptions;\n }\n\n return _objectSpread2(_objectSpread2({}, newOptions || {}), {}, _defineProperty({}, key, options[key]));\n }, null);\n};\n\nvar INVALID_STRIPE_ERROR$1 = 'Invalid prop `stripe` supplied to `Elements`. We recommend using the `loadStripe` utility from `@stripe/stripe-js`. See https://stripe.com/docs/stripe-js/react#elements-props-stripe for details.'; // We are using types to enforce the `stripe` prop in this lib, but in a real\n// integration `stripe` could be anything, so we need to do some sanity\n// validation to prevent type errors.\n\nvar validateStripe = function validateStripe(maybeStripe) {\n var errorMsg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : INVALID_STRIPE_ERROR$1;\n\n if (maybeStripe === null || isStripe(maybeStripe)) {\n return maybeStripe;\n }\n\n throw new Error(errorMsg);\n};\n\nvar parseStripeProp = function parseStripeProp(raw) {\n var errorMsg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : INVALID_STRIPE_ERROR$1;\n\n if (isPromise(raw)) {\n return {\n tag: 'async',\n stripePromise: Promise.resolve(raw).then(function (result) {\n return validateStripe(result, errorMsg);\n })\n };\n }\n\n var stripe = validateStripe(raw, errorMsg);\n\n if (stripe === null) {\n return {\n tag: 'empty'\n };\n }\n\n return {\n tag: 'sync',\n stripe: stripe\n };\n};\n\nvar registerWithStripeJs = function registerWithStripeJs(stripe) {\n if (!stripe || !stripe._registerWrapper || !stripe.registerAppInfo) {\n return;\n }\n\n stripe._registerWrapper({\n name: 'react-stripe-js',\n version: \"6.6.0\"\n });\n\n stripe.registerAppInfo({\n name: 'react-stripe-js',\n version: \"6.6.0\",\n url: 'https://stripe.com/docs/stripe-js/react'\n });\n};\n\nvar ElementsContext = /*#__PURE__*/React.createContext(null);\nElementsContext.displayName = 'ElementsContext';\nvar parseElementsContext = function parseElementsContext(ctx, useCase) {\n if (!ctx) {\n throw new Error(\"Could not find Elements context; You need to wrap the part of your app that \".concat(useCase, \" in an <Elements> provider.\"));\n }\n\n return ctx;\n};\n/**\n * The `Elements` provider allows you to use [Element components](https://stripe.com/docs/stripe-js/react#element-components) and access the [Stripe object](https://stripe.com/docs/js/initializing) in any nested component.\n * Render an `Elements` provider at the root of your React app so that it is available everywhere you need it.\n *\n * To use the `Elements` provider, call `loadStripe` from `@stripe/stripe-js` with your publishable key.\n * The `loadStripe` function will asynchronously load the Stripe.js script and initialize a `Stripe` object.\n * Pass the returned `Promise` to `Elements`.\n *\n * @docs https://docs.stripe.com/sdks/stripejs-react?ui=elements#elements-provider\n */\n\nvar Elements = function Elements(_ref) {\n var rawStripeProp = _ref.stripe,\n options = _ref.options,\n children = _ref.children;\n var parsed = React.useMemo(function () {\n return parseStripeProp(rawStripeProp);\n }, [rawStripeProp]); // For a sync stripe instance, initialize into context\n\n var _React$useState = React.useState(function () {\n return {\n stripe: parsed.tag === 'sync' ? parsed.stripe : null,\n elements: parsed.tag === 'sync' ? parsed.stripe.elements(options) : null\n };\n }),\n _React$useState2 = _slicedToArray(_React$useState, 2),\n ctx = _React$useState2[0],\n setContext = _React$useState2[1];\n\n React.useEffect(function () {\n var isMounted = true;\n\n var safeSetContext = function safeSetContext(stripe) {\n setContext(function (ctx) {\n // no-op if we already have a stripe instance (https://github.com/stripe/react-stripe-js/issues/296)\n if (ctx.stripe) return ctx;\n return {\n stripe: stripe,\n elements: stripe.elements(options)\n };\n });\n }; // For an async stripePromise, store it in context once resolved\n\n\n if (parsed.tag === 'async' && !ctx.stripe) {\n parsed.stripePromise.then(function (stripe) {\n if (stripe && isMounted) {\n // Only update Elements context if the component is still mounted\n // and stripe is not null. We allow stripe to be null to make\n // handling SSR easier.\n safeSetContext(stripe);\n }\n });\n } else if (parsed.tag === 'sync' && !ctx.stripe) {\n // Or, handle a sync stripe instance going from null -> populated\n safeSetContext(parsed.stripe);\n }\n\n return function () {\n isMounted = false;\n };\n }, [parsed, ctx, options]); // Warn on changes to stripe prop\n\n var prevStripe = usePrevious(rawStripeProp);\n React.useEffect(function () {\n if (prevStripe !== null && prevStripe !== rawStripeProp) {\n console.warn('Unsupported prop change on Elements: You cannot change the `stripe` prop after setting it.');\n }\n }, [prevStripe, rawStripeProp]); // Apply updates to elements when options prop has relevant changes\n\n var prevOptions = usePrevious(options);\n React.useEffect(function () {\n if (!ctx.elements) {\n return;\n }\n\n var updates = extractAllowedOptionsUpdates(options, prevOptions, ['clientSecret', 'fonts']);\n\n if (updates) {\n ctx.elements.update(updates);\n }\n }, [options, prevOptions, ctx.elements]); // Attach react-stripe-js version to stripe.js instance\n\n React.useEffect(function () {\n registerWithStripeJs(ctx.stripe);\n }, [ctx.stripe]);\n return /*#__PURE__*/React.createElement(ElementsContext.Provider, {\n value: ctx\n }, children);\n};\nElements.propTypes = {\n stripe: PropTypes.any,\n options: PropTypes.object\n};\nvar useElementsContextWithUseCase = function useElementsContextWithUseCase(useCaseMessage) {\n var ctx = React.useContext(ElementsContext);\n return parseElementsContext(ctx, useCaseMessage);\n};\n/**\n * @docs https://stripe.com/docs/stripe-js/react#useelements-hook\n */\n\nvar useElements = function useElements() {\n var _useElementsContextWi = useElementsContextWithUseCase('calls useElements()'),\n elements = _useElementsContextWi.elements;\n\n return elements;\n};\n/**\n * @docs https://stripe.com/docs/stripe-js/react#elements-consumer\n */\n\nvar ElementsConsumer = function ElementsConsumer(_ref2) {\n var children = _ref2.children;\n var ctx = useElementsContextWithUseCase('mounts <ElementsConsumer>'); // Assert to satisfy the busted React.FC return type (it should be ReactNode)\n\n return children(ctx);\n};\nElementsConsumer.propTypes = {\n children: PropTypes.func.isRequired\n};\n\nvar CheckoutContext = /*#__PURE__*/React.createContext(null);\nCheckoutContext.displayName = 'CheckoutContext';\nvar useElementsOrCheckoutContextWithUseCase = function useElementsOrCheckoutContextWithUseCase(useCaseString) {\n var checkout = React.useContext(CheckoutContext);\n var elements = React.useContext(ElementsContext);\n\n if (checkout) {\n if (elements) {\n throw new Error(\"You cannot wrap the part of your app that \".concat(useCaseString, \" in both a checkout provider and <Elements> provider.\"));\n } else {\n return checkout;\n }\n } else {\n return parseElementsContext(elements, useCaseString);\n }\n}; // One runtime shape, two possible static types depending on the calling hook.\n\nvar _excluded = [\"mode\"];\n\nvar capitalized = function capitalized(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n};\n\nvar createElementComponent = function createElementComponent(type, isServer, customDisplayName) {\n var displayName = \"\".concat(capitalized(type), \"Element\");\n\n var ClientElement = function ClientElement(_ref) {\n var id = _ref.id,\n className = _ref.className,\n _ref$options = _ref.options,\n options = _ref$options === void 0 ? {} : _ref$options,\n onBlur = _ref.onBlur,\n onFocus = _ref.onFocus,\n onReady = _ref.onReady,\n onChange = _ref.onChange,\n onEscape = _ref.onEscape,\n onClick = _ref.onClick,\n onLoadError = _ref.onLoadError,\n onLoaderStart = _ref.onLoaderStart,\n onNetworksChange = _ref.onNetworksChange,\n onConfirm = _ref.onConfirm,\n onCancel = _ref.onCancel,\n onShippingAddressChange = _ref.onShippingAddressChange,\n onShippingRateChange = _ref.onShippingRateChange,\n onSavedPaymentMethodRemove = _ref.onSavedPaymentMethodRemove,\n onSavedPaymentMethodUpdate = _ref.onSavedPaymentMethodUpdate,\n onAvailablePaymentMethodsChange = _ref.onAvailablePaymentMethodsChange;\n var ctx = useElementsOrCheckoutContextWithUseCase(\"mounts <\".concat(displayName, \">\"));\n var elements = 'elements' in ctx ? ctx.elements : null;\n var checkoutState = 'checkoutState' in ctx ? ctx.checkoutState : null;\n var checkoutSdk = (checkoutState === null || checkoutState === void 0 ? void 0 : checkoutState.type) === 'success' || (checkoutState === null || checkoutState === void 0 ? void 0 : checkoutState.type) === 'loading' ? checkoutState.sdk : null;\n\n var _React$useState = React.useState(null),\n _React$useState2 = _slicedToArray(_React$useState, 2),\n element = _React$useState2[0],\n setElement = _React$useState2[1];\n\n var elementRef = React.useRef(null);\n var domNode = React.useRef(null); // For every event where the merchant provides a callback, call element.on\n // with that callback. If the merchant ever changes the callback, removes\n // the old callback with element.off and then call element.on with the new one.\n\n useAttachEvent(element, 'blur', onBlur);\n useAttachEvent(element, 'focus', onFocus);\n useAttachEvent(element, 'escape', onEscape);\n useAttachEvent(element, 'click', onClick);\n useAttachEvent(element, 'loaderror', onLoadError);\n useAttachEvent(element, 'loaderstart', onLoaderStart);\n useAttachEvent(element, 'networkschange', onNetworksChange);\n useAttachEvent(element, 'confirm', onConfirm);\n useAttachEvent(element, 'cancel', onCancel);\n useAttachEvent(element, 'shippingaddresschange', onShippingAddressChange);\n useAttachEvent(element, 'shippingratechange', onShippingRateChange);\n useAttachEvent(element, 'savedpaymentmethodremove', onSavedPaymentMethodRemove);\n useAttachEvent(element, 'savedpaymentmethodupdate', onSavedPaymentMethodUpdate);\n useAttachEvent(element, 'availablepaymentmethodschange', onAvailablePaymentMethodsChange);\n useAttachEvent(element, 'change', onChange);\n var readyCallback;\n\n if (onReady) {\n if (type === 'expressCheckout') {\n // Passes through the event, which includes visible PM types\n readyCallback = onReady;\n } else {\n // For other Elements, pass through the Element itself.\n readyCallback = function readyCallback() {\n onReady(element);\n };\n }\n }\n\n useAttachEvent(element, 'ready', readyCallback);\n React.useLayoutEffect(function () {\n if (elementRef.current === null && domNode.current !== null && (elements || checkoutSdk)) {\n var newElement = null;\n\n if (checkoutSdk) {\n var elementsSdk = checkoutSdk;\n var formSdk = checkoutSdk;\n\n switch (type) {\n case 'paymentForm':\n newElement = formSdk.createForm(options);\n break;\n\n case 'payment':\n newElement = elementsSdk.createPaymentElement(options);\n break;\n\n case 'address':\n if ('mode' in options) {\n var mode = options.mode,\n restOptions = _objectWithoutProperties(options, _excluded);\n\n if (mode === 'shipping') {\n newElement = elementsSdk.createShippingAddressElement(restOptions);\n } else if (mode === 'billing') {\n newElement = elementsSdk.createBillingAddressElement(restOptions);\n } else {\n throw new Error(\"Invalid options.mode. mode must be 'billing' or 'shipping'.\");\n }\n } else {\n throw new Error(\"You must supply options.mode. mode must be 'billing' or 'shipping'.\");\n }\n\n break;\n\n case 'expressCheckout':\n newElement = elementsSdk.createExpressCheckoutElement(options);\n break;\n\n case 'currencySelector':\n newElement = checkoutSdk.createCurrencySelectorElement();\n break;\n\n case 'taxId':\n newElement = elementsSdk.createTaxIdElement(options);\n break;\n\n case 'contactDetails':\n newElement = elementsSdk.createContactDetailsElement();\n break;\n\n default:\n throw new Error(\"<\".concat(displayName, \"> is not supported inside a checkout provider. Use an <Elements> provider instead.\"));\n }\n } else if (elements) {\n newElement = elements.create(type, options);\n } // Store element in a ref to ensure it's _immediately_ available in cleanup hooks in StrictMode\n\n\n elementRef.current = newElement; // Store element in state to facilitate event listener attachment\n\n setElement(newElement);\n\n if (newElement) {\n newElement.mount(domNode.current);\n }\n }\n }, [elements, checkoutSdk, options]);\n var prevOptions = usePrevious(options);\n React.useEffect(function () {\n if (!elementRef.current) {\n return;\n }\n\n var updates = extractAllowedOptionsUpdates(options, prevOptions, ['paymentRequest']);\n\n if (updates && 'update' in elementRef.current) {\n elementRef.current.update(updates);\n }\n }, [options, prevOptions]);\n React.useLayoutEffect(function () {\n return function () {\n if (elementRef.current && typeof elementRef.current.destroy === 'function') {\n try {\n elementRef.current.destroy();\n elementRef.current = null;\n } catch (error) {// Do nothing\n }\n }\n };\n }, []);\n return /*#__PURE__*/React.createElement(\"div\", {\n id: id,\n className: className,\n ref: domNode\n });\n }; // Only render the Element wrapper in a server environment.\n\n\n var ServerElement = function ServerElement(props) {\n useElementsOrCheckoutContextWithUseCase(\"mounts <\".concat(displayName, \">\"));\n var id = props.id,\n className = props.className;\n return /*#__PURE__*/React.createElement(\"div\", {\n id: id,\n className: className\n });\n };\n\n var Element = isServer ? ServerElement : ClientElement;\n Element.propTypes = {\n id: PropTypes.string,\n className: PropTypes.string,\n onChange: PropTypes.func,\n onBlur: PropTypes.func,\n onFocus: PropTypes.func,\n onReady: PropTypes.func,\n onEscape: PropTypes.func,\n onClick: PropTypes.func,\n onLoadError: PropTypes.func,\n onLoaderStart: PropTypes.func,\n onNetworksChange: PropTypes.func,\n onConfirm: PropTypes.func,\n onCancel: PropTypes.func,\n onShippingAddressChange: PropTypes.func,\n onShippingRateChange: PropTypes.func,\n onSavedPaymentMethodRemove: PropTypes.func,\n onSavedPaymentMethodUpdate: PropTypes.func,\n onAvailablePaymentMethodsChange: PropTypes.func,\n options: PropTypes.object\n };\n Element.displayName = displayName;\n Element.__elementType = type;\n return Element;\n};\n\nvar isServer = typeof window === 'undefined';\n\nvar EmbeddedCheckoutContext = /*#__PURE__*/React.createContext(null);\nEmbeddedCheckoutContext.displayName = 'EmbeddedCheckoutProviderContext';\nvar useEmbeddedCheckoutContext = function useEmbeddedCheckoutContext() {\n var ctx = React.useContext(EmbeddedCheckoutContext);\n\n if (!ctx) {\n throw new Error('<EmbeddedCheckout> must be used within <EmbeddedCheckoutProvider>');\n }\n\n return ctx;\n};\nvar INVALID_STRIPE_ERROR = 'Invalid prop `stripe` supplied to `EmbeddedCheckoutProvider`. We recommend using the `loadStripe` utility from `@stripe/stripe-js`. See https://stripe.com/docs/stripe-js/react#elements-props-stripe for details.';\nvar EmbeddedCheckoutProvider = function EmbeddedCheckoutProvider(_ref) {\n var rawStripeProp = _ref.stripe,\n options = _ref.options,\n children = _ref.children;\n var parsed = React.useMemo(function () {\n return parseStripeProp(rawStripeProp, INVALID_STRIPE_ERROR);\n }, [rawStripeProp]);\n var embeddedCheckoutPromise = React.useRef(null);\n var loadedStripe = React.useRef(null);\n\n var _React$useState = React.useState({\n embeddedCheckout: null\n }),\n _React$useState2 = _slicedToArray(_React$useState, 2),\n ctx = _React$useState2[0],\n setContext = _React$useState2[1];\n\n React.useEffect(function () {\n // Don't support any ctx updates once embeddedCheckout or stripe is set.\n if (loadedStripe.current || embeddedCheckoutPromise.current) {\n return;\n }\n\n var setStripeAndInitEmbeddedCheckout = function setStripeAndInitEmbeddedCheckout(stripe) {\n if (loadedStripe.current || embeddedCheckoutPromise.current) return;\n loadedStripe.current = stripe;\n embeddedCheckoutPromise.current = loadedStripe.current.createEmbeddedCheckoutPage(options).then(function (embeddedCheckout) {\n setContext({\n embeddedCheckout: embeddedCheckout\n });\n });\n }; // For an async stripePromise, store it once resolved\n\n\n if (parsed.tag === 'async' && !loadedStripe.current && (options.clientSecret || options.fetchClientSecret)) {\n parsed.stripePromise.then(function (stripe) {\n if (stripe) {\n setStripeAndInitEmbeddedCheckout(stripe);\n }\n });\n } else if (parsed.tag === 'sync' && !loadedStripe.current && (options.clientSecret || options.fetchClientSecret)) {\n // Or, handle a sync stripe instance going from null -> populated\n setStripeAndInitEmbeddedCheckout(parsed.stripe);\n }\n }, [parsed, options, ctx, loadedStripe]);\n React.useEffect(function () {\n // cleanup on unmount\n return function () {\n // If embedded checkout is fully initialized, destroy it.\n if (ctx.embeddedCheckout) {\n embeddedCheckoutPromise.current = null;\n ctx.embeddedCheckout.destroy();\n } else if (embeddedCheckoutPromise.current) {\n // If embedded checkout is still initializing, destroy it once\n // it's done. This could be caused by unmounting very quickly\n // after mounting.\n embeddedCheckoutPromise.current.then(function () {\n embeddedCheckoutPromise.current = null;\n\n if (ctx.embeddedCheckout) {\n ctx.embeddedCheckout.destroy();\n }\n });\n }\n };\n }, [ctx.embeddedCheckout]); // Attach react-stripe-js version to stripe.js instance\n\n React.useEffect(function () {\n registerWithStripeJs(loadedStripe);\n }, [loadedStripe]); // Warn on changes to stripe prop.\n // The stripe prop value can only go from null to non-null once and\n // can't be changed after that.\n\n var prevStripe = usePrevious(rawStripeProp);\n React.useEffect(function () {\n if (prevStripe !== null && prevStripe !== rawStripeProp) {\n console.warn('Unsupported prop change on EmbeddedCheckoutProvider: You cannot change the `stripe` prop after setting it.');\n }\n }, [prevStripe, rawStripeProp]); // Warn on changes to options.\n\n var prevOptions = usePrevious(options);\n React.useEffect(function () {\n if (prevOptions == null) {\n return;\n }\n\n if (options == null) {\n console.warn('Unsupported prop change on EmbeddedCheckoutProvider: You cannot unset options after setting them.');\n return;\n }\n\n if (options.clientSecret === undefined && options.fetchClientSecret === undefined) {\n console.warn('Invalid props passed to EmbeddedCheckoutProvider: You must provide one of either `options.fetchClientSecret` or `options.clientSecret`.');\n }\n\n if (prevOptions.clientSecret != null && options.clientSecret !== prevOptions.clientSecret) {\n console.warn('Unsupported prop change on EmbeddedCheckoutProvider: You cannot change the client secret after setting it. Unmount and create a new instance of EmbeddedCheckoutProvider instead.');\n }\n\n if (prevOptions.fetchClientSecret != null && options.fetchClientSecret !== prevOptions.fetchClientSecret) {\n console.warn('Unsupported prop change on EmbeddedCheckoutProvider: You cannot change fetchClientSecret after setting it. Unmount and create a new instance of EmbeddedCheckoutProvider instead.');\n }\n\n if (prevOptions.onComplete != null && options.onComplete !== prevOptions.onComplete) {\n console.warn('Unsupported prop change on EmbeddedCheckoutProvider: You cannot change the onComplete option after setting it.');\n }\n\n if (prevOptions.onShippingDetailsChange != null && options.onShippingDetailsChange !== prevOptions.onShippingDetailsChange) {\n console.warn('Unsupported prop change on EmbeddedCheckoutProvider: You cannot change the onShippingDetailsChange option after setting it.');\n }\n\n if (prevOptions.onLineItemsChange != null && options.onLineItemsChange !== prevOptions.onLineItemsChange) {\n console.warn('Unsupported prop change on EmbeddedCheckoutProvider: You cannot change the onLineItemsChange option after setting it.');\n }\n }, [prevOptions, options]);\n return /*#__PURE__*/React.createElement(EmbeddedCheckoutContext.Provider, {\n value: ctx\n }, children);\n};\n\nvar EmbeddedCheckoutClientElement = function EmbeddedCheckoutClientElement(_ref) {\n var id = _ref.id,\n className = _ref.className;\n\n var _useEmbeddedCheckoutC = useEmbeddedCheckoutContext(),\n embeddedCheckout = _useEmbeddedCheckoutC.embeddedCheckout;\n\n var isMounted = React.useRef(false);\n var domNode = React.useRef(null);\n React.useLayoutEffect(function () {\n if (!isMounted.current && embeddedCheckout && domNode.current !== null) {\n embeddedCheckout.mount(domNode.current);\n isMounted.current = true;\n } // Clean up on unmount\n\n\n return function () {\n if (isMounted.current && embeddedCheckout) {\n try {\n embeddedCheckout.unmount();\n isMounted.current = false;\n } catch (e) {// Do nothing.\n // Parent effects are destroyed before child effects, so\n // in cases where both the EmbeddedCheckoutProvider and\n // the EmbeddedCheckout component are removed at the same\n // time, the embeddedCheckout instance will be destroyed,\n // which causes an error when calling unmount.\n }\n }\n };\n }, [embeddedCheckout]);\n return /*#__PURE__*/React.createElement(\"div\", {\n ref: domNode,\n id: id,\n className: className\n });\n}; // Only render the wrapper in a server environment.\n\n\nvar EmbeddedCheckoutServerElement = function EmbeddedCheckoutServerElement(_ref2) {\n var id = _ref2.id,\n className = _ref2.className;\n // Validate that we are in the right context by calling useEmbeddedCheckoutContext.\n useEmbeddedCheckoutContext();\n return /*#__PURE__*/React.createElement(\"div\", {\n id: id,\n className: className\n });\n};\n\nvar EmbeddedCheckout = isServer ? EmbeddedCheckoutServerElement : EmbeddedCheckoutClientElement;\n\nvar FinancialAccountDisclosure = function FinancialAccountDisclosure(_ref) {\n var rawStripeProp = _ref.stripe,\n onLoad = _ref.onLoad,\n onError = _ref.onError,\n options = _ref.options;\n var businessName = options === null || options === void 0 ? void 0 : options.businessName;\n var learnMoreLink = options === null || options === void 0 ? void 0 : options.learnMoreLink;\n var containerRef = React.useRef(null);\n var parsed = React.useMemo(function () {\n return parseStripeProp(rawStripeProp);\n }, [rawStripeProp]);\n\n var _React$useState = React.useState(parsed.tag === 'sync' ? parsed.stripe : null),\n _React$useState2 = _slicedToArray(_React$useState, 2),\n stripeState = _React$useState2[0],\n setStripeState = _React$useState2[1];\n\n React.useEffect(function () {\n var isMounted = true;\n\n if (parsed.tag === 'async') {\n parsed.stripePromise.then(function (stripePromise) {\n if (stripePromise && isMounted) {\n setStripeState(stripePromise);\n }\n });\n } else if (parsed.tag === 'sync') {\n setStripeState(parsed.stripe);\n }\n\n return function () {\n isMounted = false;\n };\n }, [parsed]); // Warn on changes to stripe prop\n\n var prevStripe = usePrevious(rawStripeProp);\n React.useEffect(function () {\n if (prevStripe !== null && prevStripe !== rawStripeProp) {\n console.warn('Unsupported prop change on FinancialAccountDisclosure: You cannot change the `stripe` prop after setting it.');\n }\n }, [prevStripe, rawStripeProp]); // Attach react-stripe-js version to stripe.js instance\n\n React.useEffect(function () {\n registerWithStripeJs(stripeState);\n }, [stripeState]);\n React.useEffect(function () {\n var createDisclosure = /*#__PURE__*/function () {\n var _ref2 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {\n var _yield$stripeState$cr, disclosureContent, error, container;\n\n return regeneratorRuntime.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n if (!(!stripeState || !containerRef.current)) {\n _context.next = 2;\n break;\n }\n\n return _context.abrupt(\"return\");\n\n case 2:\n _context.next = 4;\n return stripeState.createFinancialAccountDisclosure({\n businessName: businessName,\n learnMoreLink: learnMoreLink\n });\n\n case 4:\n _yield$stripeState$cr = _context.sent;\n disclosureContent = _yield$stripeState$cr.htmlElement;\n error = _yield$stripeState$cr.error;\n\n if (error && onError) {\n onError(error);\n } else if (disclosureContent) {\n container = containerRef.current;\n container.innerHTML = '';\n container.appendChild(disclosureContent);\n\n if (onLoad) {\n onLoad();\n }\n }\n\n case 8:\n case \"end\":\n return _context.stop();\n }\n }\n }, _callee);\n }));\n\n return function createDisclosure() {\n return _ref2.apply(this, arguments);\n };\n }();\n\n createDisclosure();\n }, [stripeState, businessName, learnMoreLink, onLoad, onError]);\n return /*#__PURE__*/React.createElement('div', {\n ref: containerRef\n });\n};\n\nvar IssuingDisclosure = function IssuingDisclosure(_ref) {\n var rawStripeProp = _ref.stripe,\n onLoad = _ref.onLoad,\n onError = _ref.onError,\n options = _ref.options;\n var issuingProgramID = options === null || options === void 0 ? void 0 : options.issuingProgramID;\n var publicCardProgramName = options === null || options === void 0 ? void 0 : options.publicCardProgramName;\n var learnMoreLink = options === null || options === void 0 ? void 0 : options.learnMoreLink;\n var containerRef = React.useRef(null);\n var parsed = React.useMemo(function () {\n return parseStripeProp(rawStripeProp);\n }, [rawStripeProp]);\n\n var _React$useState = React.useState(parsed.tag === 'sync' ? parsed.stripe : null),\n _React$useState2 = _slicedToArray(_React$useState, 2),\n stripeState = _React$useState2[0],\n setStripeState = _React$useState2[1];\n\n React.useEffect(function () {\n var isMounted = true;\n\n if (parsed.tag === 'async') {\n parsed.stripePromise.then(function (stripePromise) {\n if (stripePromise && isMounted) {\n setStripeState(stripePromise);\n }\n });\n } else if (parsed.tag === 'sync') {\n setStripeState(parsed.stripe);\n }\n\n return function () {\n isMounted = false;\n };\n }, [parsed]); // Warn on changes to stripe prop\n\n var prevStripe = usePrevious(rawStripeProp);\n React.useEffect(function () {\n if (prevStripe !== null && prevStripe !== rawStripeProp) {\n console.warn('Unsupported prop change on IssuingDisclosure: You cannot change the `stripe` prop after setting it.');\n }\n }, [prevStripe, rawStripeProp]); // Attach react-stripe-js version to stripe.js instance\n\n React.useEffect(function () {\n registerWithStripeJs(stripeState);\n }, [stripeState]);\n React.useEffect(function () {\n var createDisclosure = /*#__PURE__*/function () {\n var _ref2 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {\n var _yield$stripeState$cr, disclosureContent, error, container;\n\n return regeneratorRuntime.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n if (!(!stripeState || !containerRef.current)) {\n _context.next = 2;\n break;\n }\n\n return _context.abrupt(\"return\");\n\n case 2:\n _context.next = 4;\n return stripeState.createIssuingDisclosure({\n issuingProgramID: issuingProgramID,\n publicCardProgramName: publicCardProgramName,\n learnMoreLink: learnMoreLink\n });\n\n case 4:\n _yield$stripeState$cr = _context.sent;\n disclosureContent = _yield$stripeState$cr.htmlElement;\n error = _yield$stripeState$cr.error;\n\n if (error && onError) {\n onError(error);\n } else if (disclosureContent) {\n container = containerRef.current;\n container.innerHTML = '';\n container.appendChild(disclosureContent);\n\n if (onLoad) {\n onLoad();\n }\n }\n\n case 8:\n case \"end\":\n return _context.stop();\n }\n }\n }, _callee);\n }));\n\n return function createDisclosure() {\n return _ref2.apply(this, arguments);\n };\n }();\n\n createDisclosure();\n }, [stripeState, issuingProgramID, publicCardProgramName, learnMoreLink, onLoad, onError]);\n return /*#__PURE__*/React.createElement('div', {\n ref: containerRef\n });\n};\n\n/**\n * @docs https://stripe.com/docs/stripe-js/react#usestripe-hook\n */\n\nvar useStripe = function useStripe() {\n var _useElementsOrCheckou = useElementsOrCheckoutContextWithUseCase('calls useStripe()'),\n stripe = _useElementsOrCheckou.stripe;\n\n return stripe;\n};\n\n/**\n * Requires beta access:\n * Contact [Stripe support](https://support.stripe.com/) for more information.\n *\n * @docs https://stripe.com/docs/stripe-js/react#element-components\n */\n\nvar AuBankAccountElement = createElementComponent('auBankAccount', isServer);\n/**\n * @docs https://stripe.com/docs/stripe-js/react#element-components\n */\n\nvar CardElement = createElementComponent('card', isServer);\n/**\n * @docs https://stripe.com/docs/stripe-js/react#element-components\n */\n\nvar CardNumberElement = createElementComponent('cardNumber', isServer);\n/**\n * @docs https://stripe.com/docs/stripe-js/react#element-components\n */\n\nvar CardExpiryElement = createElementComponent('cardExpiry', isServer);\n/**\n * @docs https://stripe.com/docs/stripe-js/react#element-components\n */\n\nvar CardCvcElement = createElementComponent('cardCvc', isServer);\n/**\n * Requires beta access:\n * Contact [Stripe support](https://support.stripe.com/) for more information.\n */\n\nvar CurrencySelectorElement = createElementComponent('currencySelector', isServer);\n/**\n * @docs https://stripe.com/docs/stripe-js/react#element-components\n */\n\nvar IbanElement = createElementComponent('iban', isServer);\nvar PaymentElement = createElementComponent('payment', isServer);\n/**\n * @docs https://stripe.com/docs/stripe-js/react#element-components\n */\n\nvar ExpressCheckoutElement = createElementComponent('expressCheckout', isServer);\n/**\n * @docs https://stripe.com/docs/stripe-js/react#element-components\n */\n\nvar PaymentRequestButtonElement = createElementComponent('paymentRequestButton', isServer);\n/**\n * @docs https://stripe.com/docs/stripe-js/react#element-components\n */\n\nvar LinkAuthenticationElement = createElementComponent('linkAuthentication', isServer);\n/**\n * @docs https://stripe.com/docs/stripe-js/react#element-components\n */\n\nvar ContactDetailsElement = createElementComponent('contactDetails', isServer);\n/**\n * @docs https://stripe.com/docs/stripe-js/react#element-components\n */\n\nvar AddressElement = createElementComponent('address', isServer);\n/**\n * @deprecated\n * Use `AddressElement` instead.\n *\n * @docs https://stripe.com/docs/stripe-js/react#element-components\n */\n\nvar ShippingAddressElement = createElementComponent('shippingAddress', isServer);\n/**\n * @docs https://stripe.com/docs/stripe-js/react#element-components\n */\n\nvar PaymentMethodMessagingElement = createElementComponent('paymentMethodMessaging', isServer);\n/**\n * Requires beta access:\n * Contact [Stripe support](https://support.stripe.com/) for more information.\n */\n\nvar TaxIdElement = createElementComponent('taxId', isServer);\n/**\n * @docs https://stripe.com/docs/issuing/elements\n */\n\nvar IssuingCardNumberDisplayElement = createElementComponent('issuingCardNumberDisplay', isServer);\n/**\n * @docs https://stripe.com/docs/issuing/elements\n */\n\nvar IssuingCardCvcDisplayElement = createElementComponent('issuingCardCvcDisplay', isServer);\n/**\n * @docs https://stripe.com/docs/issuing/elements\n */\n\nvar IssuingCardExpiryDisplayElement = createElementComponent('issuingCardExpiryDisplay', isServer);\n/**\n * @docs https://stripe.com/docs/issuing/elements\n */\n\nvar IssuingCardPinDisplayElement = createElementComponent('issuingCardPinDisplay', isServer);\n/**\n * @docs https://stripe.com/docs/issuing/elements\n */\n\nvar IssuingCardCopyButtonElement = createElementComponent('issuingCardCopyButton', isServer);\n\nexport { AddressElement, AuBankAccountElement, CardCvcElement, CardElement, CardExpiryElement, CardNumberElement, ContactDetailsElement, CurrencySelectorElement, Elements, ElementsConsumer, EmbeddedCheckout, EmbeddedCheckoutProvider, ExpressCheckoutElement, FinancialAccountDisclosure, IbanElement, IssuingCardCopyButtonElement, IssuingCardCvcDisplayElement, IssuingCardExpiryDisplayElement, IssuingCardNumberDisplayElement, IssuingCardPinDisplayElement, IssuingDisclosure, LinkAuthenticationElement, PaymentElement, PaymentMethodMessagingElement, PaymentRequestButtonElement, ShippingAddressElement, TaxIdElement, useElements, useStripe };\n","import { Button } from '@/components/ui/button';\nimport { useProcessStripePaymentMethod } from '@/integrations/stripe/useProcessStripePaymentMethod';\n\nimport { useStripeOptions } from '@/integrations/stripe/useStripeOptions';\nimport { AddressElement, PaymentElement, useElements, useStripe } from '@stripe/react-stripe-js';\nimport { useParams } from '@tanstack/react-router';\nimport { Save } from 'lucide-react';\nimport { FormEvent, useCallback, useState } from 'react';\nimport { toast } from 'sonner';\n\ninterface AddNewPaymentMethodFormProps {\n\treadonly hasExistingBilling: boolean;\n\treadonly onPaymentAdded: (added: boolean) => void;\n\treadonly onSaveStateForBillingRedirect?: (redirecting: boolean) => void;\n}\n\nexport function AddNewPaymentMethodForm({\n\thasExistingBilling,\n\tonPaymentAdded,\n\tonSaveStateForBillingRedirect,\n}: AddNewPaymentMethodFormProps) {\n\tconst { organizationId } = useParams({ strict: false });\n\tconst stripe = useStripe();\n\tconst stripeOptions = useStripeOptions();\n\tconst elements = useElements();\n\tconst [loading, setLoading] = useState(false);\n\tconst processStripePaymentMethod = useProcessStripePaymentMethod(organizationId);\n\n\tconst onCancelClicked = useCallback(() => {\n\t\tonPaymentAdded(false);\n\t}, [onPaymentAdded]);\n\n\tconst onSubmitAddPaymentMethod = useCallback(async (evt: FormEvent) => {\n\t\tevt.preventDefault();\n\t\tif (!stripe || !elements) {\n\t\t\treturn;\n\t\t}\n\t\tsetLoading(true);\n\n\t\tawait elements.submit();\n\t\tonSaveStateForBillingRedirect?.(true);\n\t\tconst result = await stripe.confirmSetup({\n\t\t\tclientSecret: stripeOptions.clientSecret!,\n\t\t\telements,\n\t\t\tredirect: 'if_required',\n\t\t\t// If you want to test the redirect, this will force it to happen.\n\t\t\t// redirect: 'always' as 'if_required',\n\t\t\tconfirmParams: {\n\t\t\t\treturn_url: `${window.location.origin}/#/${organizationId}/billing/confirm`,\n\t\t\t},\n\t\t});\n\n\t\tif (result.error) {\n\t\t\tconsole.error(result.error.message);\n\t\t\ttoast.error(result.error.message);\n\t\t\tsetLoading(false);\n\t\t\tonSaveStateForBillingRedirect?.(false);\n\t\t} else if (result.setupIntent.payment_method) {\n\t\t\tprocessStripePaymentMethod(result.setupIntent.payment_method, onPaymentAdded);\n\t\t\tonSaveStateForBillingRedirect?.(false);\n\t\t} else {\n\t\t\t// For some payment methods, they will be redirected to an intermediate site first to authorize the\n\t\t\t// payment, then redirected to the `return_url`.\n\t\t}\n\t}, [\n\t\telements,\n\t\tonPaymentAdded,\n\t\tonSaveStateForBillingRedirect,\n\t\torganizationId,\n\t\tprocessStripePaymentMethod,\n\t\tstripe,\n\t\tstripeOptions.clientSecret,\n\t]);\n\n\treturn (\n\t\t<form\n\t\t\tid=\"billing-add-payment-method-form\"\n\t\t\tname=\"billing-add-payment-method-form\"\n\t\t\tonSubmit={onSubmitAddPaymentMethod}\n\t\t\tclassName=\"max-w-xl\"\n\t\t>\n\t\t\t<PaymentElement />\n\t\t\t<AddressElement options={{ mode: 'billing' }} />\n\n\t\t\t<div className=\"mt-4 flex gap-8 items-center\">\n\t\t\t\t<Button disabled={!stripe || !elements || loading} variant=\"submit\" className=\"rounded-full\">\n\t\t\t\t\t<Save /> Add Payment Method\n\t\t\t\t</Button>\n\t\t\t\t{hasExistingBilling && (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<div className=\"text-xs text-gray-600\">Your existing payment method will be overwritten.</div>\n\t\t\t\t\t\t<Button variant=\"defaultOutline\" type=\"button\" onClick={onCancelClicked}>Cancel</Button>\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</form>\n\t);\n}\n","function _typeof(obj) {\n \"@babel/helpers - typeof\";\n\n if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") {\n _typeof = function (obj) {\n return typeof obj;\n };\n } else {\n _typeof = function (obj) {\n return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n };\n }\n\n return _typeof(obj);\n}\n\nvar RELEASE_TRAIN = 'dahlia';\n\nvar runtimeVersionToUrlVersion = function runtimeVersionToUrlVersion(version) {\n return version === 3 ? 'v3' : version;\n};\n\nvar ORIGIN = 'https://js.stripe.com';\nvar STRIPE_JS_URL = \"\".concat(ORIGIN, \"/\").concat(RELEASE_TRAIN, \"/stripe.js\");\nvar V3_URL_REGEX = /^https:\\/\\/js\\.stripe\\.com\\/v3\\/?(\\?.*)?$/;\nvar STRIPE_JS_URL_REGEX = /^https:\\/\\/js\\.stripe\\.com\\/(v3|[a-z]+)\\/stripe\\.js(\\?.*)?$/;\nvar EXISTING_SCRIPT_MESSAGE = 'loadStripe.setLoadParameters was called but an existing Stripe.js script already exists in the document; existing script parameters will be used';\n\nvar isStripeJSURL = function isStripeJSURL(url) {\n return V3_URL_REGEX.test(url) || STRIPE_JS_URL_REGEX.test(url);\n};\n\nvar findScript = function findScript() {\n var scripts = document.querySelectorAll(\"script[src^=\\\"\".concat(ORIGIN, \"\\\"]\"));\n\n for (var i = 0; i < scripts.length; i++) {\n var script = scripts[i];\n\n if (!isStripeJSURL(script.src)) {\n continue;\n }\n\n return script;\n }\n\n return null;\n};\n\nvar injectScript = function injectScript(params) {\n var queryString = params && !params.advancedFraudSignals ? '?advancedFraudSignals=false' : '';\n var script = document.createElement('script');\n script.src = \"\".concat(STRIPE_JS_URL).concat(queryString);\n var headOrBody = document.head || document.body;\n\n if (!headOrBody) {\n throw new Error('Expected document.body not to be null. Stripe.js requires a <body> element.');\n }\n\n headOrBody.appendChild(script);\n return script;\n};\n\nvar registerWrapper = function registerWrapper(stripe, startTime) {\n if (!stripe || !stripe._registerWrapper) {\n return;\n }\n\n stripe._registerWrapper({\n name: 'stripe-js',\n version: \"9.7.0\",\n startTime: startTime\n });\n};\n\nvar stripePromise$1 = null;\nvar onErrorListener = null;\nvar onLoadListener = null;\n\nvar onError = function onError(reject) {\n return function (cause) {\n reject(new Error('Failed to load Stripe.js', {\n cause: cause\n }));\n };\n};\n\nvar onLoad = function onLoad(resolve, reject) {\n return function () {\n if (window.Stripe) {\n resolve(window.Stripe);\n } else {\n reject(new Error('Stripe.js not available'));\n }\n };\n};\n\nvar loadScript = function loadScript(params) {\n // Ensure that we only attempt to load Stripe.js at most once\n if (stripePromise$1 !== null) {\n return stripePromise$1;\n }\n\n stripePromise$1 = new Promise(function (resolve, reject) {\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n // Resolve to null when imported server side. This makes the module\n // safe to import in an isomorphic code base.\n resolve(null);\n return;\n }\n\n if (window.Stripe && params) {\n console.warn(EXISTING_SCRIPT_MESSAGE);\n }\n\n if (window.Stripe) {\n resolve(window.Stripe);\n return;\n }\n\n try {\n var script = findScript();\n\n if (script && params) {\n console.warn(EXISTING_SCRIPT_MESSAGE);\n } else if (!script) {\n script = injectScript(params);\n } else if (script && onLoadListener !== null && onErrorListener !== null) {\n var _script$parentNode;\n\n // remove event listeners\n script.removeEventListener('load', onLoadListener);\n script.removeEventListener('error', onErrorListener); // if script exists, but we are reloading due to an error,\n // reload script to trigger 'load' event\n\n (_script$parentNode = script.parentNode) === null || _script$parentNode === void 0 ? void 0 : _script$parentNode.removeChild(script);\n script = injectScript(params);\n }\n\n onLoadListener = onLoad(resolve, reject);\n onErrorListener = onError(reject);\n script.addEventListener('load', onLoadListener);\n script.addEventListener('error', onErrorListener);\n } catch (error) {\n reject(error);\n return;\n }\n }); // Resets stripePromise on error\n\n return stripePromise$1[\"catch\"](function (error) {\n stripePromise$1 = null;\n return Promise.reject(error);\n });\n};\nvar initStripe = function initStripe(maybeStripe, args, startTime) {\n if (maybeStripe === null) {\n return null;\n }\n\n var pk = args[0];\n\n if (typeof pk !== 'string') {\n throw new Error(\"Expected publishable key to be of type string, got type \".concat(_typeof(pk), \" instead.\"));\n }\n\n var isTestKey = pk.match(/^pk_test/); // @ts-expect-error this is not publicly typed\n\n var version = runtimeVersionToUrlVersion(maybeStripe.version);\n var expectedVersion = RELEASE_TRAIN;\n\n if (isTestKey && version !== expectedVersion) {\n console.warn(\"Stripe.js@\".concat(version, \" was loaded on the page, but @stripe/stripe-js@\").concat(\"9.7.0\", \" expected Stripe.js@\").concat(expectedVersion, \". This may result in unexpected behavior. For more information, see https://docs.stripe.com/sdks/stripejs-versioning\"));\n }\n\n var stripe = maybeStripe.apply(undefined, args);\n registerWrapper(stripe, startTime);\n return stripe;\n}; // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\n\nvar stripePromise;\nvar loadCalled = false;\n\nvar getStripePromise = function getStripePromise() {\n if (stripePromise) {\n return stripePromise;\n }\n\n stripePromise = loadScript(null)[\"catch\"](function (error) {\n // clear cache on error\n stripePromise = null;\n return Promise.reject(error);\n });\n return stripePromise;\n}; // Execute our own script injection after a tick to give users time to do their\n// own script injection.\n\n\nPromise.resolve().then(function () {\n return getStripePromise();\n})[\"catch\"](function (error) {\n if (!loadCalled) {\n console.warn(error);\n }\n});\nvar loadStripe = function loadStripe() {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n loadCalled = true;\n var startTime = Date.now(); // if previous attempts are unsuccessful, will re-load script\n\n return getStripePromise().then(function (maybeStripe) {\n return initStripe(maybeStripe, args, startTime);\n });\n};\n\nexport { loadStripe };\n","import { apiClient } from '@/config/apiClient';\nimport { SchemaStripeAccount } from '@/integrations/api/api.gen';\nimport { useMutation } from '@tanstack/react-query';\n\ninterface Params {\n\torganizationId: string;\n}\n\nexport async function addStripeToOrganizationAndGetIntent(params: Params): Promise<SchemaStripeAccount> {\n\tconst { data } = await apiClient.post(`/StripeAccount/`, params);\n\treturn data;\n}\n\nexport function useAddStripeToOrganizationAndGetIntent() {\n\treturn useMutation<SchemaStripeAccount, Error, Params>({\n\t\tmutationFn: (params: Params) => addStripeToOrganizationAndGetIntent(params),\n\t});\n}\n","import { apiClient } from '@/config/apiClient';\nimport { SchemaStripeAccount } from '@/integrations/api/api.gen';\nimport { useMutation } from '@tanstack/react-query';\n\ninterface Params {\n\torganizationId: string;\n}\n\nexport async function getNewStripeIntentForOrganization(params: Params): Promise<SchemaStripeAccount> {\n\t// TODO: POST /Payment/ isn't describing itself from the API.\n\tconst { data } = await apiClient.post(`/Payment/`, { organizationId: params.organizationId });\n\treturn data as SchemaStripeAccount;\n}\n\nexport function useGetNewStripeIntentForOrganization() {\n\treturn useMutation<SchemaStripeAccount, Error, Params>({\n\t\tmutationFn: (params: Params) => getNewStripeIntentForOrganization(params),\n\t});\n}\n","import { SchemaStripeAccount } from '@/integrations/api/api.gen';\nimport { useAddStripeToOrganizationAndGetIntent } from '@/integrations/stripe/addStripeToOrganizationAndGetIntent';\nimport { useGetNewStripeIntentForOrganization } from '@/integrations/stripe/getNewStripeIntentForOrganization';\nimport { useCallback, useEffect, useState } from 'react';\n\ninterface Params {\n\tenabled: boolean;\n\torganizationId: string;\n\texistingStripeId: string | undefined;\n}\n\nexport function useGetStripeClientSecret(params: Params) {\n\tconst { enabled, existingStripeId, organizationId } = params;\n\tconst { mutate: addStripeToOrganizationAndGetIntent } = useAddStripeToOrganizationAndGetIntent();\n\tconst { mutate: getNewStripeIntentForOrganization } = useGetNewStripeIntentForOrganization();\n\tconst [clientSecret, setClientSecret] = useState<string | undefined>(undefined);\n\n\tconst gotClientSecret = useCallback((data: SchemaStripeAccount) => {\n\t\tsetClientSecret(data.clientSecret);\n\t}, []);\n\n\tuseEffect(() => {\n\t\tif (enabled && import.meta.env.VITE_PUBLIC_STRIPE_KEY) {\n\t\t\tif (existingStripeId) {\n\t\t\t\tgetNewStripeIntentForOrganization({ organizationId }, { onSuccess: gotClientSecret });\n\t\t\t} else {\n\t\t\t\taddStripeToOrganizationAndGetIntent({ organizationId }, { onSuccess: gotClientSecret });\n\t\t\t}\n\t\t}\n\t}, [\n\t\taddStripeToOrganizationAndGetIntent,\n\t\tenabled,\n\t\texistingStripeId,\n\t\tgetNewStripeIntentForOrganization,\n\t\tgotClientSecret,\n\t\torganizationId,\n\t]);\n\n\treturn clientSecret;\n}\n","import { Loading } from '@/components/Loading';\nimport { getOrganizationQueryOptions } from '@/features/organization/queries/getOrganizationQuery';\nimport { useSystemTheme } from '@/hooks/useSystemTheme';\nimport { stripePromise } from '@/integrations/stripe/stripePromise';\nimport { useGetStripeClientSecret } from '@/integrations/stripe/useGetStripeClientSecret';\nimport { StripeContext } from '@/integrations/stripe/useStripeOptions';\nimport { Elements } from '@stripe/react-stripe-js';\nimport { useQuery } from '@tanstack/react-query';\nimport { useParams } from '@tanstack/react-router';\nimport { ReactNode, useMemo } from 'react';\n\nexport function StripeWrapper({ children }: { children: ReactNode }) {\n\tconst { organizationId } = useParams({ strict: false });\n\tconst { data: organization } = useQuery(getOrganizationQueryOptions(organizationId));\n\tconst clientSecret = useGetStripeClientSecret({\n\t\torganizationId,\n\t\tenabled: !!organization,\n\t\texistingStripeId: organization?.stripeId,\n\t});\n\tconst systemTheme = useSystemTheme();\n\tconst options = useMemo(() => {\n\t\treturn {\n\t\t\tclientSecret: clientSecret || '',\n\t\t\tappearance: {\n\t\t\t\ttheme: systemTheme === 'dark' ? 'night' as const : 'stripe' as const,\n\t\t\t},\n\t\t};\n\t}, [clientSecret, systemTheme]);\n\n\tif (!import.meta.env.VITE_PUBLIC_STRIPE_KEY) {\n\t\tconsole.error('No VITE_PUBLIC_STRIPE_KEY is configured for this environment.');\n\t\treturn (\n\t\t\t<div className=\"mt-20 px-4 pt-4 md:px-12 min-h-[calc(100vh-theme(spacing.32))]\">\n\t\t\t\tSetting up your billing is currently disabled. Please check back again later.\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!clientSecret || !organization) {\n\t\treturn <Loading centered />;\n\t}\n\n\treturn (\n\t\t<StripeContext value={options}>\n\t\t\t<Elements stripe={stripePromise()} options={options}>\n\t\t\t\t{children}\n\t\t\t</Elements>\n\t\t</StripeContext>\n\t);\n}\n","import { AddNewPaymentMethodForm } from '@/features/organization/billing/paymentMethod/AddNewPaymentMethodForm';\nimport { getOrganizationQueryOptions } from '@/features/organization/queries/getOrganizationQuery';\nimport { StripeWrapper } from '@/integrations/stripe/StripeContext';\nimport { useQuery } from '@tanstack/react-query';\nimport { useParams } from '@tanstack/react-router';\n\ninterface AddNewPaymentMethodProps {\n\treadonly onPaymentAdded: (added: boolean) => void;\n\treadonly onSaveStateForBillingRedirect?: (redirecting: boolean) => void;\n}\n\nexport function AddNewPaymentMethod({ onPaymentAdded, onSaveStateForBillingRedirect }: AddNewPaymentMethodProps) {\n\tconst { organizationId } = useParams({ strict: false });\n\tconst { data: organization } = useQuery(getOrganizationQueryOptions(organizationId));\n\tconst billing = organization?.billing;\n\tconst paymentMethod = billing?.paymentMethod;\n\n\treturn (\n\t\t<StripeWrapper>\n\t\t\t<div className=\"mt-2 mb-6\">\n\t\t\t\t{!paymentMethod && 'You currently have no payment method on file. Please fill out the secure form below.'}\n\t\t\t</div>\n\t\t\t<AddNewPaymentMethodForm\n\t\t\t\thasExistingBilling={!!billing}\n\t\t\t\tonSaveStateForBillingRedirect={onSaveStateForBillingRedirect}\n\t\t\t\tonPaymentAdded={onPaymentAdded}\n\t\t\t/>\n\t\t</StripeWrapper>\n\t);\n}\n","export const enum PaymentMethodStatus {\n\tPASS = 'pass',\n\tFAIL = 'fail',\n\tPENDING = 'pending',\n\tERROR = 'error',\n}\n","import { BadgeStatusVariantValues } from '@/components/ui/utils/badgeStatus';\nimport { PaymentMethodStatus } from '@/integrations/stripe/paymentMethodStatus';\n\nexport function translateStripePaymentMethodStatusToVariant(\n\tpaymentMethodStatus: PaymentMethodStatus | string,\n): BadgeStatusVariantValues {\n\tswitch (paymentMethodStatus) {\n\t\tcase PaymentMethodStatus.PASS:\n\t\t\treturn 'success';\n\t\tcase PaymentMethodStatus.FAIL:\n\t\tcase PaymentMethodStatus.ERROR:\n\t\t\treturn 'destructive';\n\t\tcase PaymentMethodStatus.PENDING:\n\t\tdefault:\n\t\t\treturn 'default';\n\t}\n}\n\nexport function translateStripePaymentMethodStatusToText(paymentMethodStatus: PaymentMethodStatus | string): string {\n\tswitch (paymentMethodStatus) {\n\t\tcase PaymentMethodStatus.PASS:\n\t\t\treturn 'READY';\n\t\tcase PaymentMethodStatus.FAIL:\n\t\tcase PaymentMethodStatus.ERROR:\n\t\tcase PaymentMethodStatus.PENDING:\n\t\tdefault:\n\t\t\treturn paymentMethodStatus.toUpperCase();\n\t}\n}\n","export function formatMonthAndYear(month: number, year: number): string {\n\tconst mm = String(month).padStart(2, '0');\n\t// Use two-digit year for typical card expiration display\n\tconst yy = String(year % 100).padStart(2, '0');\n\treturn `${mm}/${yy}`;\n}\n","import { ContactUs } from '@/components/ContactUs';\nimport { Badge } from '@/components/ui/badge';\nimport { Button } from '@/components/ui/button';\nimport { AddNewPaymentMethod } from '@/features/organization/billing/paymentMethod/AddNewPaymentMethod';\nimport { getOrganizationQueryOptions } from '@/features/organization/queries/getOrganizationQuery';\nimport { useOrganizationPermissions } from '@/hooks/usePermissions';\nimport { ENTERPRISE } from '@/integrations/api/orgType';\nimport {\n\ttranslateStripePaymentMethodStatusToText,\n\ttranslateStripePaymentMethodStatusToVariant,\n} from '@/integrations/stripe/translateStripePaymentMethodStatus';\nimport { formatMonthAndYear } from '@/lib/formatMonthAndYear';\nimport { useQuery } from '@tanstack/react-query';\nimport { useParams } from '@tanstack/react-router';\nimport { useCallback, useState } from 'react';\n\ninterface PaymentMethodsDisplayProps {\n\tonSaveStateForBillingRedirect?: (redirecting: boolean) => void;\n\tonReplacingPaymentMethod?: (value: boolean) => void;\n}\n\nexport function PaymentMethodsDisplay(props?: PaymentMethodsDisplayProps) {\n\tconst { onSaveStateForBillingRedirect, onReplacingPaymentMethod } = props ?? {};\n\tconst { organizationId } = useParams({ strict: false });\n\tconst { update } = useOrganizationPermissions(organizationId);\n\tconst { data: organization, refetch } = useQuery(getOrganizationQueryOptions(organizationId));\n\tconst billing = organization?.billing;\n\tconst paymentMethod = billing?.paymentMethod;\n\tconst [replacingPaymentMethod, setReplacingPaymentMethod] = useState(false);\n\tconst onReplacePaymentMethodClicked = useCallback(\n\t\t() => {\n\t\t\tsetReplacingPaymentMethod(!replacingPaymentMethod);\n\t\t\tonReplacingPaymentMethod?.(!replacingPaymentMethod);\n\t\t},\n\t\t[onReplacingPaymentMethod, replacingPaymentMethod],\n\t);\n\tconst onPaymentAdded = useCallback((added: boolean) => {\n\t\tsetReplacingPaymentMethod(false);\n\t\tonReplacingPaymentMethod?.(false);\n\t\tif (added) {\n\t\t\tvoid refetch();\n\t\t}\n\t}, [onReplacingPaymentMethod, refetch]);\n\n\tif (organization?.type === ENTERPRISE) {\n\t\treturn (\n\t\t\t<span>\n\t\t\t\tYou are part of an enterprise organization! We don&rsquo;t currently show your payment methods on this page.\n\t\t\t\tWant to explore your solution with Harper more? <ContactUs />, we would love to talk!\n\t\t\t</span>\n\t\t);\n\t}\n\n\tif (paymentMethod && !replacingPaymentMethod) {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<div className=\"mt-2\">\n\t\t\t\t\t{paymentMethod.brand?.toUpperCase() ?? 'Card'} ending in {paymentMethod.last4 ?? '••••'}\n\t\t\t\t\t{(paymentMethod.expMonth && paymentMethod.expYear)\n\t\t\t\t\t\t? <>(exp {formatMonthAndYear(paymentMethod.expMonth, paymentMethod.expYear)})</>\n\t\t\t\t\t\t: null}\n\t\t\t\t\t{paymentMethod.status\n\t\t\t\t\t\t? (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t—{' '}\n\t\t\t\t\t\t\t\t<Badge variant={translateStripePaymentMethodStatusToVariant(paymentMethod.status)}>\n\t\t\t\t\t\t\t\t\t{translateStripePaymentMethodStatusToText(paymentMethod.status)}\n\t\t\t\t\t\t\t\t</Badge>\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)\n\t\t\t\t\t\t: null}\n\t\t\t\t</div>\n\t\t\t\t{update && (\n\t\t\t\t\t<div className=\"mt-2 mb-6\">\n\t\t\t\t\t\t<Button variant=\"defaultOutline\" type=\"button\" onClick={onReplacePaymentMethodClicked}>\n\t\t\t\t\t\t\tReplace Payment Method\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</>\n\t\t);\n\t}\n\n\tif (!update) {\n\t\treturn (\n\t\t\t<div>\n\t\t\t\tThis org doesn't have a payment method, and you don't have access to add one. Please contact your administrator.\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<AddNewPaymentMethod\n\t\t\tonSaveStateForBillingRedirect={onSaveStateForBillingRedirect}\n\t\t\tonPaymentAdded={onPaymentAdded}\n\t\t/>\n\t);\n}\n","import { ContactUs } from '@/components/ContactUs';\nimport { Button } from '@/components/ui/button';\nimport { PaymentMethodsDisplay } from '@/features/organization/billing/paymentMethod/PaymentMethodsDisplay';\nimport { getOrganizationQueryOptions } from '@/features/organization/queries/getOrganizationQuery';\nimport { SchemaPlan } from '@/integrations/api/api.gen';\nimport { ENTERPRISE } from '@/integrations/api/orgType';\nimport { PaymentMethodStatus } from '@/integrations/stripe/paymentMethodStatus';\nimport { pluralize } from '@/lib/pluralize';\nimport { isPositive } from '@/lib/types/isPositive';\nimport { useQuery } from '@tanstack/react-query';\nimport { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react';\nimport { useState } from 'react';\n\ninterface ClusterBillingProps {\n\treadonly clusterId?: string;\n\treadonly isPending: boolean;\n\treadonly onGoBackToDetails: () => void;\n\treadonly onSaveStateForBillingRedirect: (redirecting: boolean) => void;\n\treadonly onSubmit?: () => void;\n\treadonly organizationId: string;\n\treadonly selectedPlan: SchemaPlan | undefined;\n}\n\nexport function ClusterBilling({\n\tclusterId,\n\tisPending,\n\tonGoBackToDetails,\n\tonSaveStateForBillingRedirect,\n\tonSubmit,\n\torganizationId,\n\tselectedPlan,\n}: ClusterBillingProps) {\n\tconst { data: organization } = useQuery(getOrganizationQueryOptions(organizationId));\n\tconst billing = organization?.billing;\n\tconst allowBypass = import.meta.env.DEV && !import.meta.env.VITE_PUBLIC_STRIPE_KEY;\n\tconst isEnterprise = organization?.type === ENTERPRISE;\n\tconst hasValidPaymentMethod = allowBypass || isEnterprise\n\t\t|| billing?.paymentMethod?.status === PaymentMethodStatus.PASS;\n\tconst [replacingPaymentMethod, setReplacingPaymentMethod] = useState(false);\n\tconst expirationMonths = isPositive(selectedPlan?.planLimits?.expirationMonths)\n\t\t&& selectedPlan.planLimits.expirationMonths < 1000 && selectedPlan.planLimits.expirationMonths;\n\n\tconst footer = (\n\t\t<>\n\t\t\t<div className=\"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end mt-3 max-w-xl\">\n\t\t\t\t<Button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tvariant=\"defaultOutline\"\n\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\tdisabled={isPending}\n\t\t\t\t\tonClick={onGoBackToDetails}\n\t\t\t\t>\n\t\t\t\t\t<ArrowLeftIcon /> Back to Details\n\t\t\t\t</Button>\n\t\t\t\t<Button\n\t\t\t\t\tdisabled={isPending || !hasValidPaymentMethod || replacingPaymentMethod}\n\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\tvariant=\"submit\"\n\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\tonClick={onSubmit}\n\t\t\t\t>\n\t\t\t\t\t{clusterId ? 'Edit Cluster' : 'Create New Cluster'} <ArrowRightIcon />\n\t\t\t\t</Button>\n\t\t\t</div>\n\t\t</>\n\t);\n\n\tif (isEnterprise) {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<ul className=\"list-disc ml-6 max-w-lg\">\n\t\t\t\t\t<li>\n\t\t\t\t\t\tReminder: you will be billed at your contracted rate for any additional infrastructure.\n\t\t\t\t\t</li>\n\t\t\t\t\t<li>\n\t\t\t\t\t\tYour account representative can work with you to sort out more precise details, and to help accomplish your\n\t\t\t\t\t\tobjectives with this cluster. <ContactUs overEmail={true} />, we are here to help.\n\t\t\t\t\t</li>\n\t\t\t\t</ul>\n\n\t\t\t\t{footer}\n\t\t\t</>\n\t\t);\n\t}\n\n\tif (allowBypass) {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<ul className=\"list-disc ml-6\">\n\t\t\t\t\t<li>\n\t\t\t\t\t\tStripe is not configured, and will be bypassed during cluster creation.\n\t\t\t\t\t</li>\n\t\t\t\t</ul>\n\n\t\t\t\t{footer}\n\t\t\t</>\n\t\t);\n\t}\n\n\tconst orPossiblyExpires = expirationMonths && `, or ${pluralize(expirationMonths, 'month', 'months')} elapse`;\n\n\treturn (\n\t\t<>\n\t\t\t<ul className=\"list-disc ml-6 mb-6\">\n\t\t\t\t<li>\n\t\t\t\t\tYou will be billed for this cluster today, and will receive a license for the block of usage you've requested.\n\t\t\t\t</li>\n\t\t\t\t{clusterId && (\n\t\t\t\t\t<li>\n\t\t\t\t\t\tIf you scale up, you'll be charged for the additional blocks you've purchased now, and your next auto\n\t\t\t\t\t\trenewal will be for all purchased blocks.\n\t\t\t\t\t</li>\n\t\t\t\t)}\n\t\t\t\t{clusterId && (\n\t\t\t\t\t<li>\n\t\t\t\t\t\tIf you remove a region, that region's usage block will not be used anymore (because it is specific to that\n\t\t\t\t\t\tregion).\n\t\t\t\t\t</li>\n\t\t\t\t)}\n\t\t\t\t<li>When that block is used up{orPossiblyExpires}, you will be automatically renewed.</li>\n\t\t\t\t<li>While refunds are not available, we’d be happy to assist you with troubleshooting.</li>\n\t\t\t\t<li>\n\t\t\t\t\tWe would love to work with you to sort out more precise details, and to help accomplish your objectives with\n\t\t\t\t\tthis cluster. <ContactUs overEmail={true} />, we are here to help.\n\t\t\t\t</li>\n\t\t\t</ul>\n\n\t\t\t<p className=\"text-muted-foreground text-sm mb-6\">Payment method:</p>\n\n\t\t\t<PaymentMethodsDisplay\n\t\t\t\tonSaveStateForBillingRedirect={onSaveStateForBillingRedirect}\n\t\t\t\tonReplacingPaymentMethod={setReplacingPaymentMethod}\n\t\t\t/>\n\n\t\t\t{footer}\n\t\t</>\n\t);\n}\n","// Matches one of:\n// - \"localhost\"\n// - IPv4 address (four 0–255 octets, no leading zeros for multi-digit values)\n// - Domain with subdomains: labels 1–63 chars (alphanumeric and hyphen, not starting/ending with hyphen),\n// with a final TLD of 2+ letters. No ports, no paths, no IPv6.\nexport const hostNameRegex =\n\t/(^$|^(?:localhost|(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}|(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z]{2,})$)/i;\n","export const minPortNumber = 0;\nexport const maxPortNumber = 65535;\n","import { hostNameRegex } from '@/lib/string/regex/hostNameRegex';\nimport { maxPortNumber, minPortNumber } from '@/lib/types/portNumbers';\nimport { z } from 'zod';\n\nexport const specifiedAbbreviatedName = z\n\t.string()\n\t.max(20, 'Must be at most 20 characters long.')\n\t.regex(\n\t\t/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/,\n\t\t'Can only contain lowercase letters, numbers and dashes. Must not start or end with a dash.',\n\t);\n\nexport const UpsertClusterSchema = z.object({\n\tclusterName: z.string()\n\t\t.nonempty('Please enter a cluster name.')\n\t\t.max(255, 'Cluster name cannot be longer than 255 characters long.'),\n\tabbreviatedName: z.union([\n\t\tz.literal(''),\n\t\tz.undefined(),\n\t\tspecifiedAbbreviatedName,\n\t]).optional(),\n\tfqdn: z\n\t\t.string()\n\t\t.regex(hostNameRegex, 'Please enter a valid host name without the port or any path.')\n\t\t.optional(),\n\n\tversion: z.string().optional(),\n\tdeploymentDescription: z.string().nonempty('Please select a deployment tier.'),\n\tperformanceDescription: z.string().nonempty('Please select a performance tier.'),\n\n\tregionPlans: z.array(\n\t\tz.object({\n\t\t\tregionName: z.string().nonempty('Please select a region.'),\n\t\t\tlatencyDescription: z.string().nonempty('Please select a latency tier.'),\n\t\t}),\n\t).max(50, { error: 'A maximum of 50 regions can be selected for each cluster. ' }),\n\n\tinstances: z.array(\n\t\tz.object({\n\t\t\tsecure: z.enum(['true', 'false']),\n\t\t\tfqdn: z.string()\n\t\t\t\t.nonempty('Please enter the host name of your instance.')\n\t\t\t\t.regex(hostNameRegex, 'Please enter a valid host name without the port or any path.'),\n\t\t\tport: z.number()\n\t\t\t\t.min(minPortNumber, 'Positive thinking only, please.')\n\t\t\t\t.max(maxPortNumber, 'That port number is too high.')\n\t\t\t\t.optional(),\n\t\t}),\n\t).max(100, { error: 'A maximum of 100 instances can be added to each cluster.' }),\n\n\tskipToBilling: z.boolean().optional(),\n\tskipGtmWait: z.boolean().optional(),\n\tsourceClusterId: z.string().optional(),\n});\n\nexport type UpsertClusterSchemaType = z.infer<typeof UpsertClusterSchema>;\n","import { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { specifiedAbbreviatedName, UpsertClusterSchema } from '@/features/clusters/upsert/upsertClusterSchema';\nimport { UseFormReturn } from 'react-hook-form';\nimport { z } from 'zod';\n\nexport function ClusterAbbreviatedName({\n\tcalculatedNames,\n\tdisabled,\n\tform,\n}: {\n\tcalculatedNames: { suggestedAbbreviatedName: string; fullHostName: string };\n\tdisabled?: boolean | undefined;\n\tform: UseFormReturn<z.infer<typeof UpsertClusterSchema>>;\n}) {\n\treturn (\n\t\t<>\n\t\t\t<FormField\n\t\t\t\tcontrol={form.control}\n\t\t\t\tname=\"abbreviatedName\"\n\t\t\t\trender={({ field }) => (\n\t\t\t\t\t<FormItem className=\"col-span-3\">\n\t\t\t\t\t\t<FormLabel className=\"pb-1\">Host Name</FormLabel>\n\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\tmaxLength={specifiedAbbreviatedName.maxLength!}\n\t\t\t\t\t\t\t\tautoCapitalize=\"none\"\n\t\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\t\tautoCorrect=\"off\"\n\t\t\t\t\t\t\t\tplaceholder={calculatedNames.suggestedAbbreviatedName}\n\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t</FormItem>\n\t\t\t\t)}\n\t\t\t/>\n\t\t\t<FormItem className=\"col-span-3 \">\n\t\t\t\t<FormLabel className=\"pb-1\">Full Host Name</FormLabel>\n\t\t\t\t<FormControl>\n\t\t\t\t\t<span>{calculatedNames.fullHostName}</span>\n\t\t\t\t</FormControl>\n\t\t\t\t<FormMessage />\n\t\t\t</FormItem>\n\t\t</>\n\t);\n}\n","import { cx } from 'class-variance-authority';\nimport { useMemo } from 'react';\n\nexport function TextLoadingSkeleton({ className }: { className?: string } = {}) {\n\tconst computedClassName = useMemo(() =>\n\t\tcx(\n\t\t\t`animate-pulse h-2.5 bg-gray-200 rounded-full dark:bg-gray-700`,\n\t\t\t!className?.includes('mb-') && 'mb-4 ',\n\t\t\t!className?.includes('w-') && 'w-48 ',\n\t\t\tclassName,\n\t\t), [className]);\n\treturn <div className={computedClassName}></div>;\n}\n","import * as SelectPrimitive from '@radix-ui/react-select';\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from 'lucide-react';\nimport * as React from 'react';\n\nimport { cn } from '@/lib/cn';\n\nfunction Select({ ...props }: React.ComponentProps<typeof SelectPrimitive.Root>) {\n\treturn <SelectPrimitive.Root data-slot=\"select\" {...props} />;\n}\n\nfunction SelectGroup({ ...props }: React.ComponentProps<typeof SelectPrimitive.Group>) {\n\treturn <SelectPrimitive.Group data-slot=\"select-group\" {...props} />;\n}\n\nfunction SelectValue({ ...props }: React.ComponentProps<typeof SelectPrimitive.Value>) {\n\treturn <SelectPrimitive.Value data-slot=\"select-value\" {...props} />;\n}\n\nfunction SelectTrigger({ className, children, ...props }: React.ComponentProps<typeof SelectPrimitive.Trigger>) {\n\treturn (\n\t\t<SelectPrimitive.Trigger\n\t\t\tdata-slot=\"select-trigger\"\n\t\t\tclassName={cn(\n\t\t\t\t\"border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive flex h-9 w-fit items-center justify-between gap-2 rounded-md border bg-white text-foreground dark:bg-grey-700 dark:text-white px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 *:data-[slot=select-value]:truncate *:data-[slot=select-value]:block *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t\t<SelectPrimitive.Icon asChild>\n\t\t\t\t<ChevronDownIcon className=\"opacity-50 size-4\" />\n\t\t\t</SelectPrimitive.Icon>\n\t\t</SelectPrimitive.Trigger>\n\t);\n}\n\nfunction SelectContent({\n\tclassName,\n\tchildren,\n\tposition = 'popper',\n\t...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n\treturn (\n\t\t<SelectPrimitive.Portal>\n\t\t\t<SelectPrimitive.Content\n\t\t\t\tdata-slot=\"select-content\"\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border shadow-md',\n\t\t\t\t\tposition === 'popper'\n\t\t\t\t\t\t&& 'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tposition={position}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<SelectScrollUpButton />\n\t\t\t\t<SelectPrimitive.Viewport\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t'p-1',\n\t\t\t\t\t\tposition === 'popper'\n\t\t\t\t\t\t\t&& 'h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1',\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t{children}\n\t\t\t\t</SelectPrimitive.Viewport>\n\t\t\t\t<SelectScrollDownButton />\n\t\t\t</SelectPrimitive.Content>\n\t\t</SelectPrimitive.Portal>\n\t);\n}\n\nfunction SelectLabel({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Label>) {\n\treturn (\n\t\t<SelectPrimitive.Label\n\t\t\tdata-slot=\"select-label\"\n\t\t\tclassName={cn('px-2 py-1.5 text-sm font-medium', className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nfunction SelectItem({ className, children, ...props }: React.ComponentProps<typeof SelectPrimitive.Item>) {\n\treturn (\n\t\t<SelectPrimitive.Item\n\t\t\tdata-slot=\"select-item\"\n\t\t\tclassName={cn(\n\t\t\t\t\"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n\t\t\t<span className=\"absolute right-2 flex size-3.5 items-center justify-center\">\n\t\t\t\t<SelectPrimitive.ItemIndicator>\n\t\t\t\t\t<CheckIcon className=\"size-4\" />\n\t\t\t\t</SelectPrimitive.ItemIndicator>\n\t\t\t</span>\n\t\t</SelectPrimitive.Item>\n\t);\n}\n\nfunction SelectSeparator({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n\treturn (\n\t\t<SelectPrimitive.Separator\n\t\t\tdata-slot=\"select-separator\"\n\t\t\tclassName={cn('bg-border pointer-events-none -mx-1 my-1 h-px', className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nfunction SelectScrollUpButton({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n\treturn (\n\t\t<SelectPrimitive.ScrollUpButton\n\t\t\tdata-slot=\"select-scroll-up-button\"\n\t\t\tclassName={cn('flex cursor-default items-center justify-center py-1', className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<ChevronUpIcon className=\"size-4\" />\n\t\t</SelectPrimitive.ScrollUpButton>\n\t);\n}\n\nfunction SelectScrollDownButton({\n\tclassName,\n\t...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n\treturn (\n\t\t<SelectPrimitive.ScrollDownButton\n\t\t\tdata-slot=\"select-scroll-down-button\"\n\t\t\tclassName={cn('flex cursor-default items-center justify-center py-1', className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<ChevronDownIcon className=\"size-4\" />\n\t\t</SelectPrimitive.ScrollDownButton>\n\t);\n}\n\nexport {\n\tSelect,\n\tSelectContent,\n\tSelectGroup,\n\tSelectItem,\n\tSelectLabel,\n\tSelectScrollDownButton,\n\tSelectScrollUpButton,\n\tSelectSeparator,\n\tSelectTrigger,\n\tSelectValue,\n};\n","import { TextLoadingSkeleton } from '@/components/TextLoadingSkeleton';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';\nimport { UpsertClusterSchema } from '@/features/clusters/upsert/upsertClusterSchema';\nimport { Suspense } from 'react';\nimport { UseFormReturn } from 'react-hook-form';\nimport { z } from 'zod';\n\nconst DEPLOYMENT_FULL_DESCRIPTION: { [key: string]: string } = {\n\t'Colocated': 'Shared infrastructure for optimized value',\n\t'Dedicated': 'Dedicated infrastructure for consistent performance',\n\t'Self-Hosted': 'Your own infrastructure',\n};\n\nexport function ClusterDeploymentDescription({\n\tavailableDeploymentTypes,\n\tdisabled,\n\tform,\n}: {\n\tavailableDeploymentTypes: string[];\n\tdisabled?: boolean | undefined;\n\tform: UseFormReturn<z.infer<typeof UpsertClusterSchema>>;\n}) {\n\treturn (\n\t\t<FormField\n\t\t\tcontrol={form.control}\n\t\t\tname=\"deploymentDescription\"\n\t\t\trender={({ field }) => (\n\t\t\t\t<FormItem className=\"col-span-3\">\n\t\t\t\t\t<FormLabel className=\"pb-1\">Harper Deployment</FormLabel>\n\n\t\t\t\t\t<Suspense fallback={<TextLoadingSkeleton />}>\n\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t<Select\n\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\tonValueChange={(deploymentDescription) => {\n\t\t\t\t\t\t\t\t\tfield.onChange(deploymentDescription);\n\t\t\t\t\t\t\t\t\tvoid form.trigger();\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<SelectTrigger className=\"w-full h-auto\">\n\t\t\t\t\t\t\t\t\t<SelectValue placeholder=\"Choose Tier\" />\n\t\t\t\t\t\t\t\t</SelectTrigger>\n\t\t\t\t\t\t\t\t<SelectContent>\n\t\t\t\t\t\t\t\t\t<SelectGroup>\n\t\t\t\t\t\t\t\t\t\t{availableDeploymentTypes.map((deploymentDescription) => (\n\t\t\t\t\t\t\t\t\t\t\t<SelectItem\n\t\t\t\t\t\t\t\t\t\t\t\tkey={deploymentDescription}\n\t\t\t\t\t\t\t\t\t\t\t\tvalue={deploymentDescription}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t<dt className=\"text-left font-bold text-sm/6\">{deploymentDescription}</dt>\n\t\t\t\t\t\t\t\t\t\t\t\t{DEPLOYMENT_FULL_DESCRIPTION[deploymentDescription] && (\n\t\t\t\t\t\t\t\t\t\t\t\t\t<dd className=\"font-light\">{DEPLOYMENT_FULL_DESCRIPTION[deploymentDescription]}</dd>\n\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t</SelectItem>\n\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t</SelectGroup>\n\t\t\t\t\t\t\t\t</SelectContent>\n\t\t\t\t\t\t\t</Select>\n\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t</Suspense>\n\n\t\t\t\t\t<FormMessage />\n\t\t\t\t</FormItem>\n\t\t\t)}\n\t\t/>\n\t);\n}\n","import { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { UpsertClusterSchema } from '@/features/clusters/upsert/upsertClusterSchema';\nimport { UseFormReturn } from 'react-hook-form';\nimport { z } from 'zod';\n\nexport function ClusterFQDN({\n\tdisabled,\n\tform,\n}: {\n\tdisabled?: boolean | undefined;\n\tform: UseFormReturn<z.infer<typeof UpsertClusterSchema>>;\n}) {\n\treturn (\n\t\t<FormField\n\t\t\tcontrol={form.control}\n\t\t\tname=\"fqdn\"\n\t\t\trender={({ field }) => (\n\t\t\t\t<FormItem className=\"md:col-span-6 col-span-3\">\n\t\t\t\t\t<FormLabel className=\"pb-1\">Optional Cluster Load Balancer Host Name</FormLabel>\n\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\tautoCapitalize=\"none\"\n\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\tautoCorrect=\"off\"\n\t\t\t\t\t\t\tplaceholder=\"example.your-company.com\"\n\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</FormControl>\n\t\t\t\t\t<FormMessage />\n\t\t\t\t</FormItem>\n\t\t\t)}\n\t\t/>\n\t);\n}\n","import { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { UpsertClusterSchema } from '@/features/clusters/upsert/upsertClusterSchema';\nimport { UseFormReturn } from 'react-hook-form';\nimport { z } from 'zod';\n\nexport function ClusterName({\n\tclassName,\n\tdisabled,\n\tform,\n}: {\n\tclassName: string;\n\tdisabled?: boolean | undefined;\n\tform: UseFormReturn<z.infer<typeof UpsertClusterSchema>>;\n}) {\n\treturn (\n\t\t<FormField\n\t\t\tcontrol={form.control}\n\t\t\tname=\"clusterName\"\n\t\t\trender={({ field }) => (\n\t\t\t\t<FormItem className={className}>\n\t\t\t\t\t<FormLabel className=\"pb-1\">Cluster Name</FormLabel>\n\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\tautoFocus={true}\n\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\tmaxLength={UpsertClusterSchema.shape.clusterName.maxLength!}\n\t\t\t\t\t\t\tautoCapitalize=\"words\"\n\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</FormControl>\n\t\t\t\t\t<FormMessage />\n\t\t\t\t</FormItem>\n\t\t\t)}\n\t\t/>\n\t);\n}\n","import { TextLoadingSkeleton } from '@/components/TextLoadingSkeleton';\nimport { Badge } from '@/components/ui/badge';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';\nimport { UpsertClusterSchema } from '@/features/clusters/upsert/upsertClusterSchema';\nimport { Suspense } from 'react';\nimport { UseFormReturn } from 'react-hook-form';\nimport { z } from 'zod';\n\nexport function ClusterPerformanceDescription({\n\tavailablePerformanceDescriptions,\n\tform,\n\tselectedDeployment,\n}: {\n\tavailablePerformanceDescriptions: {\n\t\tname: string;\n\t\tperformanceTier: string;\n\t\tdescription?: string;\n\t\tisPremium?: boolean;\n\t}[];\n\tform: UseFormReturn<z.infer<typeof UpsertClusterSchema>>;\n\tselectedDeployment: string;\n}) {\n\treturn (\n\t\t<FormField\n\t\t\tcontrol={form.control}\n\t\t\tname=\"performanceDescription\"\n\t\t\trender={({ field }) => (\n\t\t\t\t<FormItem className=\"col-span-3\">\n\t\t\t\t\t<FormLabel className=\"pb-1\">\n\t\t\t\t\t\t{selectedDeployment.startsWith('Self') ? 'Support' : 'Performance'} &amp; Usage\n\t\t\t\t\t</FormLabel>\n\n\t\t\t\t\t<Suspense fallback={<TextLoadingSkeleton />}>\n\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t<Select\n\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\tonValueChange={(performanceDescription) => {\n\t\t\t\t\t\t\t\t\tfield.onChange(performanceDescription);\n\t\t\t\t\t\t\t\t\tvoid form.trigger();\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\tdisabled={!availablePerformanceDescriptions?.length}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<SelectTrigger className=\"w-full h-auto\">\n\t\t\t\t\t\t\t\t\t<SelectValue placeholder=\"Choose Tier\" />\n\t\t\t\t\t\t\t\t</SelectTrigger>\n\t\t\t\t\t\t\t\t<SelectContent>\n\t\t\t\t\t\t\t\t\t<SelectGroup>\n\t\t\t\t\t\t\t\t\t\t{availablePerformanceDescriptions.map((performanceDescription) => (\n\t\t\t\t\t\t\t\t\t\t\t<SelectItem\n\t\t\t\t\t\t\t\t\t\t\t\tkey={performanceDescription.name}\n\t\t\t\t\t\t\t\t\t\t\t\tvalue={performanceDescription.performanceTier}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t<dt className=\"text-left font-bold text-sm/6 flex items-center gap-2\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t{performanceDescription.name}\n\t\t\t\t\t\t\t\t\t\t\t\t\t{performanceDescription.isPremium && <Badge>Premium</Badge>}\n\t\t\t\t\t\t\t\t\t\t\t\t</dt>\n\t\t\t\t\t\t\t\t\t\t\t\t{performanceDescription.description && (\n\t\t\t\t\t\t\t\t\t\t\t\t\t<dd className=\"text-left font-light\">{performanceDescription.description}</dd>\n\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t</SelectItem>\n\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t</SelectGroup>\n\t\t\t\t\t\t\t\t</SelectContent>\n\t\t\t\t\t\t\t</Select>\n\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t</Suspense>\n\n\t\t\t\t\t<FormMessage />\n\t\t\t\t</FormItem>\n\t\t\t)}\n\t\t/>\n\t);\n}\n","import { useFormField } from '@/components/ui/form/useFormField';\nimport { cn } from '@/lib/cn';\nimport { ComponentProps } from 'react';\n\nexport function FormDescription({ className, ...props }: ComponentProps<'p'>) {\n\tconst { formDescriptionId } = useFormField();\n\n\treturn (\n\t\t<p\n\t\t\tdata-slot=\"form-description\"\n\t\t\tid={formDescriptionId}\n\t\t\tclassName={cn('text-muted-foreground text-sm', className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n","import { FormControl } from '@/components/ui/form/FormControl';\nimport { FormDescription } from '@/components/ui/form/FormDescription';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { Input } from '@/components/ui/input';\nimport { UpsertClusterSchema } from '@/features/clusters/upsert/upsertClusterSchema';\nimport { UseFormReturn } from 'react-hook-form';\nimport { z } from 'zod';\n\nexport function ClusterSkipGtmWait({\n\tclassName,\n\tform,\n}: {\n\tclassName?: string;\n\tform: UseFormReturn<z.infer<typeof UpsertClusterSchema>>;\n}) {\n\treturn (\n\t\t<FormField\n\t\t\tcontrol={form.control}\n\t\t\tname=\"skipGtmWait\"\n\t\t\trender={({ field }) => (\n\t\t\t\t<FormItem className={className}>\n\t\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\tclassName=\"w-4 h-4 cursor-pointer\"\n\t\t\t\t\t\t\t\tchecked={field.value || false}\n\t\t\t\t\t\t\t\tonChange={field.onChange}\n\t\t\t\t\t\t\t\tonBlur={field.onBlur}\n\t\t\t\t\t\t\t\tname={field.name}\n\t\t\t\t\t\t\t\tref={field.ref}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t<FormLabel className=\"cursor-pointer\">Immediate upgrade and restart</FormLabel>\n\t\t\t\t\t</div>\n\t\t\t\t\t<FormDescription>\n\t\t\t\t\t\tApply changes immediately without waiting for each instance to be taken out of the load balancer (faster,\n\t\t\t\t\t\tbut potentially less safe).\n\t\t\t\t\t</FormDescription>\n\t\t\t\t</FormItem>\n\t\t\t)}\n\t\t/>\n\t);\n}\n","import { TextLoadingSkeleton } from '@/components/TextLoadingSkeleton';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';\nimport { HarperVersionsResponse } from '@/features/clusters/queries/getHarperVersionsQuery';\nimport { UpsertClusterSchema } from '@/features/clusters/upsert/upsertClusterSchema';\nimport { Suspense } from 'react';\nimport { UseFormReturn } from 'react-hook-form';\nimport { z } from 'zod';\n\nexport function ClusterVersion({\n\tclassName,\n\tdisabled,\n\tform,\n\tharperVersions,\n}: {\n\tclassName: string;\n\tdisabled?: boolean | undefined;\n\tform: UseFormReturn<z.infer<typeof UpsertClusterSchema>>;\n\tharperVersions: HarperVersionsResponse | undefined;\n}) {\n\tif (!harperVersions?.value?.length) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<FormField\n\t\t\tcontrol={form.control}\n\t\t\tname=\"version\"\n\t\t\trender={({ field }) => (\n\t\t\t\t<FormItem className={className}>\n\t\t\t\t\t<FormLabel className=\"pb-1\">Harper Version</FormLabel>\n\n\t\t\t\t\t<Suspense fallback={<TextLoadingSkeleton />}>\n\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t<Select\n\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\tonValueChange={(version) => {\n\t\t\t\t\t\t\t\t\tfield.onChange(version);\n\t\t\t\t\t\t\t\t\tvoid form.trigger();\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<SelectTrigger className=\"w-full h-auto\">\n\t\t\t\t\t\t\t\t\t<SelectValue placeholder=\"Choose Version\" />\n\t\t\t\t\t\t\t\t</SelectTrigger>\n\t\t\t\t\t\t\t\t<SelectContent>\n\t\t\t\t\t\t\t\t\t<SelectGroup>\n\t\t\t\t\t\t\t\t\t\t{harperVersions?.value.map((harperVersion) => (\n\t\t\t\t\t\t\t\t\t\t\t<SelectItem\n\t\t\t\t\t\t\t\t\t\t\t\tkey={harperVersion.version}\n\t\t\t\t\t\t\t\t\t\t\t\tvalue={harperVersion.version}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{harperVersion.version} <span className=\"font-light opacity-50\">{harperVersion.name}</span>\n\t\t\t\t\t\t\t\t\t\t\t</SelectItem>\n\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t</SelectGroup>\n\t\t\t\t\t\t\t\t</SelectContent>\n\t\t\t\t\t\t\t</Select>\n\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t</Suspense>\n\n\t\t\t\t\t<FormMessage />\n\t\t\t\t</FormItem>\n\t\t\t)}\n\t\t/>\n\t);\n}\n","const numberPrefix = new RegExp(/^\\d+/);\n\nexport function sortByNumberPrefix(a: string, b: string): number {\n\tconst aPrefix = parseInt(a.match(numberPrefix)?.[0] || '0', 10);\n\tconst bPrefix = parseInt(b.match(numberPrefix)?.[0] || '0', 10);\n\tif (aPrefix === bPrefix) {\n\t\treturn 0;\n\t}\n\treturn aPrefix > bPrefix ? 1 : -1;\n}\n","export type Units = 'bytes' | 'secs';\n\nconst dataUnits = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\nconst timeUnits = ['secs', 'mins', 'hrs'];\nconst unitsMultipliers = {\n\tbytes: 1000,\n\tsecs: 60,\n};\n\nexport function scaleValueToUnits(value: number, baseUnits: string, units: string) {\n\tlet availableUnits;\n\tlet scaleBase;\n\tswitch (baseUnits) {\n\t\tcase 'bytes': {\n\t\t\tavailableUnits = dataUnits;\n\t\t\tscaleBase = unitsMultipliers.bytes;\n\t\t\tbreak;\n\t\t}\n\t\tcase 'secs': {\n\t\t\tavailableUnits = timeUnits;\n\t\t\tscaleBase = unitsMultipliers.secs;\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\treturn value;\n\t}\n\tconst scaleExponent = availableUnits.indexOf(units);\n\tif (scaleExponent === -1) {\n\t\treturn value;\n\t}\n\tconst scaleFactor = scaleBase ** scaleExponent;\n\treturn value / scaleFactor;\n}\n\nexport function determineUnits(baseUnits: string, value: number) {\n\tlet availableUnits;\n\tlet unitsMultiplier;\n\tswitch (baseUnits) {\n\t\tcase 'bytes':\n\t\t\tavailableUnits = dataUnits;\n\t\t\tunitsMultiplier = unitsMultipliers.bytes;\n\t\t\tbreak;\n\t\tcase 'secs':\n\t\t\tavailableUnits = timeUnits;\n\t\t\tunitsMultiplier = unitsMultipliers.secs;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn baseUnits;\n\t}\n\tlet i = 0;\n\twhile (value >= unitsMultiplier && i < availableUnits.length - 1) {\n\t\tvalue /= unitsMultiplier;\n\t\ti++;\n\t}\n\treturn availableUnits[i];\n}\n","import { determineUnits, scaleValueToUnits } from '@/lib/units.ts';\n\nexport function humanFileSize(input: number, multiplierFromBytes: number = 1) {\n\tconst initialValue = input * multiplierFromBytes;\n\tconst units = determineUnits('bytes', initialValue);\n\tconst scaled = scaleValueToUnits(initialValue, 'bytes', units);\n\n\tconst value = new Intl.NumberFormat().format(Math.round(scaled));\n\treturn `${value} ${units}`;\n}\n","export function addCommasToNumbers(input: number): string {\n\treturn new Intl.NumberFormat().format(input);\n}\n","import { addCommasToNumbers } from '@/lib/addCommasToNumbers';\n\nconst units = ['K', 'M', 'B', 'T', 'Qa', 'Qi', 'Sx', 'Sp', 'Oc', 'No', 'Dc'];\n\nexport function humanNumber(input: number): string {\n\tconst thresh = 1000;\n\tlet value = input;\n\n\tif (Math.abs(value) < thresh) {\n\t\treturn String(Math.round(value));\n\t}\n\n\tlet u = -1;\n\tconst r = 10;\n\n\tdo {\n\t\tvalue /= thresh;\n\t\t++u;\n\t} while (Math.round(Math.abs(value) * r) / r >= thresh && u < units.length - 1);\n\n\treturn `${addCommasToNumbers(Math.round(value))} ${units[u]}`;\n}\n","import { SchemaPlan, SchemaRegion } from '@/integrations/api/api.gen';\n\nexport type UsageRange = {\n\tmin: number;\n\tmax: number;\n};\n\nexport type UsageScale = {\n\treadRate: UsageRange;\n\ttotalReads: UsageRange;\n\twriteRate: UsageRange;\n\ttotalWrites: UsageRange;\n};\n\n/**\n * Determines the floor and ceiling for the usage gauges by looking across every performance tier and\n * distribution (region) available. Read values scale with a region's purchasedBlockMultiplier (so the\n * floor uses the smallest multiplier and the ceiling the largest); write values do not scale.\n * Gauges fill on a logarithmic scale between min and max so that lower tiers (e.g. free → medium) still\n * show a meaningful jump rather than being dwarfed by the largest tiers.\n */\nexport function calculateUsageScale(\n\tdeploymentPlans: SchemaPlan[],\n\tregionNameToLatencyToRegion: Record<string, Record<string, SchemaRegion>>,\n): UsageScale {\n\tconst multipliers = Object.values(regionNameToLatencyToRegion)\n\t\t.flatMap(latencyToRegion => Object.values(latencyToRegion))\n\t\t.map(region => region.purchasedBlockMultiplier ?? 1);\n\tconst maxMultiplier = Math.max(...multipliers, 1);\n\tconst minMultiplier = Math.min(...multipliers, maxMultiplier);\n\n\tconst range = (pick: (plan: SchemaPlan) => number | undefined): UsageRange => {\n\t\tconst values = deploymentPlans\n\t\t\t.map(pick)\n\t\t\t.filter((value): value is number => typeof value === 'number' && value > 0);\n\t\tif (!values.length) {\n\t\t\treturn { min: 0, max: 0 };\n\t\t}\n\t\treturn { min: Math.min(...values), max: Math.max(...values) };\n\t};\n\n\tconst readRate = range(plan => plan.planLimits?.readsPerMinuteCount);\n\tconst totalReads = range(plan => plan.planLimits?.totalReadCount);\n\n\treturn {\n\t\treadRate: { min: readRate.min * minMultiplier, max: readRate.max * maxMultiplier },\n\t\ttotalReads: { min: totalReads.min * minMultiplier, max: totalReads.max * maxMultiplier },\n\t\twriteRate: range(plan => plan.planLimits?.writesPerMinuteCount),\n\t\ttotalWrites: range(plan => plan.planLimits?.totalWriteCount),\n\t};\n}\n\n/**\n * Maps a value onto a 0–1 logarithmic fill between the range's floor and ceiling. The log scale keeps\n * the steps between smaller tiers visible instead of compressing everything beneath the largest tier.\n */\nexport function logarithmicFill(value: number, { min, max }: UsageRange): number {\n\tif (value <= 0) {\n\t\treturn 0;\n\t}\n\tconst floor = Math.max(Math.min(min, value), 1);\n\tconst ceiling = Math.max(max, value);\n\tif (ceiling <= floor) {\n\t\treturn 1;\n\t}\n\tconst fill = (Math.log(value) - Math.log(floor)) / (Math.log(ceiling) - Math.log(floor));\n\treturn Math.min(Math.max(fill, 0), 1);\n}\n","import { Button } from '@/components/ui/button';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { SchemaCloudInstanceTypes, SchemaPlan, SchemaRegion } from '@/integrations/api/api.gen';\nimport { excludeFalsy } from '@/lib/arrays/excludeFalsy';\nimport { cn } from '@/lib/cn';\nimport { humanFileSize } from '@/lib/humanFileSize';\nimport { humanNumber } from '@/lib/humanNumber';\nimport { pluralize } from '@/lib/pluralize';\nimport { isPositive } from '@/lib/types/isPositive';\nimport {\n\tArrowDownIcon,\n\tArrowDownToLineIcon,\n\tArrowRightIcon,\n\tArrowUpFromLineIcon,\n\tCalendarClockIcon,\n\tGaugeIcon,\n\ttype LucideIcon,\n} from 'lucide-react';\nimport { useCallback, useMemo, useState } from 'react';\nimport { logarithmicFill, UsageScale } from '../lib/calculateUsageScale';\n\nexport function ResourcesPerInstance({ selectedPlan, selectedRegion, usageScale, isEnterprise, cloudProvider }: {\n\treadonly selectedPlan: SchemaPlan | undefined;\n\treadonly selectedRegion: SchemaRegion | undefined;\n\treadonly usageScale: UsageScale;\n\treadonly isEnterprise: boolean;\n\treadonly cloudProvider: keyof SchemaCloudInstanceTypes | undefined;\n}) {\n\tconst [toggled, setToggled] = useState(false);\n\tconst onUsageLimitsClick = useCallback(() => {\n\t\tsetToggled(!toggled);\n\t}, [toggled, setToggled]);\n\tconst planLimits = selectedPlan?.planLimits;\n\tconst resourcesPerInstance = selectedPlan?.resourcesPerInstance;\n\tconst cloudInstanceType = cloudProvider && selectedPlan?.cloudInstanceTypes?.[cloudProvider];\n\n\tconst expirationMonths = isPositive(planLimits?.expirationMonths) && planLimits.expirationMonths < 1000\n\t\t&& planLimits.expirationMonths;\n\tconst multiplier = selectedRegion?.purchasedBlockMultiplier ?? 1;\n\tconst rows = useMemo<{ label: string; value: string }[]>(() => {\n\t\tif (!planLimits) {\n\t\t\treturn [];\n\t\t}\n\t\treturn ([\n\t\t\tisPositive(planLimits.totalReadCount) && {\n\t\t\t\tlabel: 'Total Reads',\n\t\t\t\tvalue: humanNumber(planLimits.totalReadCount * multiplier),\n\t\t\t},\n\t\t\tisPositive(planLimits.totalReadsBytes) && {\n\t\t\t\tlabel: 'Total Read Transfer',\n\t\t\t\tvalue: `${humanFileSize(planLimits.totalReadsBytes * multiplier)}`,\n\t\t\t},\n\t\t\tisPositive(planLimits.readsPerMinuteCount) && {\n\t\t\t\tlabel: 'Read Rate',\n\t\t\t\tvalue: `${humanNumber(planLimits.readsPerMinuteCount * 60 * multiplier)}/hr`,\n\t\t\t},\n\t\t\tisPositive(planLimits.readsPerMinuteBytes) && {\n\t\t\t\tlabel: 'Read Bandwidth',\n\t\t\t\tvalue: `${humanFileSize(planLimits.readsPerMinuteBytes * 60 * multiplier)}/hr`,\n\t\t\t},\n\t\t\tisPositive(planLimits.totalWriteCount) && {\n\t\t\t\tlabel: 'Total Writes',\n\t\t\t\tvalue: humanNumber(planLimits.totalWriteCount),\n\t\t\t},\n\t\t\tisPositive(planLimits.totalWritesBytes) && {\n\t\t\t\tlabel: 'Total Write Transfer',\n\t\t\t\tvalue: `${humanFileSize(planLimits.totalWritesBytes)}`,\n\t\t\t},\n\t\t\tisPositive(planLimits.writesPerMinuteCount) && {\n\t\t\t\tlabel: 'Write Rate',\n\t\t\t\tvalue: `${humanNumber(planLimits.writesPerMinuteCount * 60)}/hr`,\n\t\t\t},\n\t\t\tisPositive(planLimits.writesPerMinuteBytes) && {\n\t\t\t\tlabel: 'Write Bandwidth',\n\t\t\t\tvalue: `${humanFileSize(planLimits.writesPerMinuteBytes * 60)}/hr`,\n\t\t\t},\n\t\t\tisPositive(planLimits.totalRealTimeMessageDeliveries) && {\n\t\t\t\tlabel: 'Total Real-Time Messages',\n\t\t\t\tvalue: `${humanNumber(planLimits.totalRealTimeMessageDeliveries * multiplier)} messages`,\n\t\t\t},\n\t\t\tisPositive(planLimits.totalRealTimeMessageDeliveryBytes) && {\n\t\t\t\tlabel: 'Total Real-Time Message Transfer',\n\t\t\t\tvalue: `${humanFileSize(planLimits.totalRealTimeMessageDeliveryBytes * multiplier)}`,\n\t\t\t},\n\t\t\tisPositive(planLimits.realTimeMessageDeliveriesPerMinute) && {\n\t\t\t\tlabel: 'Real-Time Message Rate',\n\t\t\t\tvalue: `${humanNumber(planLimits.realTimeMessageDeliveriesPerMinute * 60 * multiplier)}/hr`,\n\t\t\t},\n\t\t\tisPositive(planLimits.realTimeMessageDeliveryBytesPerMinute) && {\n\t\t\t\tlabel: 'Real-Time Message Bandwidth',\n\t\t\t\tvalue: `${humanFileSize(planLimits.realTimeMessageDeliveryBytesPerMinute * 60 * multiplier)}/hr`,\n\t\t\t},\n\t\t\tisPositive(planLimits.tlsHandshakes) && {\n\t\t\t\tlabel: 'TLS Handshakes',\n\t\t\t\tvalue: `${humanNumber(planLimits.tlsHandshakes * 60 * multiplier)}`,\n\t\t\t},\n\t\t\tisPositive(planLimits.applicationComputeHours) && {\n\t\t\t\tlabel: 'Application Compute Hours',\n\t\t\t\tvalue: `${humanNumber(planLimits.applicationComputeHours * multiplier)}`,\n\t\t\t},\n\t\t\t!!resourcesPerInstance && isPositive(resourcesPerInstance.storageGb) && {\n\t\t\t\tlabel: 'Storage',\n\t\t\t\tvalue: `${humanFileSize(resourcesPerInstance.storageGb * 1000_000_000)}`,\n\t\t\t},\n\t\t\t!!resourcesPerInstance && isPositive(resourcesPerInstance.cpuCores) && {\n\t\t\t\tlabel: 'Maximum CPU Cores',\n\t\t\t\tvalue: `${humanNumber(resourcesPerInstance.cpuCores)}`,\n\t\t\t},\n\t\t\t!!resourcesPerInstance && isPositive(resourcesPerInstance.memoryMb) && {\n\t\t\t\tlabel: 'Memory',\n\t\t\t\tvalue: `${resourcesPerInstance.memoryMb / 1024} GB`,\n\t\t\t},\n\t\t\t!!cloudInstanceType && {\n\t\t\t\tlabel: 'Cloud Instance Type',\n\t\t\t\tvalue: cloudInstanceType,\n\t\t\t},\n\t\t\t!!expirationMonths && {\n\t\t\t\tlabel: 'Expiration',\n\t\t\t\tvalue: pluralize(expirationMonths, 'month', 'months'),\n\t\t\t},\n\t\t\t!!selectedRegion?.id && {\n\t\t\t\tlabel: 'Region ID',\n\t\t\t\tvalue: selectedRegion.id,\n\t\t\t},\n\t\t\t!!selectedPlan?.id && {\n\t\t\t\tlabel: 'Plan ID',\n\t\t\t\tvalue: selectedPlan.id,\n\t\t\t},\n\t\t] satisfies Array<boolean | { label: string; value: string }>).filter(excludeFalsy);\n\t}, [expirationMonths, selectedRegion, selectedPlan, multiplier]);\n\n\tif (!planLimits) {\n\t\t// The user hasn't selected a plan yet. so let's not show anything for the ResourcesPerInstance space yet.\n\t\treturn '';\n\t}\n\n\tif (!isPositive(planLimits.totalReadCount)) {\n\t\treturn 'This plan has no usage limits.';\n\t}\n\n\tconst forThePriceAbove = isEnterprise\n\t\t? 'for the contracted rate'\n\t\t: 'for the price listed above';\n\tconst expiresInMonths = expirationMonths ? ` in ${pluralize(expirationMonths, 'month', 'months')} or` : '';\n\n\tconst readRate = isPositive(planLimits.readsPerMinuteCount) ? planLimits.readsPerMinuteCount * multiplier : 0;\n\tconst writeRate = isPositive(planLimits.writesPerMinuteCount) ? planLimits.writesPerMinuteCount : 0;\n\tconst totalReads = planLimits.totalReadCount * multiplier;\n\tconst totalWrites = isPositive(planLimits.totalWriteCount) ? planLimits.totalWriteCount : 0;\n\n\tconst usageStats = ([\n\t\treadRate > 0 && {\n\t\t\ticon: GaugeIcon,\n\t\t\tlabel: 'Read Rate',\n\t\t\tvalue: `${humanNumber(readRate)}/min`,\n\t\t\tfill: logarithmicFill(readRate, usageScale.readRate),\n\t\t},\n\t\ttotalReads > 0 && {\n\t\t\ticon: ArrowUpFromLineIcon,\n\t\t\tlabel: 'Total Reads',\n\t\t\tvalue: humanNumber(totalReads),\n\t\t\tfill: logarithmicFill(totalReads, usageScale.totalReads),\n\t\t},\n\t\twriteRate > 0 && {\n\t\t\ticon: GaugeIcon,\n\t\t\tlabel: 'Write Rate',\n\t\t\tvalue: `${humanNumber(writeRate)}/min`,\n\t\t\tfill: logarithmicFill(writeRate, usageScale.writeRate),\n\t\t},\n\t\ttotalWrites > 0 && {\n\t\t\ticon: ArrowDownToLineIcon,\n\t\t\tlabel: 'Total Writes',\n\t\t\tvalue: humanNumber(totalWrites),\n\t\t\tfill: logarithmicFill(totalWrites, usageScale.totalWrites),\n\t\t},\n\t\t!!expirationMonths && {\n\t\t\ticon: CalendarClockIcon,\n\t\t\tlabel: 'License Term',\n\t\t\tvalue: pluralize(expirationMonths, 'month', 'months'),\n\t\t},\n\t] satisfies Array<boolean | { icon: LucideIcon; label: string; value: string; fill?: number }>).filter(excludeFalsy);\n\n\treturn (\n\t\t<FormItem className=\"basis-full\">\n\t\t\t<div className=\"flex flex-wrap items-center justify-between gap-x-2\">\n\t\t\t\t<FormLabel onClick={onUsageLimitsClick} className=\"cursor-pointer\">\n\t\t\t\t\tUsage block included with this plan\n\t\t\t\t</FormLabel>\n\t\t\t\t<Button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tvariant=\"link\"\n\t\t\t\t\tclassName=\"text-foreground\"\n\t\t\t\t\tonClick={onUsageLimitsClick}\n\t\t\t\t>\n\t\t\t\t\tLearn More {toggled ? <ArrowDownIcon /> : <ArrowRightIcon />}\n\t\t\t\t</Button>\n\t\t\t</div>\n\t\t\t<div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-5\">\n\t\t\t\t{usageStats.map(stat => (\n\t\t\t\t\t<UsageStat\n\t\t\t\t\t\tkey={stat.label}\n\t\t\t\t\t\ticon={stat.icon}\n\t\t\t\t\t\tlabel={stat.label}\n\t\t\t\t\t\tvalue={stat.value}\n\t\t\t\t\t\tfill={stat.fill}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</div>\n\t\t\t<FormControl>\n\t\t\t\t<dl\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t'divide-y divide-border rounded-md overflow-hidden transition-[max-height] duration-200 ease-in',\n\t\t\t\t\t\ttoggled ? 'max-h-fit border border-border' : 'max-h-0',\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t<div className=\"text-sm px-4 py-5 leading-relaxed text-muted-foreground\">\n\t\t\t\t\t\tThis plan licenses Harper for the usage limits below, {forThePriceAbove}. The usage license expires\n\t\t\t\t\t\t{expiresInMonths}{' '}\n\t\t\t\t\t\twhen any usage limit is reached. New usage blocks are automatically purchased/billed as blocks are consumed.\n\t\t\t\t\t</div>\n\t\t\t\t\t{rows.map((row, index) => (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tkey={row.label}\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t'px-4 py-1 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-3',\n\t\t\t\t\t\t\t\tindex % 2 === 0 && 'bg-muted dark:bg-grey-700',\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<dt className=\"text-sm/6 font-medium text-foreground\">{row.label}</dt>\n\t\t\t\t\t\t\t<dd className=\"mt-1 text-sm/6 text-muted-foreground sm:col-span-2 sm:mt-0\">{row.value}</dd>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t))}\n\t\t\t\t</dl>\n\t\t\t</FormControl>\n\t\t\t<FormMessage />\n\t\t</FormItem>\n\t);\n}\n\nfunction UsageStat({ icon: Icon, label, value, fill }: {\n\treadonly icon: LucideIcon;\n\treadonly label: string;\n\treadonly value: string;\n\treadonly fill?: number;\n}) {\n\treturn (\n\t\t<div className=\"flex flex-col gap-2 rounded-md border border-border bg-background/50 p-3\">\n\t\t\t<div className=\"flex items-center gap-1.5 text-muted-foreground\">\n\t\t\t\t<Icon className=\"size-4 shrink-0\" />\n\t\t\t\t<span className=\"text-xs font-medium\">{label}</span>\n\t\t\t</div>\n\t\t\t<span className=\"text-lg font-bold text-foreground tabular-nums\">{value}</span>\n\t\t\t{fill !== undefined && (\n\t\t\t\t<div className=\"h-1.5 w-full overflow-hidden rounded-full bg-sky-500/15\">\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName=\"h-full rounded-full bg-sky-500 transition-[width] duration-300\"\n\t\t\t\t\t\tstyle={{ width: `${Math.max(Math.min(fill, 1) * 100, 4)}%` }}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","import { Badge } from '@/components/ui/badge';\nimport { Button } from '@/components/ui/button';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';\nimport { UpsertClusterSchemaType } from '@/features/clusters/upsert/upsertClusterSchema';\nimport { SchemaCloudInstanceTypes, SchemaPlan, SchemaRegion } from '@/integrations/api/api.gen';\nimport { sortByNumberPrefix } from '@/lib/arrays/sort/byNumberPrefix';\nimport { MapPinIcon, TrashIcon } from 'lucide-react';\nimport { useCallback, useEffect, useMemo } from 'react';\nimport { Control, UseFieldArrayReturn, UseFormReturn } from 'react-hook-form';\nimport { PremiumOnlyRegions } from '../lib/calculatePremiumOnlyRegions';\nimport { UsageScale } from '../lib/calculateUsageScale';\nimport { ResourcesPerInstance } from './ResourcesPerInstance';\n\ntype RegionFormInputsProps = {\n\tcontrol: Control<UpsertClusterSchemaType>;\n\tfieldArray: UseFieldArrayReturn<UpsertClusterSchemaType, 'regionPlans'>;\n\tform: UseFormReturn<UpsertClusterSchemaType>;\n\tindex: number;\n\tregionNameToLatencyToRegion: Record<string, Record<string, SchemaRegion>>;\n\tpremiumOnlyRegions: PremiumOnlyRegions;\n\tusageScale: UsageScale;\n\tselectedPlan: SchemaPlan | undefined;\n\tisEnterprise: boolean;\n\tcloudProvider: keyof SchemaCloudInstanceTypes | undefined;\n};\n\nexport function RegionFormInputs({\n\tcontrol,\n\tfieldArray,\n\tform,\n\tindex,\n\tregionNameToLatencyToRegion,\n\tpremiumOnlyRegions,\n\tusageScale,\n\tselectedPlan,\n\tisEnterprise,\n\tcloudProvider,\n}: RegionFormInputsProps) {\n\tconst availableRegionNames = useMemo(() => Object.keys(regionNameToLatencyToRegion).sort(), [\n\t\tregionNameToLatencyToRegion,\n\t]);\n\tconst isDedicated = form.watch('deploymentDescription')?.startsWith('Dedicated');\n\tconst selectedRegionName = form.watch(`regionPlans.${index}.regionName`);\n\tconst selectedLatencyDescription = form.watch(`regionPlans.${index}.latencyDescription`);\n\tconst availableLatencyDescriptions = useMemo(\n\t\t() => Object.keys(regionNameToLatencyToRegion[selectedRegionName] || {}).sort(sortByNumberPrefix).reverse(),\n\t\t[regionNameToLatencyToRegion, selectedRegionName],\n\t);\n\n\tconst allowedRegionIds = selectedPlan?.allowedRegionIds;\n\tconst isRegionAllowedByPlan = useCallback(\n\t\t(regionName: string) =>\n\t\t\t!allowedRegionIds?.length\n\t\t\t|| Object.values(regionNameToLatencyToRegion[regionName] || {}).some(region =>\n\t\t\t\tallowedRegionIds.includes(region.id)\n\t\t\t),\n\t\t[allowedRegionIds, regionNameToLatencyToRegion],\n\t);\n\tconst isLatencyAllowedByPlan = useCallback(\n\t\t(latencyDescription: string) => {\n\t\t\tif (!allowedRegionIds?.length) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tconst id = regionNameToLatencyToRegion[selectedRegionName]?.[latencyDescription]?.id;\n\t\t\treturn !id || allowedRegionIds.includes(id);\n\t\t},\n\t\t[allowedRegionIds, regionNameToLatencyToRegion, selectedRegionName],\n\t);\n\n\tuseEffect(function autoPickLatencyDescription() {\n\t\tif (\n\t\t\tselectedRegionName && availableLatencyDescriptions?.length\n\t\t\t&& !availableLatencyDescriptions?.includes(selectedLatencyDescription)\n\t\t) {\n\t\t\tconst oldValue = selectedLatencyDescription?.split(' ')[0].toLowerCase();\n\t\t\tconst newValue = availableLatencyDescriptions.find(description =>\n\t\t\t\t!oldValue ? true : description.split(' ')[0].toLowerCase() === oldValue\n\t\t\t) || availableLatencyDescriptions[0];\n\t\t\tform.setValue(`regionPlans.${index}.latencyDescription`, newValue);\n\t\t\tvoid form.trigger();\n\t\t}\n\t}, [availableLatencyDescriptions, form, index, selectedLatencyDescription, selectedRegionName]);\n\n\tconst onRemoveClicked = useCallback(() => {\n\t\tfieldArray?.remove(index);\n\t\tvoid form.trigger();\n\t}, [fieldArray, form, index]);\n\n\treturn (\n\t\t<div className=\"md:col-span-6 col-span-3 py-2 pl-4 border-l-4 border-border gap-6 flex flex-wrap items-start\">\n\t\t\t<FormField\n\t\t\t\tcontrol={control}\n\t\t\t\tname={`regionPlans.${index}.regionName`}\n\t\t\t\trender={({ field: regionField }) => (\n\t\t\t\t\t<FormItem className=\"flex-1\">\n\t\t\t\t\t\t<FormLabel className=\"flex items-center gap-1.5\">\n\t\t\t\t\t\t\t<MapPinIcon className=\"size-4 shrink-0\" />\n\t\t\t\t\t\t\tRegion {fieldArray.fields.length > 1 ? index + 1 : ''}\n\t\t\t\t\t\t</FormLabel>\n\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t<Select\n\t\t\t\t\t\t\t\tonValueChange={value => {\n\t\t\t\t\t\t\t\t\tregionField.onChange(value);\n\t\t\t\t\t\t\t\t\tform.trigger();\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t{...regionField}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<SelectTrigger className=\"w-full\">\n\t\t\t\t\t\t\t\t\t<SelectValue placeholder=\"Choose Region\" />\n\t\t\t\t\t\t\t\t</SelectTrigger>\n\t\t\t\t\t\t\t\t<SelectContent>\n\t\t\t\t\t\t\t\t\t<SelectGroup>\n\t\t\t\t\t\t\t\t\t\t{availableRegionNames.map((regionName) => (\n\t\t\t\t\t\t\t\t\t\t\t<SelectItem key={regionName} value={regionName} disabled={!isRegionAllowedByPlan(regionName)}>\n\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t{regionName}\n\t\t\t\t\t\t\t\t\t\t\t\t\t{premiumOnlyRegions.regionNames.has(regionName) && <Badge>Premium</Badge>}\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t</SelectItem>\n\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t</SelectGroup>\n\t\t\t\t\t\t\t\t</SelectContent>\n\t\t\t\t\t\t\t</Select>\n\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t</FormItem>\n\t\t\t\t)}\n\t\t\t/>\n\n\t\t\t<FormField\n\t\t\t\tcontrol={control}\n\t\t\t\tname={`regionPlans.${index}.latencyDescription`}\n\t\t\t\trender={({ field: regionField }) => (\n\t\t\t\t\t<FormItem className=\"flex-1\">\n\t\t\t\t\t\t<FormLabel>Estimated {isDedicated ? 'P95' : 'P90'} Latency, Distribution</FormLabel>\n\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t<Select\n\t\t\t\t\t\t\t\tonValueChange={value => {\n\t\t\t\t\t\t\t\t\tregionField.onChange(value);\n\t\t\t\t\t\t\t\t\tform.trigger();\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t{...regionField}\n\t\t\t\t\t\t\t\tdisabled={!availableLatencyDescriptions?.length}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<SelectTrigger className=\"w-full\">\n\t\t\t\t\t\t\t\t\t<SelectValue placeholder=\"Choose Latency Tier\" />\n\t\t\t\t\t\t\t\t</SelectTrigger>\n\t\t\t\t\t\t\t\t<SelectContent>\n\t\t\t\t\t\t\t\t\t<SelectGroup>\n\t\t\t\t\t\t\t\t\t\t{availableLatencyDescriptions.map((latencyDescription) => (\n\t\t\t\t\t\t\t\t\t\t\t<SelectItem\n\t\t\t\t\t\t\t\t\t\t\t\tkey={latencyDescription}\n\t\t\t\t\t\t\t\t\t\t\t\tvalue={latencyDescription}\n\t\t\t\t\t\t\t\t\t\t\t\tdisabled={!isLatencyAllowedByPlan(latencyDescription)}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t{latencyDescription}\n\t\t\t\t\t\t\t\t\t\t\t\t\t{(() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst id = regionNameToLatencyToRegion[selectedRegionName]?.[latencyDescription]?.id;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\treturn id && premiumOnlyRegions.regionIds.has(id) && <Badge>Premium</Badge>;\n\t\t\t\t\t\t\t\t\t\t\t\t\t})()}\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t</SelectItem>\n\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t</SelectGroup>\n\t\t\t\t\t\t\t\t</SelectContent>\n\t\t\t\t\t\t\t</Select>\n\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t</FormItem>\n\t\t\t\t)}\n\t\t\t/>\n\n\t\t\t{fieldArray?.fields?.length && fieldArray?.fields?.length > 1 && (\n\t\t\t\t<div className=\"flex-none mt-6\">\n\t\t\t\t\t<Button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tvariant=\"destructiveOutline\"\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tonClick={onRemoveClicked}\n\t\t\t\t\t>\n\t\t\t\t\t\t<TrashIcon /> <span className=\"sr-only\">Remove</span>\n\t\t\t\t\t</Button>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t<ResourcesPerInstance\n\t\t\t\tselectedPlan={selectedPlan}\n\t\t\t\tselectedRegion={regionNameToLatencyToRegion[selectedRegionName]?.[selectedLatencyDescription]}\n\t\t\t\tusageScale={usageScale}\n\t\t\t\tisEnterprise={isEnterprise}\n\t\t\t\tcloudProvider={cloudProvider}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n","import { ContactUs } from '@/components/ContactUs';\nimport { ErrorComponent } from '@/components/ErrorComponent';\nimport { Button } from '@/components/ui/button';\nimport { SchemaCloudInstanceTypes, SchemaPlan, SchemaRegion } from '@/integrations/api/api.gen';\nimport { PlusIcon } from 'lucide-react';\nimport { useCallback, useMemo } from 'react';\nimport { useFieldArray, UseFormReturn } from 'react-hook-form';\nimport { RegionFormInputs } from './components/RegionFormInputs';\nimport { PremiumOnlyRegions } from './lib/calculatePremiumOnlyRegions';\nimport { UsageScale } from './lib/calculateUsageScale';\nimport { UpsertClusterSchemaType } from './upsertClusterSchema';\n\ninterface ClusterRegionsProps {\n\tform: UseFormReturn<UpsertClusterSchemaType>;\n\tregionLocations: SchemaRegion[] | undefined;\n\tregionNameToLatencyToRegion: Record<string, Record<string, SchemaRegion>>;\n\tpremiumOnlyRegions: PremiumOnlyRegions;\n\tusageScale: UsageScale;\n\tselectedPlan: SchemaPlan | undefined;\n\ttotalPrice: number | undefined;\n\tisEnterprise: boolean;\n\tcloudProvider: keyof SchemaCloudInstanceTypes | undefined;\n}\n\nexport function ClusterRegions({\n\tform,\n\tregionLocations,\n\tregionNameToLatencyToRegion,\n\tpremiumOnlyRegions,\n\tusageScale,\n\tselectedPlan,\n\ttotalPrice,\n\tisEnterprise,\n\tcloudProvider,\n}: ClusterRegionsProps) {\n\tconst selectedRegionPlans = form.watch('regionPlans');\n\n\tconst regionPlansFieldArray = useFieldArray({\n\t\tcontrol: form.control,\n\t\tname: 'regionPlans',\n\t});\n\n\tconst nextAvailableRegionToAdd = useMemo(() => {\n\t\tconst selectedRegionNames = selectedRegionPlans.map(region =>\n\t\t\tregionNameToLatencyToRegion?.[region.regionName!]?.[region.latencyDescription!]?.region\n\t\t);\n\t\tif (!totalPrice) {\n\t\t\t// Free plans can only add a single region.\n\t\t\treturn null;\n\t\t}\n\t\treturn regionLocations?.find(r => !selectedRegionNames.includes(r.region));\n\t}, [regionLocations, regionNameToLatencyToRegion, selectedRegionPlans, totalPrice]);\n\n\tconst onAddARegionClick = useCallback(() => {\n\t\tif (nextAvailableRegionToAdd) {\n\t\t\tregionPlansFieldArray.append({\n\t\t\t\tregionName: nextAvailableRegionToAdd.region,\n\t\t\t\tlatencyDescription: nextAvailableRegionToAdd.latencyDescription,\n\t\t\t});\n\t\t\tvoid form.trigger();\n\t\t}\n\t}, [form, nextAvailableRegionToAdd, regionPlansFieldArray]);\n\n\tif (!regionLocations?.length) {\n\t\treturn (\n\t\t\t<div className=\"md:col-span-6 col-span-3\">\n\t\t\t\t<ErrorComponent\n\t\t\t\t\tclassName=\"mt-0 m-0\"\n\t\t\t\t\ttitle=\"No Regions Available\"\n\t\t\t\t\tshowReturnToHome={false}\n\t\t\t\t\terror={{\n\t\t\t\t\t\tmessage: (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\tThe deployment type you selected currently has no available regions. Please try a different deployment\n\t\t\t\t\t\t\t\ttype, try again later, or <ContactUs />.\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t),\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t{regionPlansFieldArray.fields.map((field, index) => (\n\t\t\t\t<RegionFormInputs\n\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\tfieldArray={regionPlansFieldArray}\n\t\t\t\t\tform={form}\n\t\t\t\t\tindex={index}\n\t\t\t\t\tkey={field.id}\n\t\t\t\t\tregionNameToLatencyToRegion={regionNameToLatencyToRegion}\n\t\t\t\t\tpremiumOnlyRegions={premiumOnlyRegions}\n\t\t\t\t\tusageScale={usageScale}\n\t\t\t\t\tselectedPlan={selectedPlan}\n\t\t\t\t\tisEnterprise={isEnterprise}\n\t\t\t\t\tcloudProvider={cloudProvider}\n\t\t\t\t/>\n\t\t\t))}\n\n\t\t\t{nextAvailableRegionToAdd && (\n\t\t\t\t<div className=\"md:col-span-6 col-span-3\">\n\t\t\t\t\t<Button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tvariant=\"positiveOutline\"\n\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\tonClick={onAddARegionClick}\n\t\t\t\t\t>\n\t\t\t\t\t\t<PlusIcon />\n\t\t\t\t\t\tAdd Additional Region Usage\n\t\t\t\t\t</Button>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</>\n\t);\n}\n","import { Button } from '@/components/ui/button';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';\nimport { defaultOperationsApiPort } from '@/config/constants';\nimport { UpsertClusterSchemaType } from '@/features/clusters/upsert/upsertClusterSchema';\nimport { maxPortNumber, minPortNumber } from '@/lib/types/portNumbers';\nimport { TrashIcon } from 'lucide-react';\nimport { useCallback } from 'react';\nimport { Control, UseFieldArrayReturn, UseFormReturn } from 'react-hook-form';\n\ntype InstanceFormInputsProps = {\n\tcontrol: Control<UpsertClusterSchemaType>;\n\tfieldArray: UseFieldArrayReturn<UpsertClusterSchemaType, 'instances'>;\n\tform: UseFormReturn<UpsertClusterSchemaType>;\n\tindex: number;\n};\n\nexport function InstanceFormInputs({\n\tcontrol,\n\tfieldArray,\n\tform,\n\tindex,\n}: InstanceFormInputsProps) {\n\tconst onRemoveClicked = useCallback(() => {\n\t\tfieldArray?.remove(index);\n\t}, [fieldArray, index]);\n\n\treturn (\n\t\t<div className=\"md:col-span-6 col-span-3 p-4 rounded-md bg-accent gap-6 flex flex-wrap items-start\">\n\t\t\t<FormField\n\t\t\t\tcontrol={control}\n\t\t\t\tname={`instances.${index}.secure`}\n\t\t\t\trender={({ field }) => (\n\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t<FormLabel>Instance {fieldArray.fields.length > 1 ? index + 1 : ''}</FormLabel>\n\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t<Select\n\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\tonValueChange={value => {\n\t\t\t\t\t\t\t\t\tfield.onChange(value);\n\t\t\t\t\t\t\t\t\tvoid form.trigger();\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<SelectTrigger className=\"w-full\">\n\t\t\t\t\t\t\t\t\t<SelectValue placeholder=\"https://\" />\n\t\t\t\t\t\t\t\t</SelectTrigger>\n\t\t\t\t\t\t\t\t<SelectContent>\n\t\t\t\t\t\t\t\t\t<SelectGroup>\n\t\t\t\t\t\t\t\t\t\t<SelectItem value=\"true\">https://</SelectItem>\n\t\t\t\t\t\t\t\t\t\t<SelectItem value=\"false\">http://</SelectItem>\n\t\t\t\t\t\t\t\t\t</SelectGroup>\n\t\t\t\t\t\t\t\t</SelectContent>\n\t\t\t\t\t\t\t</Select>\n\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t</FormItem>\n\t\t\t\t)}\n\t\t\t/>\n\n\t\t\t<FormField\n\t\t\t\tcontrol={control}\n\t\t\t\tname={`instances.${index}.fqdn`}\n\t\t\t\trender={({ field }) => (\n\t\t\t\t\t<FormItem className=\"flex-3\">\n\t\t\t\t\t\t<FormLabel>Host Name</FormLabel>\n\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\tautoCapitalize=\"none\"\n\t\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\t\tautoCorrect=\"off\"\n\t\t\t\t\t\t\t\tonChange={e => {\n\t\t\t\t\t\t\t\t\tfield.onChange(e);\n\t\t\t\t\t\t\t\t\tconst value = e.target.value;\n\t\t\t\t\t\t\t\t\tconst isLocalhost = value === 'localhost' || value === '127.0.0.1';\n\t\t\t\t\t\t\t\t\tconst secureFieldState = form.getFieldState(`instances.${index}.secure`);\n\n\t\t\t\t\t\t\t\t\tif (isLocalhost && !secureFieldState.isDirty) {\n\t\t\t\t\t\t\t\t\t\tform.setValue(`instances.${index}.secure`, 'false');\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t</FormItem>\n\t\t\t\t)}\n\t\t\t/>\n\n\t\t\t<FormField\n\t\t\t\tcontrol={control}\n\t\t\t\tname={`instances.${index}.port`}\n\t\t\t\trender={({ field }) => (\n\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t<FormLabel>Operations API Port</FormLabel>\n\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\ttype=\"number\"\n\t\t\t\t\t\t\t\tmin={minPortNumber}\n\t\t\t\t\t\t\t\tmax={maxPortNumber}\n\t\t\t\t\t\t\t\tautoCapitalize=\"none\"\n\t\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\t\tautoCorrect=\"off\"\n\t\t\t\t\t\t\t\tplaceholder={String(defaultOperationsApiPort)}\n\t\t\t\t\t\t\t\tonChange={e => {\n\t\t\t\t\t\t\t\t\tfield.onChange(e.target.value ? parseInt(e.target.value, 10) : undefined);\n\t\t\t\t\t\t\t\t\tvoid form.trigger();\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t</FormItem>\n\t\t\t\t)}\n\t\t\t/>\n\n\t\t\t{fieldArray?.fields?.length && fieldArray?.fields?.length > 1 && (\n\t\t\t\t<div className=\"flex-none mt-6\">\n\t\t\t\t\t<Button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tvariant=\"destructiveOutline\"\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tonClick={onRemoveClicked}\n\t\t\t\t\t>\n\t\t\t\t\t\t<TrashIcon /> <span className=\"sr-only\">Remove</span>\n\t\t\t\t\t</Button>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","import { Button } from '@/components/ui/button';\nimport { defaultOperationsApiPort } from '@/config/constants';\nimport { UpsertClusterSchemaType } from '@/features/clusters/upsert/upsertClusterSchema';\nimport { PlusIcon } from 'lucide-react';\nimport { useCallback } from 'react';\nimport { useFieldArray, UseFormReturn } from 'react-hook-form';\nimport { InstanceFormInputs } from './InstanceFormInputs';\n\ninterface ClusterInstancesProps {\n\tform: UseFormReturn<UpsertClusterSchemaType>;\n}\n\nexport function ClusterInstances({\n\tform,\n}: ClusterInstancesProps) {\n\tconst instancesFieldArray = useFieldArray({\n\t\tcontrol: form.control,\n\t\tname: 'instances',\n\t});\n\n\tconst onAddInstanceClick = useCallback(() => {\n\t\tinstancesFieldArray.append({\n\t\t\tsecure: 'true',\n\t\t\tfqdn: '',\n\t\t\tport: defaultOperationsApiPort,\n\t\t});\n\t}, [instancesFieldArray]);\n\n\treturn (\n\t\t<>\n\t\t\t{instancesFieldArray.fields.map((field, index) => (\n\t\t\t\t<InstanceFormInputs\n\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\tfieldArray={instancesFieldArray}\n\t\t\t\t\tform={form}\n\t\t\t\t\tindex={index}\n\t\t\t\t\tkey={field.id}\n\t\t\t\t/>\n\t\t\t))}\n\n\t\t\t<div className=\"md:col-span-6 col-span-3\">\n\t\t\t\t<Button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tvariant=\"positiveOutline\"\n\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\tonClick={onAddInstanceClick}\n\t\t\t\t>\n\t\t\t\t\t<PlusIcon />\n\t\t\t\t\tAdd Instance\n\t\t\t\t</Button>\n\t\t\t</div>\n\t\t</>\n\t);\n}\n","import { SchemaPlan, SchemaRegion } from '@/integrations/api/api.gen';\n\nexport type PremiumOnlyRegions = {\n\tregionNames: Set<string>;\n\tregionIds: Set<string>;\n};\n\nfunction planServesRegion(plan: SchemaPlan, regionId: string): boolean {\n\treturn !plan.allowedRegionIds?.length || plan.allowedRegionIds.includes(regionId);\n}\n\n/**\n * Determines which regions and latencies are only reachable via premium tiers — i.e. plans above the\n * lowest planLevel for the deployment. A region/latency is \"premium-only\" when no base-level plan can\n * serve it but at least one higher-level plan can. A region name is premium-only when every selectable\n * latency under it is premium-only.\n */\nexport function calculatePremiumOnlyRegions(\n\tdeploymentPlans: SchemaPlan[],\n\tregionNameToLatencyToRegion: Record<string, Record<string, SchemaRegion>>,\n): PremiumOnlyRegions {\n\tconst regionNames = new Set<string>();\n\tconst regionIds = new Set<string>();\n\tif (!deploymentPlans.length) {\n\t\treturn { regionNames, regionIds };\n\t}\n\n\tconst minPlanLevel = Math.min(...deploymentPlans.map(plan => plan.planLevel ?? 0));\n\tconst basePlans = deploymentPlans.filter(plan => (plan.planLevel ?? 0) === minPlanLevel);\n\tconst premiumPlans = deploymentPlans.filter(plan => (plan.planLevel ?? 0) > minPlanLevel);\n\tif (!premiumPlans.length) {\n\t\treturn { regionNames, regionIds };\n\t}\n\n\tfor (const [regionName, latencyToRegion] of Object.entries(regionNameToLatencyToRegion)) {\n\t\tlet anySelectableLatency = false;\n\t\tlet allSelectableLatenciesPremiumOnly = true;\n\t\tfor (const region of Object.values(latencyToRegion)) {\n\t\t\tconst servedByBase = basePlans.some(plan => planServesRegion(plan, region.id));\n\t\t\tconst servedByPremium = premiumPlans.some(plan => planServesRegion(plan, region.id));\n\t\t\tif (!servedByBase && !servedByPremium) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tanySelectableLatency = true;\n\t\t\tif (!servedByBase) {\n\t\t\t\tregionIds.add(region.id);\n\t\t\t} else {\n\t\t\t\tallSelectableLatenciesPremiumOnly = false;\n\t\t\t}\n\t\t}\n\t\tif (anySelectableLatency && allSelectableLatenciesPremiumOnly) {\n\t\t\tregionNames.add(regionName);\n\t\t}\n\t}\n\n\treturn { regionNames, regionIds };\n}\n","import { Button } from '@/components/ui/button';\nimport { DialogFooter } from '@/components/ui/dialog';\nimport { HarperVersionsResponse } from '@/features/clusters/queries/getHarperVersionsQuery';\nimport { ClusterAbbreviatedName } from '@/features/clusters/upsert/fields/ClusterAbbreviatedName';\nimport { ClusterDeploymentDescription } from '@/features/clusters/upsert/fields/ClusterDeploymentDescription';\nimport { ClusterFQDN } from '@/features/clusters/upsert/fields/ClusterFQDN';\nimport { ClusterName } from '@/features/clusters/upsert/fields/ClusterName';\nimport { ClusterPerformanceDescription } from '@/features/clusters/upsert/fields/ClusterPerformanceDescription';\nimport { ClusterSkipGtmWait } from '@/features/clusters/upsert/fields/ClusterSkipGtmWait';\nimport { ClusterVersion } from '@/features/clusters/upsert/fields/ClusterVersion';\nimport { SchemaCloudInstanceTypes, SchemaPlan, SchemaRegion } from '@/integrations/api/api.gen';\nimport { ArrowRight } from 'lucide-react';\nimport { useEffect, useMemo } from 'react';\nimport { UseFormReturn, useFormState } from 'react-hook-form';\nimport { ClusterRegions } from './ClusterRegions';\nimport { ClusterInstances } from './components/ClusterInstances';\nimport { calculatePremiumOnlyRegions } from './lib/calculatePremiumOnlyRegions';\nimport { calculateUsageScale } from './lib/calculateUsageScale';\nimport { PartialUpgrade } from './lib/detectPartialUpgrade';\nimport { UpsertClusterSchemaType } from './upsertClusterSchema';\n\ninterface ClusterDetailsProps {\n\tcalculatedNames: { suggestedAbbreviatedName: string; fullHostName: string };\n\tclusterId?: string;\n\tdeploymentToPerformanceToPlan: Record<string, Record<string, SchemaPlan>>;\n\tform: UseFormReturn<UpsertClusterSchemaType>;\n\tharperVersions: HarperVersionsResponse | undefined;\n\tisEnterprise: boolean;\n\tcloudProvider: keyof SchemaCloudInstanceTypes | undefined;\n\tisPending: boolean;\n\tmode: 'version' | undefined;\n\tpartialUpgrade: PartialUpgrade | null;\n\tregionLocations: SchemaRegion[] | undefined;\n\tregionNameToLatencyToRegion: Record<string, Record<string, SchemaRegion>>;\n\tselectedDeployment: string;\n\tselectedPerformance: string;\n\tselectedPlan: SchemaPlan | undefined;\n\ttotalPrice: number;\n}\n\nexport function ClusterDetails({\n\tcalculatedNames,\n\tclusterId,\n\tdeploymentToPerformanceToPlan,\n\tform,\n\tharperVersions,\n\tisEnterprise,\n\tcloudProvider,\n\tisPending,\n\tmode,\n\tpartialUpgrade,\n\tregionLocations,\n\tregionNameToLatencyToRegion,\n\tselectedDeployment,\n\tselectedPerformance,\n\tselectedPlan,\n\ttotalPrice,\n}: ClusterDetailsProps) {\n\tconst { isDirty, isValid } = useFormState();\n\tconst availablePerformanceDescriptions = useMemo(() => {\n\t\tconst plansByTier = deploymentToPerformanceToPlan[selectedDeployment] || {};\n\t\tconst planLevels = Object.values(plansByTier).map(plan => plan.planLevel ?? 0);\n\t\tconst minPlanLevel = planLevels.length ? Math.min(...planLevels) : 0;\n\t\treturn Object.keys(plansByTier).map(performanceTier => {\n\t\t\tconst isPremium = (plansByTier[performanceTier].planLevel ?? 0) > minPlanLevel;\n\t\t\tconst splitByParens = performanceTier.slice(0, -1).split('(');\n\t\t\tif (splitByParens.length > 1) {\n\t\t\t\treturn {\n\t\t\t\t\tperformanceTier,\n\t\t\t\t\tname: splitByParens[0],\n\t\t\t\t\tdescription: splitByParens[1],\n\t\t\t\t\tisPremium,\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst splitByFor = performanceTier.split(' for ');\n\t\t\tif (splitByFor.length > 1) {\n\t\t\t\treturn {\n\t\t\t\t\tperformanceTier,\n\t\t\t\t\tname: splitByFor[0],\n\t\t\t\t\tdescription: 'For ' + splitByFor[1],\n\t\t\t\t\tisPremium,\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tperformanceTier,\n\t\t\t\tname: performanceTier,\n\t\t\t\tdescription: '',\n\t\t\t\tisPremium,\n\t\t\t};\n\t\t});\n\t}, [deploymentToPerformanceToPlan, selectedDeployment]);\n\tconst availableDeploymentTypes = useMemo(() => Object.keys(deploymentToPerformanceToPlan).sort(), [\n\t\tdeploymentToPerformanceToPlan,\n\t]);\n\tconst premiumOnlyRegions = useMemo(\n\t\t() =>\n\t\t\tcalculatePremiumOnlyRegions(\n\t\t\t\tObject.values(deploymentToPerformanceToPlan[selectedDeployment] || {}),\n\t\t\t\tregionNameToLatencyToRegion,\n\t\t\t),\n\t\t[deploymentToPerformanceToPlan, regionNameToLatencyToRegion, selectedDeployment],\n\t);\n\tconst usageScale = useMemo(\n\t\t() =>\n\t\t\tcalculateUsageScale(\n\t\t\t\tObject.values(deploymentToPerformanceToPlan).flatMap(performanceToPlan => Object.values(performanceToPlan)),\n\t\t\t\tregionNameToLatencyToRegion,\n\t\t\t),\n\t\t[deploymentToPerformanceToPlan, regionNameToLatencyToRegion],\n\t);\n\n\tuseEffect(function autoSelectFirstAvailablePerformanceDescription() {\n\t\tif (\n\t\t\tavailablePerformanceDescriptions?.length\n\t\t\t&& !availablePerformanceDescriptions.find(sp => sp.performanceTier === selectedPerformance)\n\t\t) {\n\t\t\tform.setValue('performanceDescription', availablePerformanceDescriptions[0].performanceTier);\n\t\t\tvoid form.trigger();\n\t\t}\n\t}, [selectedDeployment, selectedPerformance, availablePerformanceDescriptions, form]);\n\n\tconst isSelfManaged = selectedDeployment === 'Self-Hosted';\n\n\t// On a partially-upgraded cluster the version is already pre-selected to the latest, so the form\n\t// never goes dirty — allow re-submitting it anyway so the lagging instances can be retried.\n\tconst allowVersionResubmit = mode === 'version' && !!partialUpgrade;\n\n\tconst footer = (\n\t\t<DialogFooter className=\"mt-3 mb-12\">\n\t\t\t<Button\n\t\t\t\ttype=\"submit\"\n\t\t\t\tvariant=\"submit\"\n\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\tdisabled={isPending || (clusterId && !isDirty && !allowVersionResubmit) || !isValid}\n\t\t\t>\n\t\t\t\t{mode !== 'version' && totalPrice > 0\n\t\t\t\t\t? 'Confirm Payment Details'\n\t\t\t\t\t: clusterId\n\t\t\t\t\t? 'Edit Cluster'\n\t\t\t\t\t: 'Create New Cluster'}\n\t\t\t\t<ArrowRight />\n\t\t\t</Button>\n\t\t</DialogFooter>\n\t);\n\n\tif (mode === 'version') {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<div className=\"grid grid-cols-3 items-start gap-6 text-foreground md:grid-cols-6\">\n\t\t\t\t\t<ClusterName\n\t\t\t\t\t\tclassName={harperVersions?.value?.length ? 'col-span-3' : 'md:col-span-6 col-span-3'}\n\t\t\t\t\t\tdisabled={true}\n\t\t\t\t\t\tform={form}\n\t\t\t\t\t/>\n\t\t\t\t\t<ClusterVersion\n\t\t\t\t\t\tclassName=\"col-span-3\"\n\t\t\t\t\t\tform={form}\n\t\t\t\t\t\tharperVersions={harperVersions}\n\t\t\t\t\t/>\n\t\t\t\t\t<ClusterSkipGtmWait className=\"col-span-3 md:col-span-6\" form={form} />\n\t\t\t\t\t{partialUpgrade && (\n\t\t\t\t\t\t<p className=\"col-span-3 md:col-span-6 max-w-prose text-xs font-light text-amber-600 dark:text-amber-400\">\n\t\t\t\t\t\t\t{partialUpgrade.behindCount} of {partialUpgrade.total} instances{' '}\n\t\t\t\t\t\t\t{partialUpgrade.behindCount === 1 ? 'is' : 'are'} still on an older version. Re-run the upgrade to bring\n\t\t\t\t\t\t\t{' '}\n\t\t\t\t\t\t\t{partialUpgrade.behindCount === 1 ? 'it' : 'them'} up to {partialUpgrade.latest}.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t{footer}\n\t\t\t</>\n\t\t);\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t<div className=\"grid grid-cols-3 items-start gap-6 text-foreground md:grid-cols-6\">\n\t\t\t\t<ClusterName\n\t\t\t\t\tclassName={harperVersions?.value?.length ? 'col-span-3' : 'md:col-span-6 col-span-3'}\n\t\t\t\t\tdisabled={!!clusterId}\n\t\t\t\t\tform={form}\n\t\t\t\t/>\n\t\t\t\t<ClusterVersion\n\t\t\t\t\tclassName=\"col-span-3\"\n\t\t\t\t\tdisabled={!!clusterId}\n\t\t\t\t\tform={form}\n\t\t\t\t\tharperVersions={harperVersions}\n\t\t\t\t/>\n\n\t\t\t\t{isSelfManaged\n\t\t\t\t\t? <ClusterFQDN form={form} disabled={!!clusterId} />\n\t\t\t\t\t: <ClusterAbbreviatedName form={form} calculatedNames={calculatedNames} disabled={!!clusterId} />}\n\n\t\t\t\t<ClusterDeploymentDescription form={form} availableDeploymentTypes={availableDeploymentTypes} />\n\n\t\t\t\t<ClusterPerformanceDescription\n\t\t\t\t\tavailablePerformanceDescriptions={availablePerformanceDescriptions}\n\t\t\t\t\tform={form}\n\t\t\t\t\tselectedDeployment={selectedDeployment}\n\t\t\t\t/>\n\n\t\t\t\t{isSelfManaged\n\t\t\t\t\t? <ClusterInstances form={form} />\n\t\t\t\t\t: (\n\t\t\t\t\t\t<ClusterRegions\n\t\t\t\t\t\t\tform={form}\n\t\t\t\t\t\t\tregionLocations={regionLocations}\n\t\t\t\t\t\t\tregionNameToLatencyToRegion={regionNameToLatencyToRegion}\n\t\t\t\t\t\t\tpremiumOnlyRegions={premiumOnlyRegions}\n\t\t\t\t\t\t\tusageScale={usageScale}\n\t\t\t\t\t\t\tselectedPlan={selectedPlan}\n\t\t\t\t\t\t\ttotalPrice={totalPrice}\n\t\t\t\t\t\t\tisEnterprise={isEnterprise}\n\t\t\t\t\t\t\tcloudProvider={cloudProvider}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t{clusterId && !isSelfManaged && <ClusterSkipGtmWait className=\"col-span-3 md:col-span-6\" form={form} />}\n\t\t\t</div>\n\t\t\t{footer}\n\t\t</>\n\t);\n}\n","import { defaultOperationsApiPort } from '@/config/constants';\nimport { UpsertClusterSchema } from '@/features/clusters/upsert/upsertClusterSchema';\nimport { z } from 'zod';\n\nexport function calculateInstanceFQDN(instance: z.infer<typeof UpsertClusterSchema.shape.instances.element>) {\n\tconst { fqdn } = instance;\n\tlet { secure, port } = instance;\n\tif (!port) {\n\t\tport = defaultOperationsApiPort;\n\t}\n\tif (port === 443 && secure === 'false') {\n\t\tsecure = 'true';\n\t}\n\tif (port === 80 && secure === 'true') {\n\t\tsecure = 'false';\n\t}\n\treturn `${secure === 'true' ? 'https' : 'http'}://${fqdn}${port === 443 || port === 80 ? '' : (':' + port)}`\n\t\t.toLowerCase();\n}\n","import { UpsertClusterSchemaType } from '@/features/clusters/upsert/upsertClusterSchema';\nimport { SchemaPlan, SchemaRegion } from '@/integrations/api/api.gen';\n\nexport function calculateDefaultDeploymentPerformanceAndRegionPlans(\n\tplanTypes: SchemaPlan[],\n\tregionLocations: SchemaRegion[],\n\talreadyUsingFree?: boolean,\n): null | Pick<UpsertClusterSchemaType, 'deploymentDescription' | 'performanceDescription' | 'regionPlans'> {\n\tconst planToSelect =\n\t\tplanTypes.find(planType =>\n\t\t\t(alreadyUsingFree ? !!planType.priceUsd : !planType.priceUsd) && planType.deploymentType === 'colocated'\n\t\t)\n\t\t|| planTypes.find(planType => planType.deploymentType === 'colocated')\n\t\t|| planTypes[0];\n\tconst allowedRegionIds = planToSelect?.allowedRegionIds;\n\tif (planToSelect) {\n\t\tconst allowedRegions = allowedRegionIds\n\t\t\t? regionLocations.filter(regionLocation => allowedRegionIds.includes(regionLocation.id))\n\t\t\t: regionLocations;\n\t\tconst regionToSelect = allowedRegions.find(regionLocation => regionLocation.region === 'US') || allowedRegions[0];\n\t\tif (regionToSelect) {\n\t\t\treturn {\n\t\t\t\tdeploymentDescription: planToSelect.deploymentDescription,\n\t\t\t\tperformanceDescription: planToSelect.performanceDescription,\n\t\t\t\tregionPlans: [\n\t\t\t\t\t{\n\t\t\t\t\t\tregionName: regionToSelect.region,\n\t\t\t\t\t\tlatencyDescription: regionToSelect.latencyDescription,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\t}\n\treturn null;\n}\n","import { UpsertClusterSchemaType } from '@/features/clusters/upsert/upsertClusterSchema';\nimport { SchemaPlan, SchemaRegion } from '@/integrations/api/api.gen';\nimport { UseFormReturn } from 'react-hook-form';\nimport {\n\tcalculateDefaultDeploymentPerformanceAndRegionPlans,\n} from './calculateDefaultDeploymentPerformanceAndRegionPlans';\n\nexport function pickDefaultDeploymentPerformanceAndRegionPlans(\n\tform: UseFormReturn<UpsertClusterSchemaType>,\n\tplanTypes: SchemaPlan[] | undefined,\n\tregionLocations: SchemaRegion[] | undefined,\n) {\n\tif (planTypes && regionLocations) {\n\t\tconst values = form.getValues();\n\t\tif (!values.deploymentDescription || !values.performanceDescription || !values.regionPlans.length) {\n\t\t\tconst defaults = calculateDefaultDeploymentPerformanceAndRegionPlans(planTypes, regionLocations);\n\t\t\tif (defaults) {\n\t\t\t\tif (!values.deploymentDescription && !values.performanceDescription) {\n\t\t\t\t\tform.setValue('deploymentDescription', defaults.deploymentDescription);\n\t\t\t\t\tform.setValue('performanceDescription', defaults.performanceDescription);\n\t\t\t\t}\n\t\t\t\tif (!values.regionPlans.length) {\n\t\t\t\t\tform.setValue('regionPlans', defaults.regionPlans);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n","export function PriceDisplay({ price }: { readonly price?: number }) {\n\tconst numberFormat = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' });\n\tconst parts = numberFormat.formatToParts(price || 0);\n\treturn (\n\t\t<span className=\"text-4xl\">\n\t\t\t{parts.map((part, index) => <PricePart key={index} type={part.type} value={part.value} />)}\n\t\t</span>\n\t);\n}\n\nfunction PricePart({ type, value }: ReturnType<Intl.NumberFormat['formatToParts']>[0]) {\n\tswitch (type) {\n\t\tcase 'currency':\n\t\tcase 'decimal':\n\t\tcase 'fraction':\n\t\t\treturn <sup className=\"font-light text-xl\">{value}</sup>;\n\t\tdefault:\n\t\t\treturn value;\n\t}\n}\n","import { EstimatedProgressBar } from '@/components/EstimatedProgressBar';\nimport { Badge } from '@/components/ui/badge';\nimport { Form } from '@/components/ui/form/Form';\nimport { isFailed } from '@/components/ui/utils/badgeStatus';\nimport { defaultOperationsApiPort } from '@/config/constants';\nimport { useCreateNewClusterMutation } from '@/features/clusters/hooks/useCreateNewCluster';\nimport { useEditClusterMutation } from '@/features/clusters/hooks/useUpdateCluster';\nimport { terminateCluster } from '@/features/clusters/mutations/terminateCluster';\nimport { HarperVersionsResponse } from '@/features/clusters/queries/getHarperVersionsQuery';\nimport { getOrganization } from '@/features/organization/queries/getOrganizationQuery';\nimport { SchemaPlan, SchemaRegion, SchemaRegionPlan } from '@/integrations/api/api.gen';\nimport { Organization } from '@/integrations/api/api.patch';\nimport { ENTERPRISE } from '@/integrations/api/orgType';\nimport { sortByField } from '@/lib/arrays/sort/byField';\nimport { groupThenKeyBy } from '@/lib/groupThenKeyBy';\nimport { pluralize } from '@/lib/pluralize';\nimport { collapseKebabsToMaxLength } from '@/lib/string/collapseKebabsToMaxLength';\nimport { stringsShareAPrefix } from '@/lib/string/stringsShareAPrefix';\nimport { toKebabCase } from '@/lib/string/to-kebab-case';\nimport { isPositive } from '@/lib/types/isPositive';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { useNavigate, useRouter } from '@tanstack/react-router';\nimport { cx } from 'class-variance-authority';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\nimport { ClusterBilling } from './ClusterBilling';\nimport { ClusterDetails } from './ClusterDetails';\nimport { calculateInstanceFQDN } from './lib/calculateInstanceFQDN';\nimport { PartialUpgrade } from './lib/detectPartialUpgrade';\nimport { pickDefaultDeploymentPerformanceAndRegionPlans } from './lib/pickDefaultDeploymentPerformanceAndRegionPlans';\nimport { PriceDisplay } from './PriceDisplay';\nimport { specifiedAbbreviatedName, UpsertClusterSchema, UpsertClusterSchemaType } from './upsertClusterSchema';\n\ninterface ClusterFormProps {\n\talreadyUsingFree: boolean;\n\tclusterId?: string;\n\tdefaultValues: UpsertClusterSchemaType;\n\tdeploymentToPerformanceToPlan: Record<string, Record<string, SchemaPlan>>;\n\tharperVersions: HarperVersionsResponse | undefined;\n\tmode: 'version' | undefined;\n\torganization: Organization;\n\torganizationId: string;\n\tpartialUpgrade: PartialUpgrade | null;\n\tplanTypes: SchemaPlan[];\n\tregionLocationsColocated: SchemaRegion[];\n\tregionLocationsDedicated: SchemaRegion[];\n\tsetSavedClusterState: (value: null | ({ clusterId?: string } & UpsertClusterSchemaType)) => void;\n\tstartOffOnBilling: boolean;\n}\n\nexport function ClusterForm({\n\talreadyUsingFree,\n\tclusterId,\n\tdefaultValues,\n\tdeploymentToPerformanceToPlan,\n\tharperVersions,\n\tmode,\n\torganization,\n\torganizationId,\n\tpartialUpgrade,\n\tplanTypes,\n\tregionLocationsColocated,\n\tregionLocationsDedicated,\n\tsetSavedClusterState,\n\tstartOffOnBilling,\n}: ClusterFormProps) {\n\tconst navigate = useNavigate();\n\tconst router = useRouter();\n\tconst isEnterprise = organization?.type === ENTERPRISE;\n\tconst cloudProvider = organization?.channel === 'Akamai' ? 'linode' : undefined;\n\n\tconst queryClient = useQueryClient();\n\tconst { mutate: submitNewClusterData, isPending: isCreatePending } = useCreateNewClusterMutation();\n\tconst { mutate: submitEditClusterData, isPending: isEditPending } = useEditClusterMutation();\n\n\tconst [confirmingPaymentDetails, setConfirmingPaymentDetails] = useState(startOffOnBilling);\n\n\tconst colocatedRegionNameToLatencyToRegion = useMemo<Record<string, Record<string, SchemaRegion>>>(\n\t\t() =>\n\t\t\tgroupThenKeyBy(\n\t\t\t\tregionLocationsColocated?.sort(sortByField('latencyDescription')) || [],\n\t\t\t\t'region',\n\t\t\t\t'latencyDescription',\n\t\t\t),\n\t\t[regionLocationsColocated],\n\t);\n\tconst dedicatedRegionNameToLatencyToRegion = useMemo<Record<string, Record<string, SchemaRegion>>>(\n\t\t() =>\n\t\t\tgroupThenKeyBy(\n\t\t\t\tregionLocationsDedicated?.sort(sortByField('latencyDescription')) || [],\n\t\t\t\t'region',\n\t\t\t\t'latencyDescription',\n\t\t\t),\n\t\t[regionLocationsDedicated],\n\t);\n\n\tconst refineZod = useCallback((data: UpsertClusterSchemaType, ctx: z.RefinementCtx) => {\n\t\tconst names = new Set();\n\t\tconst selectedPlan = deploymentToPerformanceToPlan?.[data.deploymentDescription]?.[data.performanceDescription];\n\t\tconst isSelfManaged = data.deploymentDescription === 'Self-Hosted';\n\t\tif (isSelfManaged) {\n\t\t\tfor (let i = 0; i < data.instances.length; i++) {\n\t\t\t\tconst fqdn = calculateInstanceFQDN(data.instances[i]);\n\t\t\t\tif (!names.has(fqdn)) {\n\t\t\t\t\tnames.add(fqdn);\n\t\t\t\t} else {\n\t\t\t\t\tctx.addIssue({\n\t\t\t\t\t\tcode: 'custom',\n\t\t\t\t\t\tpath: [`instances.${i}.fqdn`],\n\t\t\t\t\t\tmessage: 'Every instance url must be unique!',\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif (selectedPlan?.priceUsd === 0 && alreadyUsingFree) {\n\t\t\t\tctx.addIssue({\n\t\t\t\t\tcode: 'custom',\n\t\t\t\t\tpath: [`performanceDescription`],\n\t\t\t\t\tmessage: 'Only one free cluster is allowed per organization.',\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst regionNameToLatencyToRegion = selectedPlan?.deploymentDescription !== 'Dedicated'\n\t\t\t\t? colocatedRegionNameToLatencyToRegion\n\t\t\t\t: dedicatedRegionNameToLatencyToRegion;\n\n\t\t\tfor (let i = 0; i < data.regionPlans.length; i++) {\n\t\t\t\tconst regionPlan = data.regionPlans[i];\n\t\t\t\tconst region = regionNameToLatencyToRegion[regionPlan.regionName]?.[regionPlan.latencyDescription];\n\t\t\t\tif (!names.has(regionPlan.regionName)) {\n\t\t\t\t\tnames.add(regionPlan.regionName);\n\t\t\t\t} else {\n\t\t\t\t\tctx.addIssue({\n\t\t\t\t\t\tcode: 'custom',\n\t\t\t\t\t\tpath: [`regionPlans.${i}.regionName`],\n\t\t\t\t\t\tmessage: 'You can only select a region once!',\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif (selectedPlan?.allowedRegionIds?.length && region?.id) {\n\t\t\t\t\tif (!selectedPlan.allowedRegionIds.includes(region.id)) {\n\t\t\t\t\t\tconst prefixMatches = stringsShareAPrefix(selectedPlan.allowedRegionIds, region.id);\n\t\t\t\t\t\tif (!prefixMatches) {\n\t\t\t\t\t\t\tctx.addIssue({\n\t\t\t\t\t\t\t\tcode: 'custom',\n\t\t\t\t\t\t\t\tpath: [`regionPlans.${i}.regionName`],\n\t\t\t\t\t\t\t\tmessage: `This region is not available with the selected performance tier!`,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tctx.addIssue({\n\t\t\t\t\t\t\t\tcode: 'custom',\n\t\t\t\t\t\t\t\tpath: [`regionPlans.${i}.latencyDescription`],\n\t\t\t\t\t\t\t\tmessage: `This latency is not available with the selected performance tier!`,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (i >= 1) {\n\t\t\t\t\t\tctx.addIssue({\n\t\t\t\t\t\t\tcode: 'custom',\n\t\t\t\t\t\t\tpath: [`regionPlans.${i}.regionName`],\n\t\t\t\t\t\t\tmessage: `You can only select one region with this performance tier!`,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}, [\n\t\talreadyUsingFree,\n\t\tcolocatedRegionNameToLatencyToRegion,\n\t\tdedicatedRegionNameToLatencyToRegion,\n\t\tdeploymentToPerformanceToPlan,\n\t]);\n\n\tconst form = useForm({\n\t\tmode: 'onChange',\n\t\tresolver: zodResolver(UpsertClusterSchema.superRefine(refineZod)),\n\t\tdefaultValues,\n\t});\n\n\tconst [firstTime, setFirstTime] = useState(true);\n\tuseEffect(() => {\n\t\tif (firstTime && defaultValues) {\n\t\t\tsetSavedClusterState(null);\n\t\t\tsetFirstTime(false);\n\t\t}\n\t}, [defaultValues, firstTime, setSavedClusterState]);\n\n\tconst clusterName = form.watch('clusterName');\n\tconst abbreviatedName = form.watch('abbreviatedName');\n\tconst selectedDeployment = form.watch('deploymentDescription');\n\tconst selectedPerformance = form.watch('performanceDescription');\n\tconst selectedRegionPlans = form.watch('regionPlans');\n\tconst selectedInstances = form.watch('instances');\n\n\tconst regionNameToLatencyToRegion = selectedDeployment !== 'Dedicated'\n\t\t? colocatedRegionNameToLatencyToRegion\n\t\t: dedicatedRegionNameToLatencyToRegion;\n\tconst regionLocations = selectedDeployment !== 'Dedicated'\n\t\t? regionLocationsColocated\n\t\t: regionLocationsDedicated;\n\n\tuseEffect(function syncInstancesAndRegionsWithSelfManagedSelection() {\n\t\tconst values = form.getValues();\n\t\tconst isSelfManaged = selectedDeployment === 'Self-Hosted';\n\t\tif (!selectedDeployment) {\n\t\t\treturn;\n\t\t}\n\t\tif (isSelfManaged) {\n\t\t\tif (values.abbreviatedName) {\n\t\t\t\tform.setValue('abbreviatedName', '');\n\t\t\t}\n\t\t\tif (values.regionPlans.length) {\n\t\t\t\tform.setValue('regionPlans', []);\n\t\t\t}\n\t\t\tif (!values.instances.length) {\n\t\t\t\tform.setValue('instances', [\n\t\t\t\t\t{\n\t\t\t\t\t\tsecure: 'true',\n\t\t\t\t\t\tfqdn: '',\n\t\t\t\t\t\tport: defaultOperationsApiPort,\n\t\t\t\t\t},\n\t\t\t\t]);\n\t\t\t}\n\t\t} else {\n\t\t\tif (values.fqdn) {\n\t\t\t\tform.setValue('fqdn', '');\n\t\t\t}\n\t\t\tif (values.instances.length) {\n\t\t\t\tform.setValue('instances', []);\n\t\t\t}\n\t\t\tif (!values.regionPlans.length) {\n\t\t\t\tpickDefaultDeploymentPerformanceAndRegionPlans(form, planTypes, regionLocations);\n\t\t\t}\n\t\t}\n\t}, [form, planTypes, regionLocations, selectedDeployment]);\n\n\tconst calculatedNames = useMemo(() => {\n\t\tconst suggestedAbbreviatedName = collapseKebabsToMaxLength(\n\t\t\ttoKebabCase(clusterName),\n\t\t\tspecifiedAbbreviatedName.maxLength!,\n\t\t);\n\t\treturn {\n\t\t\tsuggestedAbbreviatedName,\n\t\t\tfullHostName: `${abbreviatedName || suggestedAbbreviatedName}.${\n\t\t\t\torganization.subdomain || 'your-org'\n\t\t\t}.harperfabric.com`,\n\t\t};\n\t}, [clusterName, abbreviatedName, organization]);\n\tconst selectedPlan = useMemo(() => deploymentToPerformanceToPlan?.[selectedDeployment]?.[selectedPerformance], [\n\t\tdeploymentToPerformanceToPlan,\n\t\tselectedDeployment,\n\t\tselectedPerformance,\n\t]);\n\n\tuseEffect(function autoSelectRegionBasedOnAllowedRegionIds() {\n\t\tconst allowedRegionIds = selectedPlan?.allowedRegionIds;\n\t\tif (allowedRegionIds?.length && selectedRegionPlans?.length === 1) {\n\t\t\tconst firstRegion = selectedRegionPlans[0];\n\t\t\tconst firstSelectedRegion = regionNameToLatencyToRegion?.[firstRegion.regionName]\n\t\t\t\t?.[firstRegion.latencyDescription];\n\t\t\tif (!allowedRegionIds.includes(firstSelectedRegion?.id)) {\n\t\t\t\tconst possibleRegions = regionLocations?.filter(r => allowedRegionIds.includes(r.id));\n\t\t\t\tconst regionToSelect = possibleRegions?.find(r => r.region === 'US') || possibleRegions?.[0];\n\t\t\t\tif (regionToSelect) {\n\t\t\t\t\tform.setValue('regionPlans.0.regionName', regionToSelect.region);\n\t\t\t\t\tform.setValue('regionPlans.0.latencyDescription', regionToSelect.latencyDescription);\n\t\t\t\t\tvoid form.trigger();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}, [selectedPlan, selectedRegionPlans, form, regionNameToLatencyToRegion, regionLocations]);\n\n\tuseEffect(function syncRegionSelectionsWithPossibleRegions() {\n\t\tconst isSelfManaged = selectedDeployment === 'Self-Hosted';\n\t\tif (!isSelfManaged && Object.keys(regionNameToLatencyToRegion).length && selectedRegionPlans.length) {\n\t\t\tfor (let i = 0; i < selectedRegionPlans.length; i++) {\n\t\t\t\tconst regionPlan = selectedRegionPlans[i];\n\t\t\t\tif (!regionNameToLatencyToRegion[regionPlan.regionName]) {\n\t\t\t\t\tform.setValue(`regionPlans.${i}.regionName`, '');\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}, [form, regionNameToLatencyToRegion, selectedDeployment, selectedRegionPlans]);\n\n\tconst totalPrice = !selectedPlan?.priceUsd\n\t\t? 0\n\t\t: selectedDeployment === 'Self-Hosted'\n\t\t? selectedInstances.length * selectedPlan.priceUsd\n\t\t: selectedRegionPlans.reduce((total, region) => {\n\t\t\tconst regionPlan = regionNameToLatencyToRegion?.[region.regionName!]?.[region.latencyDescription!];\n\t\t\treturn total + (!regionPlan\n\t\t\t\t? 0\n\t\t\t\t: selectedPlan.priceUsd * regionPlan.instanceCount / 2);\n\t\t}, 0);\n\n\tconst expirationMonths = selectedPlan?.planLimits?.expirationMonths;\n\tconst termMonths = isPositive(expirationMonths) && expirationMonths < 1000 ? expirationMonths : undefined;\n\tconst monthlyPrice = termMonths ? totalPrice / termMonths : totalPrice;\n\n\tconst onStartSaving = useCallback(({\n\t\tcreating,\n\t\tdeploymentDescription,\n\t}: {\n\t\tcreating: boolean;\n\t\tdeploymentDescription: string;\n\t}) =>\n\t\ttoast.message(creating ? 'Creating Cluster' : 'Updating Cluster', {\n\t\t\tdescription: (\n\t\t\t\t<EstimatedProgressBar\n\t\t\t\t\tmessage=\"This may take a little bit, hold tight!\"\n\t\t\t\t\tlateMessage=\"Still working on it... why don't you grab a coffee, and I'll let you know when it's done?\"\n\t\t\t\t\tduration={deploymentDescription === 'Dedicated' ? 60_000 : 5_000}\n\t\t\t\t/>\n\t\t\t),\n\t\t\tduration: 0,\n\t\t}), []);\n\n\tconst onClusterSavedCallback = useCallback(async ({\n\t\tclusterId,\n\t\tsourceClusterId,\n\t\tcreating,\n\t\ttoastId,\n\t\tisSelfManaged,\n\t}: {\n\t\tclusterId: string;\n\t\tsourceClusterId: string | undefined;\n\t\tcreating: boolean;\n\t\tisSelfManaged: boolean;\n\t\ttoastId: string | number;\n\t}) => {\n\t\tif (sourceClusterId) {\n\t\t\tconst existingOrg = await getOrganization(organizationId);\n\t\t\tconst sourceCluster = existingOrg.clusters?.find(c => c.id === sourceClusterId);\n\t\t\tif (isFailed(sourceCluster?.status)) {\n\t\t\t\tawait terminateCluster(sourceClusterId);\n\t\t\t}\n\t\t}\n\n\t\tvoid queryClient.invalidateQueries({ queryKey: [organizationId], refetchType: 'active' });\n\t\tif (!creating) {\n\t\t\tvoid queryClient.invalidateQueries({ queryKey: [clusterId], refetchType: 'active' });\n\t\t}\n\n\t\tvoid router.invalidate();\n\t\tif (isSelfManaged) {\n\t\t\tvoid navigate({ to: `/${organizationId}/${clusterId}/instances` });\n\t\t} else if (creating) {\n\t\t\tvoid navigate({ to: `/${organizationId}/${clusterId}/starting-up` });\n\t\t} else {\n\t\t\tvoid navigate({ to: `/${organizationId}/${clusterId}/scaling` });\n\t\t}\n\t\tform.reset();\n\t\ttoast.success(creating ? 'Cluster Created' : 'Cluster Updated', {\n\t\t\tid: toastId,\n\t\t\tdescription: isSelfManaged\n\t\t\t\t? undefined\n\t\t\t\t: creating\n\t\t\t\t? 'It is being provisioned now.'\n\t\t\t\t: 'The updates are being provisioned now.',\n\t\t\tduration: 5_000,\n\t\t});\n\t}, [queryClient, router, navigate, organizationId, form]);\n\n\tconst executeChangesToCluster = useCallback(async () => {\n\t\tconst formData = form.getValues();\n\t\tconst plans: SchemaRegionPlan[] = [];\n\t\tconst plan = deploymentToPerformanceToPlan[formData.deploymentDescription][formData.performanceDescription];\n\n\t\tconst isSelfManaged = formData.deploymentDescription === 'Self-Hosted';\n\t\tif (isSelfManaged) {\n\t\t\tfor (const instance of formData.instances) {\n\t\t\t\tplans.push({\n\t\t\t\t\tautoRenew: true,\n\t\t\t\t\tinstanceFqdn: instance.fqdn,\n\t\t\t\t\toperationsApiPort: instance.port || defaultOperationsApiPort,\n\t\t\t\t\toperationsApiSecure: instance.secure === 'true',\n\t\t\t\t\tplanId: plan.id,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tfor (const regionPlan of formData.regionPlans) {\n\t\t\t\tconst region = regionNameToLatencyToRegion[regionPlan.regionName][regionPlan.latencyDescription];\n\t\t\t\tplans.push({\n\t\t\t\t\tautoRenew: true,\n\t\t\t\t\tplanId: plan.id,\n\t\t\t\t\tregionId: region.id,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tsetSavedClusterState(null);\n\t\tconst toastId = onStartSaving({ creating: !clusterId, deploymentDescription: formData.deploymentDescription });\n\t\tconst clearToast = () => toast.dismiss(toastId);\n\t\tif (clusterId) {\n\t\t\tsubmitEditClusterData(\n\t\t\t\tmode === 'version'\n\t\t\t\t\t? { id: clusterId, version: formData.version, skipGtmWait: formData.skipGtmWait }\n\t\t\t\t\t: { id: clusterId, regionPlans: plans, skipGtmWait: formData.skipGtmWait },\n\t\t\t\t{\n\t\t\t\t\tonSuccess: (data) =>\n\t\t\t\t\t\tonClusterSavedCallback({\n\t\t\t\t\t\t\tclusterId: data.id,\n\t\t\t\t\t\t\tsourceClusterId: formData.sourceClusterId,\n\t\t\t\t\t\t\tisSelfManaged,\n\t\t\t\t\t\t\tcreating: false,\n\t\t\t\t\t\t\ttoastId,\n\t\t\t\t\t\t}),\n\t\t\t\t\tonError: clearToast,\n\t\t\t\t},\n\t\t\t);\n\t\t} else {\n\t\t\tsubmitNewClusterData({\n\t\t\t\tabbreviatedName: isSelfManaged\n\t\t\t\t\t? undefined\n\t\t\t\t\t: (formData.abbreviatedName || calculatedNames.suggestedAbbreviatedName),\n\t\t\t\tautoRenew: true,\n\t\t\t\tfqdn: isSelfManaged && formData.fqdn || undefined,\n\t\t\t\tname: formData.clusterName,\n\t\t\t\tversion: formData.version,\n\t\t\t\torganizationId,\n\t\t\t\tregionPlans: plans,\n\t\t\t}, {\n\t\t\t\tonSuccess: (data) =>\n\t\t\t\t\tonClusterSavedCallback({\n\t\t\t\t\t\tclusterId: data.id,\n\t\t\t\t\t\tsourceClusterId: formData.sourceClusterId,\n\t\t\t\t\t\tisSelfManaged,\n\t\t\t\t\t\tcreating: true,\n\t\t\t\t\t\ttoastId,\n\t\t\t\t\t}),\n\t\t\t\tonError: clearToast,\n\t\t\t});\n\t\t}\n\t}, [\n\t\tcalculatedNames.suggestedAbbreviatedName,\n\t\tclusterId,\n\t\tdeploymentToPerformanceToPlan,\n\t\tform,\n\t\tonClusterSavedCallback,\n\t\tonStartSaving,\n\t\torganizationId,\n\t\tregionNameToLatencyToRegion,\n\t\tsetSavedClusterState,\n\t\tsubmitEditClusterData,\n\t\tsubmitNewClusterData,\n\t]);\n\n\tconst submitClusterDetailsForm = useCallback(() => {\n\t\tif (mode !== 'version' && totalPrice > 0) {\n\t\t\tsetConfirmingPaymentDetails(true);\n\t\t\treturn;\n\t\t}\n\t\treturn executeChangesToCluster();\n\t}, [mode, executeChangesToCluster, totalPrice]);\n\n\tconst onSaveStateForBillingRedirect = useCallback((redirecting: boolean) => {\n\t\tsetSavedClusterState(redirecting ? { clusterId, ...form.getValues(), skipToBilling: true } : null);\n\t}, [clusterId, form, setSavedClusterState]);\n\n\tconst onGoBackToDetails = useCallback(() => {\n\t\tsetConfirmingPaymentDetails(false);\n\t}, []);\n\n\tconst pricingMarginRight = !isEnterprise && 'mr-37.5';\n\treturn (\n\t\t<>\n\t\t\t{!isEnterprise && mode !== 'version' && (\n\t\t\t\t<div className=\"absolute top-3 right-4 md:right-12 flex flex-col items-end text-right\">\n\t\t\t\t\t<dt className=\"font-light\">{termMonths ? 'Monthly Price' : 'Total Price'}</dt>\n\t\t\t\t\t<dd className=\"font-bold\">\n\t\t\t\t\t\t{totalPrice > 0\n\t\t\t\t\t\t\t? (\n\t\t\t\t\t\t\t\t<span className=\"inline-flex items-baseline\">\n\t\t\t\t\t\t\t\t\t<PriceDisplay price={monthlyPrice} />\n\t\t\t\t\t\t\t\t\t{!!termMonths && (\n\t\t\t\t\t\t\t\t\t\t<span className=\"font-light text-base text-muted-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t/mo{termMonths > 1 && <sup>*</sup>}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t: <span className=\"text-4xl text-green\">Free</span>}\n\t\t\t\t\t</dd>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t<Form {...form}>\n\t\t\t\t{!confirmingPaymentDetails\n\t\t\t\t\t? (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t<h1 className={cx('text-lg leading-none text-foreground font-semibold mb-4', pricingMarginRight)}>\n\t\t\t\t\t\t\t\tCluster Configuration\n\t\t\t\t\t\t\t</h1>\n\t\t\t\t\t\t\t<div className={cx('mb-6 flex flex-col items-start gap-2', pricingMarginRight)}>\n\t\t\t\t\t\t\t\t<p className=\"sr-only\">Configure your Harper cluster and define deployment plans.</p>\n\t\t\t\t\t\t\t\t{!isEnterprise && mode !== 'version' && (\n\t\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t\t<Badge variant=\"warning\">Beta pricing subject to change.</Badge>\n\t\t\t\t\t\t\t\t\t\t{!!termMonths && termMonths > 1 && totalPrice > 0 && (\n\t\t\t\t\t\t\t\t\t\t\t<p className=\"max-w-prose text-xs font-light text-muted-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t\t* Billed as{' '}\n\t\t\t\t\t\t\t\t\t\t\t\t{new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(totalPrice)}{' '}\n\t\t\t\t\t\t\t\t\t\t\t\tevery{' '}\n\t\t\t\t\t\t\t\t\t\t\t\t{pluralize(termMonths, 'month', 'months')}, or sooner if you reach a usage limit — then a new\n\t\t\t\t\t\t\t\t\t\t\t\tlicense is issued.\n\t\t\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t<form\n\t\t\t\t\t\t\t\tid=\"cluster-upsert-form\"\n\t\t\t\t\t\t\t\tname=\"cluster-upsert-form\"\n\t\t\t\t\t\t\t\tonSubmit={form.handleSubmit(submitClusterDetailsForm)}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<ClusterDetails\n\t\t\t\t\t\t\t\t\tcalculatedNames={calculatedNames}\n\t\t\t\t\t\t\t\t\tclusterId={clusterId}\n\t\t\t\t\t\t\t\t\tdeploymentToPerformanceToPlan={deploymentToPerformanceToPlan}\n\t\t\t\t\t\t\t\t\tform={form}\n\t\t\t\t\t\t\t\t\tisPending={isCreatePending || isEditPending}\n\t\t\t\t\t\t\t\t\tharperVersions={harperVersions}\n\t\t\t\t\t\t\t\t\tmode={mode}\n\t\t\t\t\t\t\t\t\tpartialUpgrade={partialUpgrade}\n\t\t\t\t\t\t\t\t\tregionLocations={regionLocations}\n\t\t\t\t\t\t\t\t\tregionNameToLatencyToRegion={regionNameToLatencyToRegion}\n\t\t\t\t\t\t\t\t\tselectedDeployment={selectedDeployment}\n\t\t\t\t\t\t\t\t\tselectedPerformance={selectedPerformance}\n\t\t\t\t\t\t\t\t\tselectedPlan={selectedPlan}\n\t\t\t\t\t\t\t\t\ttotalPrice={totalPrice}\n\t\t\t\t\t\t\t\t\tisEnterprise={isEnterprise}\n\t\t\t\t\t\t\t\t\tcloudProvider={cloudProvider}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</form>\n\t\t\t\t\t\t</>\n\t\t\t\t\t)\n\t\t\t\t\t: (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t<h1 className={cx('text-lg leading-none text-foreground font-semibold mb-4', pricingMarginRight)}>\n\t\t\t\t\t\t\t\tCluster Billing\n\t\t\t\t\t\t\t</h1>\n\t\t\t\t\t\t\t<p className={cx('text-muted-foreground text-sm mb-2', pricingMarginRight)}>\n\t\t\t\t\t\t\t\tPlease confirm the following billing details:\n\t\t\t\t\t\t\t</p>\n\n\t\t\t\t\t\t\t<ClusterBilling\n\t\t\t\t\t\t\t\tclusterId={clusterId}\n\t\t\t\t\t\t\t\tisPending={isCreatePending || isEditPending}\n\t\t\t\t\t\t\t\tonGoBackToDetails={onGoBackToDetails}\n\t\t\t\t\t\t\t\tonSaveStateForBillingRedirect={onSaveStateForBillingRedirect}\n\t\t\t\t\t\t\t\tonSubmit={executeChangesToCluster}\n\t\t\t\t\t\t\t\torganizationId={organizationId}\n\t\t\t\t\t\t\t\tselectedPlan={selectedPlan}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</>\n\t\t\t\t\t)}\n\t\t\t</Form>\n\t\t</>\n\t);\n}\n","import { UpsertClusterSchemaType } from './upsertClusterSchema';\n\nexport function isUpsertClusterSchema(instance: unknown): instance is UpsertClusterSchemaType {\n\treturn (instance as UpsertClusterSchemaType)?.clusterName !== undefined;\n}\n","import { compareVersions } from '@/lib/string/wasAReleasedBeforeB';\n\nexport interface PartialUpgrade {\n\t/** The highest version reported across the cluster — the version lagging instances should reach. */\n\tlatest: string;\n\t/** How many instances are still on a version older than `latest`. */\n\tbehindCount: number;\n\t/** Total number of instances reporting a version. */\n\ttotal: number;\n}\n\n/**\n * Given the versions reported by a cluster's instances, detect whether the cluster is in a\n * partially-upgraded state — i.e. at least one instance is on an older version than the rest.\n *\n * This happens when an upgrade succeeds on some instances but fails on others: the failed instance\n * stays on the old version while the rest move to the target. The version picker treats the highest\n * version as \"current\" and offers nothing newer, so there is otherwise no way to re-run the upgrade\n * for the lagging instances.\n *\n * Returns the target version, how many instances are behind it, and the total reporting a version.\n * Returns null when the cluster is uniform (or fewer than two instances report a version), since\n * there is nothing to re-run.\n */\nexport function detectPartialUpgrade(versions: Array<string | undefined | null>): PartialUpgrade | null {\n\tconst reported = versions.filter((v): v is string => !!v);\n\tif (reported.length < 2) {\n\t\treturn null;\n\t}\n\tconst latest = reported.reduce((max, v) => compareVersions(v, max) > 0 ? v : max);\n\tconst behindCount = reported.filter(v => v !== latest).length;\n\treturn behindCount > 0 ? { latest, behindCount, total: reported.length } : null;\n}\n","import { ContactUs } from '@/components/ContactUs';\nimport { ErrorComponent } from '@/components/ErrorComponent';\nimport { Loading } from '@/components/Loading';\nimport { SubNavSimpleLayout } from '@/components/SubNavSimpleLayout';\nimport { isFailed, isTerminated } from '@/components/ui/utils/badgeStatus';\nimport { deletedClusterStatuses } from '@/config/clusterStatuses';\nimport { getPlanTypesOptions } from '@/features/cluster/queries/getPlanTypesQuery';\nimport { getHarperVersionsOptions, HarperVersionsResponse } from '@/features/clusters/queries/getHarperVersionsQuery';\nimport { getRegionLocationsOptions } from '@/features/clusters/queries/getRegionLocationsQuery';\nimport { useLocalStorage } from '@/hooks/useLocalStorage';\nimport { useOrganizationClusterPermissions } from '@/hooks/usePermissions';\nimport { SchemaPlan } from '@/integrations/api/api.gen';\nimport { Cluster, Organization } from '@/integrations/api/api.patch';\nimport { excludeFalsy } from '@/lib/arrays/excludeFalsy';\nimport { sortByField } from '@/lib/arrays/sort/byField';\nimport { byInstanceFqdnThenPort } from '@/lib/arrays/sort/byInstanceFqdnThenPort';\nimport { groupThenKeyBy } from '@/lib/groupThenKeyBy';\nimport { LocalStorageKeys } from '@/lib/storage/localStorageKeys';\nimport { compareVersions, wasAReleasedBeforeB } from '@/lib/string/wasAReleasedBeforeB';\nimport { useQuery } from '@tanstack/react-query';\nimport { useParams, useRouteContext } from '@tanstack/react-router';\nimport { useMemo } from 'react';\nimport { z } from 'zod';\nimport { ClusterForm } from './ClusterForm';\nimport { isUpsertClusterSchema } from './isUpsertClusterSchema';\nimport {\n\tcalculateDefaultDeploymentPerformanceAndRegionPlans,\n} from './lib/calculateDefaultDeploymentPerformanceAndRegionPlans';\nimport { detectPartialUpgrade } from './lib/detectPartialUpgrade';\nimport { UpsertClusterSchema, UpsertClusterSchemaType } from './upsertClusterSchema';\n\nexport function UpsertCluster() {\n\tconst { organizationId, clusterId, mode }: { organizationId: string; clusterId?: string; mode?: 'version' } =\n\t\tuseParams({ strict: false });\n\tconst { create, update } = useOrganizationClusterPermissions(organizationId);\n\tconst { organization, cluster }: {\n\t\torganization: Organization;\n\t\tcluster?: Cluster;\n\t} = useRouteContext({ strict: false });\n\tconst [savedClusterState, setSavedClusterState] = useLocalStorage<\n\t\t| null\n\t\t| ({\n\t\t\tclusterId?: string;\n\t\t} & (UpsertClusterSchemaType | Cluster))\n\t>(LocalStorageKeys.SavedClusterState, null);\n\n\tconst { data: planTypes } = useQuery(getPlanTypesOptions(organizationId));\n\tconst { data: regionLocationsColocated } = useQuery(getRegionLocationsOptions({\n\t\tavailableHosts: true,\n\t\torganizationId,\n\t}));\n\tconst { data: regionLocationsDedicated } = useQuery(getRegionLocationsOptions({ organizationId }));\n\n\tconst { data: newHarperVersions } = useQuery(getHarperVersionsOptions());\n\tconst harperVersions = useMemo(() => {\n\t\tif (cluster) {\n\t\t\tconst clusterVersions = cluster.instances?.map(i => i.version).filter(excludeFalsy);\n\t\t\tif (newHarperVersions && clusterVersions) {\n\t\t\t\tconst latestClusterVersion = clusterVersions.sort(compareVersions).pop();\n\t\t\t\treturn {\n\t\t\t\t\t...newHarperVersions,\n\t\t\t\t\tvalue: [\n\t\t\t\t\t\t!!latestClusterVersion && {\n\t\t\t\t\t\t\tname: 'current',\n\t\t\t\t\t\t\tversion: latestClusterVersion,\n\t\t\t\t\t\t} as const,\n\t\t\t\t\t\t...(newHarperVersions?.value || []).filter(v => {\n\t\t\t\t\t\t\t// Is our version unique from the latest cluster version?\n\t\t\t\t\t\t\treturn latestClusterVersion !== v.version\n\t\t\t\t\t\t\t\t// Do we have a cluster version?\n\t\t\t\t\t\t\t\t&& (!latestClusterVersion\n\t\t\t\t\t\t\t\t\t// Or if we do, have we updated to a higher version already?\n\t\t\t\t\t\t\t\t\t// This can prevent upgrading to, say, \"next\" v5, and then downgrading to the \"latest\" v4.\n\t\t\t\t\t\t\t\t\t|| wasAReleasedBeforeB(latestClusterVersion, v.version));\n\t\t\t\t\t\t}),\n\t\t\t\t\t].filter(excludeFalsy),\n\t\t\t\t} satisfies HarperVersionsResponse;\n\t\t\t}\n\t\t}\n\t\treturn newHarperVersions;\n\t}, [newHarperVersions, cluster]);\n\n\t// Detect a partially-upgraded cluster, where at least one instance failed to reach the version the\n\t// rest of the cluster is on. In that state the version picker pre-selects the latest version as\n\t// \"current\" and offers nothing newer, so the form can never become dirty — leaving no way to\n\t// re-run the upgrade for the lagging instances. We surface this so the form can allow re-submitting\n\t// the current target as a recovery path.\n\tconst partialUpgrade = useMemo(\n\t\t() => detectPartialUpgrade(cluster?.instances?.map(i => i.version) ?? []),\n\t\t[cluster],\n\t);\n\n\tconst alreadyUsingFree = useMemo(() => {\n\t\tfor (const orgCluster of organization?.clusters ?? []) {\n\t\t\tif (\n\t\t\t\torgCluster.id !== cluster?.id\n\t\t\t\t&& planTypes\n\t\t\t\t&& !isTerminated(orgCluster.status)\n\t\t\t\t&& !isFailed(orgCluster.status)\n\t\t\t\t&& orgCluster.plans\n\t\t\t) {\n\t\t\t\tfor (const clusterPlan of orgCluster.plans) {\n\t\t\t\t\tconst foundPlan = planTypes.find(p => p.id === clusterPlan.planId);\n\t\t\t\t\tif (foundPlan?.priceUsd === 0 && !foundPlan.id.startsWith('self-hosted')) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}, [cluster?.id, organization?.clusters, planTypes]);\n\n\tconst deploymentToPerformanceToPlan = useMemo<Record<string, Record<string, SchemaPlan>>>(\n\t\t() =>\n\t\t\tgroupThenKeyBy(planTypes?.sort(sortByField('priceUsd')) || [], 'deploymentDescription', 'performanceDescription'),\n\t\t[planTypes],\n\t);\n\n\tconst defaultValues = useMemo<null | UpsertClusterSchemaType>(() => {\n\t\tif (\n\t\t\t!planTypes || !harperVersions || !regionLocationsColocated || !regionLocationsDedicated || (clusterId && !cluster)\n\t\t) {\n\t\t\treturn null;\n\t\t}\n\n\t\tlet clusterToLoad = cluster;\n\n\t\tif (savedClusterState) {\n\t\t\tif (isUpsertClusterSchema(savedClusterState)) {\n\t\t\t\treturn {\n\t\t\t\t\t...savedClusterState,\n\t\t\t\t\tclusterName: savedClusterState.clusterName || '',\n\t\t\t\t\tabbreviatedName: savedClusterState.abbreviatedName || '',\n\t\t\t\t\tversion: savedClusterState.version,\n\t\t\t\t\tdeploymentDescription: savedClusterState.deploymentDescription || '',\n\t\t\t\t\tperformanceDescription: savedClusterState.performanceDescription || '',\n\t\t\t\t\tfqdn: savedClusterState.fqdn || '',\n\t\t\t\t\tregionPlans: savedClusterState.regionPlans || [],\n\t\t\t\t\tinstances: savedClusterState.instances || [],\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tclusterToLoad = savedClusterState;\n\t\t\t}\n\t\t}\n\n\t\tconst selectedPlan = planTypes?.find(planType => planType.id === cluster?.plans?.[0].planId);\n\n\t\tconst regionPlans: z.infer<typeof UpsertClusterSchema.shape.regionPlans> = [];\n\t\tconst instances: z.infer<typeof UpsertClusterSchema.shape.instances> = [];\n\t\tconst regionLocations = selectedPlan?.deploymentDescription !== 'Dedicated'\n\t\t\t? regionLocationsColocated\n\t\t\t: regionLocationsDedicated;\n\t\tconst defaults = calculateDefaultDeploymentPerformanceAndRegionPlans(planTypes, regionLocations, alreadyUsingFree);\n\n\t\tlet isSelfManaged = false;\n\t\tif (clusterToLoad) {\n\t\t\tif (clusterToLoad.plans) {\n\t\t\t\tfor (const plan of clusterToLoad.plans) {\n\t\t\t\t\tif (plan.regionId) {\n\t\t\t\t\t\tconst selectedRegion = regionLocations.find(regionLocation => regionLocation.id === plan.regionId);\n\t\t\t\t\t\tif (selectedRegion) {\n\t\t\t\t\t\t\tregionPlans.push({\n\t\t\t\t\t\t\t\tregionName: selectedRegion.region,\n\t\t\t\t\t\t\t\tlatencyDescription: selectedRegion.latencyDescription,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!regionPlans.length && clusterToLoad.instances) {\n\t\t\t\tconst clusterInstances = clusterToLoad.instances\n\t\t\t\t\t.filter(instance => instance.status && !deletedClusterStatuses.includes(instance.status))\n\t\t\t\t\t.sort(byInstanceFqdnThenPort);\n\t\t\t\tfor (const instance of clusterInstances) {\n\t\t\t\t\tisSelfManaged = true;\n\t\t\t\t\tinstances.push({\n\t\t\t\t\t\tfqdn: instance.instanceFqdn,\n\t\t\t\t\t\tport: instance.operationsApiPort,\n\t\t\t\t\t\tsecure: instance.operationsApiSecure ? 'true' : 'false',\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (defaults) {\n\t\t\tregionPlans.push(...defaults.regionPlans);\n\t\t}\n\t\tif (!isSelfManaged && !regionPlans.length) {\n\t\t\tregionPlans.push({ regionName: '', latencyDescription: '' });\n\t\t}\n\n\t\tconst version = harperVersions.value?.find(v => v.name === 'current')?.version\n\t\t\t?? harperVersions.value?.find(v => v.name === 'stable')?.version;\n\n\t\treturn {\n\t\t\tsourceClusterId: clusterToLoad?.id,\n\t\t\tautoRenew: clusterToLoad?.plans?.[0]?.autoRenew ?? true,\n\t\t\tclusterName: clusterToLoad?.name ?? '',\n\t\t\tabbreviatedName: clusterToLoad?.abbreviatedName ?? '',\n\t\t\tversion,\n\t\t\tdeploymentDescription: selectedPlan?.deploymentDescription ?? defaults?.deploymentDescription ?? '',\n\t\t\tperformanceDescription: selectedPlan?.performanceDescription ?? defaults?.performanceDescription ?? '',\n\t\t\tfqdn: isSelfManaged ? clusterToLoad?.fqdn ?? '' : '',\n\t\t\tinstances,\n\t\t\tregionPlans,\n\t\t};\n\t}, [\n\t\talreadyUsingFree,\n\t\tcluster,\n\t\tclusterId,\n\t\tplanTypes,\n\t\tharperVersions,\n\t\tregionLocationsColocated,\n\t\tregionLocationsDedicated,\n\t\tsavedClusterState,\n\t]);\n\n\tconst isLoading = !defaultValues || !organization || !planTypes || !regionLocationsColocated\n\t\t|| !regionLocationsDedicated;\n\tif (isLoading) {\n\t\treturn (\n\t\t\t<SubNavSimpleLayout>\n\t\t\t\t<Loading centered={true} text=\"Loading...\" />\n\t\t\t</SubNavSimpleLayout>\n\t\t);\n\t}\n\n\tif (cluster?.id ? !update : !create) {\n\t\treturn (\n\t\t\t<SubNavSimpleLayout>\n\t\t\t\t<ErrorComponent\n\t\t\t\t\ttitle={`Not Allowed`}\n\t\t\t\t\terror={{\n\t\t\t\t\t\tmessage: (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\tYou do not have permission to {cluster?.id ? 'update' : 'create'} clusters in this org.\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t),\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t</SubNavSimpleLayout>\n\t\t);\n\t}\n\n\tif (planTypes.length === 0) {\n\t\treturn (\n\t\t\t<SubNavSimpleLayout>\n\t\t\t\t<ErrorComponent\n\t\t\t\t\ttitle={`Cluster ${clusterId ? 'Modification' : 'Creation'} Not Currently Allowed`}\n\t\t\t\t\terror={{\n\t\t\t\t\t\tmessage: (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\tThere are no available deployment types right now! Please try again later, or <ContactUs />.\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t),\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t</SubNavSimpleLayout>\n\t\t);\n\t}\n\n\treturn (\n\t\t<SubNavSimpleLayout className=\"max-w-4xl mx-auto\">\n\t\t\t<ClusterForm\n\t\t\t\talreadyUsingFree={alreadyUsingFree}\n\t\t\t\tclusterId={clusterId}\n\t\t\t\tdefaultValues={defaultValues}\n\t\t\t\tdeploymentToPerformanceToPlan={deploymentToPerformanceToPlan}\n\t\t\t\tharperVersions={harperVersions}\n\t\t\t\tmode={mode}\n\t\t\t\torganization={organization}\n\t\t\t\torganizationId={organizationId}\n\t\t\t\tpartialUpgrade={partialUpgrade}\n\t\t\t\tplanTypes={planTypes}\n\t\t\t\tregionLocationsColocated={regionLocationsColocated}\n\t\t\t\tregionLocationsDedicated={regionLocationsDedicated}\n\t\t\t\tsetSavedClusterState={setSavedClusterState}\n\t\t\t\tstartOffOnBilling={isUpsertClusterSchema(savedClusterState) && savedClusterState.skipToBilling === true}\n\t\t\t/>\n\t\t</SubNavSimpleLayout>\n\t);\n}\n","import { Cluster } from '@/integrations/api/api.patch';\n\nconst statusPriority: Record<string, number> = {\n\t'FAILED': 0,\n\t'UPDATING': 1,\n\t'PROVISIONING': 2,\n\t'RUNNING': 3,\n\t'TERMINATED': 4,\n};\n\nconst DEFAULT_PRIORITY = statusPriority.RUNNING;\n\nexport function byClusterStatusThenName(a: Cluster, b: Cluster) {\n\tif (a.status === b.status) {\n\t\treturn a.name.localeCompare(b.name);\n\t}\n\n\tconst priorityA = a.status ? statusPriority[a.status] ?? DEFAULT_PRIORITY : DEFAULT_PRIORITY;\n\tconst priorityB = b.status ? statusPriority[b.status] ?? DEFAULT_PRIORITY : DEFAULT_PRIORITY;\n\treturn priorityA - priorityB;\n}\n","export function curryFilterByFuzzySearch<T>(fields: (keyof T)[], searchFor: string): (t: T) => boolean {\n\tconst searchForLower = searchFor.toLowerCase();\n\treturn (t: T) => {\n\t\tfor (const field of fields) {\n\t\t\tconst value = t[field];\n\t\t\tif (value === undefined || value === null) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (typeof value === 'string') {\n\t\t\t\tif (value.toLowerCase().includes(searchForLower)) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t} else if (typeof value === 'boolean') {\n\t\t\t\tif (value && (searchForLower === 'yes' || searchForLower === 'true' || searchForLower === '1')) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (!value && (searchForLower === 'no' || searchForLower === 'false' || searchForLower === '0')) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthrow new Error('curryFilterByFuzzySearch has not implemented support for ' + (typeof value) + ' fields yet!');\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t};\n}\n","import { SubNavMenu } from '@/components/SubNavMenu';\nimport { Button } from '@/components/ui/button';\nimport { Input } from '@/components/ui/input';\nimport { isTerminated } from '@/components/ui/utils/badgeStatus';\nimport { ClusterCard } from '@/features/clusters/components/ClusterCard';\nimport { UpsertCluster } from '@/features/clusters/upsert';\nimport { getOrganizationQueryOptions } from '@/features/organization/queries/getOrganizationQuery';\nimport { useLocalStorage } from '@/hooks/useLocalStorage';\nimport { useOrganizationClusterPermissions } from '@/hooks/usePermissions';\nimport { Cluster } from '@/integrations/api/api.patch';\nimport { byClusterStatusThenName } from '@/lib/arrays/sort/byClusterStatusThenName';\nimport { LocalStorageKeys } from '@/lib/storage/localStorageKeys';\nimport { curryFilterByFuzzySearch } from '@/lib/string/filterByFuzzySearch';\nimport { useSuspenseQuery } from '@tanstack/react-query';\nimport { Link, Navigate, useParams } from '@tanstack/react-router';\nimport { Plus } from 'lucide-react';\nimport { FormEvent, useCallback, useMemo, useState } from 'react';\n\nexport function ClustersList() {\n\tconst { organizationId }: { organizationId: string } = useParams({ strict: false });\n\tconst { create } = useOrganizationClusterPermissions(organizationId);\n\tconst { data: orgInfo, isSuccess } = useSuspenseQuery(getOrganizationQueryOptions(organizationId));\n\tconst [savedClusterState] = useLocalStorage<unknown | null>(LocalStorageKeys.SavedClusterState, null);\n\n\tconst [filterByNameValue, setFilterByNameValue] = useState('');\n\tconst clearFilterByNameValue = useCallback(() => setFilterByNameValue(''), []);\n\n\tconst onFilterByNameChanged = useCallback((e: FormEvent<HTMLInputElement>) => {\n\t\tsetFilterByNameValue(e.currentTarget.value?.toLowerCase() || '');\n\t}, []);\n\n\tconst runningClusters = useMemo(() =>\n\t\torgInfo?.clusters\n\t\t\t?.slice()\n\t\t\t.filter(cluster => !isTerminated(cluster.status))\n\t\t\t.sort(byClusterStatusThenName)\n\t\t|| [], [orgInfo?.clusters]);\n\n\tconst filteredClusters = useMemo(() =>\n\t\trunningClusters\n\t\t\t.filter(curryFilterByFuzzySearch<Cluster>(['id', 'name'], filterByNameValue))\n\t\t|| [], [filterByNameValue, runningClusters]);\n\n\tif (orgInfo && runningClusters.length === 0 && create) {\n\t\treturn <UpsertCluster />;\n\t}\n\tif (savedClusterState) {\n\t\treturn <Navigate to={`/${organizationId}/new-cluster`} />;\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t<SubNavMenu>\n\t\t\t\t{isSuccess\n\t\t\t\t\t? (\n\t\t\t\t\t\t<div className=\"flex w-full justify-end gap-2\">\n\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\tplaceholder=\"Filter by name\"\n\t\t\t\t\t\t\t\tclassName=\"inline-block w-full text-xs\"\n\t\t\t\t\t\t\t\tvalue={filterByNameValue}\n\t\t\t\t\t\t\t\tonChange={onFilterByNameChanged}\n\t\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t\t{create && (\n\t\t\t\t\t\t\t\t<Link to=\"new-cluster\">\n\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\tvariant=\"positive\"\n\t\t\t\t\t\t\t\t\t\taccessKey=\"n\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<Plus />{' '}\n\t\t\t\t\t\t\t\t\t\t<span className=\"hidden sm:inline-block\">\n\t\t\t\t\t\t\t\t\t\t\t<u>N</u>ew <span className=\"hidden md:inline-block\">Cluster</span>\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)\n\t\t\t\t\t: null}\n\t\t\t</SubNavMenu>\n\t\t\t<section className=\"mt-32 px-4 pt-4 md:px-12 min-h-[calc(100vh-(--spacing(32)))]\">\n\t\t\t\t<div className=\"grid grid-cols-1 gap-4 md:grid-cols-12 mb-4\">\n\t\t\t\t\t{filteredClusters.map((cluster) => (\n\t\t\t\t\t\t<div key={cluster.id} className=\"col-span-1 md:col-span-4 lg:col-span-3 2xl:col-span-2\">\n\t\t\t\t\t\t\t<ClusterCard cluster={cluster} />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t))}\n\t\t\t\t\t{!filteredClusters.length && (\n\t\t\t\t\t\t<div className=\"col-span-1 md:col-span-12 text-center\">\n\t\t\t\t\t\t\t<h2 className=\"my-4 text-xl\">No matches found.</h2>\n\t\t\t\t\t\t\t<Button type=\"button\" variant=\"outline\" onClick={clearFilterByNameValue}>Clear Filters</Button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t</section>\n\t\t</>\n\t);\n}\n","export function currentUrlAfterHash(): string {\n\tconst hash = location.hash;\n\tif (!hash) {\n\t\treturn '/';\n\t}\n\treturn hash.startsWith('#/') ? hash.slice(1) : hash;\n}\n","import { currentUrlAfterHash } from '@/lib/urls/currentUrlAfterHash';\n\nexport function currentUrlIncludingHash(): string {\n\treturn '/#' + currentUrlAfterHash();\n}\n","import { Loading } from '@/components/Loading';\nimport { useLocalStorage } from '@/hooks/useLocalStorage';\nimport { useProcessStripePaymentMethod } from '@/integrations/stripe/useProcessStripePaymentMethod';\nimport { LocalStorageKeys } from '@/lib/storage/localStorageKeys';\nimport { currentUrlIncludingHash } from '@/lib/urls/currentUrlIncludingHash';\nimport { useStripe } from '@stripe/react-stripe-js';\nimport { useNavigate, useParams, useSearch } from '@tanstack/react-router';\nimport { useCallback, useEffect } from 'react';\nimport { toast } from 'sonner';\n\nexport function ProcessSetupIntent() {\n\tconst { organizationId } = useParams({ strict: false });\n\tconst navigate = useNavigate();\n\tconst urlParams = new URLSearchParams(window.location.search);\n\tconst clientSecretBeforeHash = urlParams.get('setup_intent_client_secret');\n\tconst { setup_intent_client_secret: clientSecretAfterHash }: {\n\t\tsetup_intent_client_secret?: string;\n\t} = useSearch({ strict: false });\n\tconst [savedClusterState] = useLocalStorage<\n\t\t{\n\t\t\tclusterId?: string;\n\t\t} & unknown | null\n\t>(LocalStorageKeys.SavedClusterState, null);\n\tconst clientSecret = clientSecretBeforeHash || clientSecretAfterHash;\n\n\tconst stripe = useStripe();\n\tconst processStripePaymentMethod = useProcessStripePaymentMethod(organizationId);\n\tconst navigateBack = useCallback(() => {\n\t\tconst to = savedClusterState\n\t\t\t? savedClusterState.clusterId\n\t\t\t\t? `../../${savedClusterState.clusterId}/edit`\n\t\t\t\t: '../../new-cluster'\n\t\t\t: '../';\n\t\twindow.history.replaceState(null, '', currentUrlIncludingHash());\n\t\tvoid navigate({ search: undefined, to });\n\t}, [navigate, savedClusterState]);\n\n\tuseEffect(() => {\n\t\tif (!stripe || !clientSecret || !processStripePaymentMethod || !organizationId || !navigateBack) {\n\t\t\treturn;\n\t\t}\n\n\t\t(async function() {\n\t\t\ttry {\n\t\t\t\tconst { setupIntent } = await stripe.retrieveSetupIntent(clientSecret);\n\t\t\t\tswitch (setupIntent?.status) {\n\t\t\t\t\tcase 'succeeded':\n\t\t\t\t\t\tif (setupIntent.payment_method !== null) {\n\t\t\t\t\t\t\tprocessStripePaymentMethod(setupIntent.payment_method, navigateBack);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttoast.error('Failed to process payment method details. Please try another payment method.');\n\t\t\t\t\t\t\tnavigateBack();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'processing':\n\t\t\t\t\t\ttoast.warning('Processing payment method. Please check back later.');\n\t\t\t\t\t\tnavigateBack();\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'requires_payment_method':\n\t\t\t\t\t\ttoast.error('Failed to process payment method details. Please try another payment method.');\n\t\t\t\t\t\tnavigateBack();\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\ttoast.error('Failed to process payment method details. Please try another payment method.');\n\t\t\t\t\t\tnavigateBack();\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(err);\n\t\t\t\ttoast.error('Failed to process payment method details. Please try another payment method.');\n\t\t\t\tnavigateBack();\n\t\t\t}\n\t\t})();\n\t}, [clientSecret, navigateBack, organizationId, processStripePaymentMethod, stripe]);\n\n\treturn <Loading centered />;\n}\n","import { ProcessSetupIntent } from '@/features/organization/billing/confirm/ProcessSetupIntent';\nimport { StripeWrapper } from '@/integrations/stripe/StripeContext';\n\nexport function ConfirmSetupIntent() {\n\treturn (\n\t\t<StripeWrapper>\n\t\t\t<ProcessSetupIntent />\n\t\t</StripeWrapper>\n\t);\n}\n","import { excludeFalsy } from '@/lib/arrays/excludeFalsy';\n\nexport function buildAbsoluteLinkToPage({\n\tclusterId,\n\tinstanceId,\n\torganizationId,\n}: {\n\tclusterId?: string;\n\tinstanceId?: string;\n\torganizationId?: string;\n}, page?: string): string {\n\treturn '/' + [\n\t\torganizationId,\n\t\tclusterId,\n\t\tinstanceId && 'instance',\n\t\tinstanceId,\n\t\tpage,\n\t].filter(excludeFalsy).join('/');\n}\n","import { SubNavMenu } from '@/components/SubNavMenu';\nimport { useOrganizationPermissions } from '@/hooks/usePermissions';\nimport { buildAbsoluteLinkToPage } from '@/lib/urls/buildAbsoluteLinkToPage';\nimport { Link, Outlet, useParams } from '@tanstack/react-router';\nimport { CreditCardIcon, ReceiptIcon, ReceiptTextIcon } from 'lucide-react';\n\nconst sharedClasses = 'flex items-center p-2 rounded-lg group';\nconst inactiveProps = { className: 'text-foreground hover:bg-accent dark:text-white dark:hover:bg-gray-700' };\nconst activeProps = { className: 'text-black bg-white pointer-events-none cursor-default' };\n\nexport function OrgBillingIndex() {\n\tconst { organizationId } = useParams({ strict: false });\n\tconst { update } = useOrganizationPermissions(organizationId);\n\n\tif (!update) {\n\t\treturn (\n\t\t\t<div className=\"mt-32 px-4 pt-4 md:px-12 min-h-[calc(100vh-theme(spacing.32))]\">\n\t\t\t\tYou don't have access to manage payments for this organization. Please contact your administrator.\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t<SubNavMenu />\n\t\t\t<div className=\"mt-32 px-4 pt-4 md:px-12 min-h-[calc(100vh-theme(spacing.32))]\">\n\t\t\t\t<div className=\"md:grid gap-4 md:grid-cols-12 min-h-[calc(100vh-theme(spacing.36))] mb-12\">\n\t\t\t\t\t<section className=\"col-span-1 text-foreground md:col-span-4 lg:col-span-3 md:border-r-1 border-b md:border-b-0 md:pr-4 border-gray-700\">\n\t\t\t\t\t\t<DesktopBillingNavBar />\n\t\t\t\t\t\t<MobileBillingNavBar />\n\t\t\t\t\t</section>\n\t\t\t\t\t<section className=\"col-span-1 text-foreground md:col-span-8 lg:col-span-9\">\n\t\t\t\t\t\t<Outlet />\n\t\t\t\t\t</section>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</>\n\t);\n}\n\nfunction DesktopBillingNavBar() {\n\tconst params = useParams({ strict: false });\n\treturn (\n\t\t<div className=\"hidden md:block\">\n\t\t\t<span className={sharedClasses}>\n\t\t\t\t<ReceiptIcon className=\"inline-block\" />\n\t\t\t\t<h3 className=\"ms-3 text-2xl font-extrabold text-foreground\">Billing</h3>\n\t\t\t</span>\n\n\t\t\t<ul className=\"border-t border-gray-700 pt-4 mt-4 space-y-2\">\n\t\t\t\t<li>\n\t\t\t\t\t<Link\n\t\t\t\t\t\tto={buildAbsoluteLinkToPage(params, 'billing')}\n\t\t\t\t\t\tclassName={sharedClasses}\n\t\t\t\t\t\tactiveOptions={{ exact: true }}\n\t\t\t\t\t\tinactiveProps={inactiveProps}\n\t\t\t\t\t\tactiveProps={activeProps}\n\t\t\t\t\t>\n\t\t\t\t\t\t<CreditCardIcon className=\"inline-block\" /> <span className=\"ms-3\">Payment Method</span>\n\t\t\t\t\t</Link>\n\t\t\t\t</li>\n\t\t\t\t<li>\n\t\t\t\t\t<Link\n\t\t\t\t\t\tto={buildAbsoluteLinkToPage(params, 'billing/invoices')}\n\t\t\t\t\t\tclassName={sharedClasses}\n\t\t\t\t\t\tinactiveProps={inactiveProps}\n\t\t\t\t\t\tactiveProps={activeProps}\n\t\t\t\t\t>\n\t\t\t\t\t\t<ReceiptTextIcon className=\"inline-block\" />\n\t\t\t\t\t\t<span className=\"ms-3\">Invoices &amp; Payments</span>\n\t\t\t\t\t</Link>\n\t\t\t\t</li>\n\t\t\t</ul>\n\t\t</div>\n\t);\n}\n\nfunction MobileBillingNavBar() {\n\tconst params = useParams({ strict: false });\n\treturn (\n\t\t<ul className=\"flex space-x-4 md:hidden py-2\">\n\t\t\t<li>\n\t\t\t\t<Link\n\t\t\t\t\tto={buildAbsoluteLinkToPage(params, 'billing')}\n\t\t\t\t\tclassName={sharedClasses}\n\t\t\t\t\tactiveOptions={{ exact: true }}\n\t\t\t\t\tinactiveProps={inactiveProps}\n\t\t\t\t\tactiveProps={activeProps}\n\t\t\t\t>\n\t\t\t\t\t<CreditCardIcon className=\"inline-block\" /> <span className=\"ms-3\">Payment Method</span>\n\t\t\t\t</Link>\n\t\t\t</li>\n\t\t\t<li>\n\t\t\t\t<Link\n\t\t\t\t\tto={buildAbsoluteLinkToPage(params, 'billing/invoices')}\n\t\t\t\t\tclassName={sharedClasses}\n\t\t\t\t\tinactiveProps={inactiveProps}\n\t\t\t\t\tactiveProps={activeProps}\n\t\t\t\t>\n\t\t\t\t\t<ReceiptTextIcon className=\"inline-block\" /> <span className=\"ms-3\">Invoices &amp; Payments</span>\n\t\t\t\t</Link>\n\t\t\t</li>\n\t\t</ul>\n\t);\n}\n","import { Button } from '@/components/ui/button';\nimport { cn } from '@/lib/cn';\nimport { flexRender, Header, RowData } from '@tanstack/react-table';\nimport { ArrowDown, ArrowUp, ArrowUpDown, GripVerticalIcon } from 'lucide-react';\nimport * as React from 'react';\nimport { useCallback } from 'react';\n\nexport interface TableProps extends React.ComponentProps<'table'> {\n\tcontainerClassName?: string;\n}\n\nexport function Table({ className, containerClassName, ...props }: TableProps) {\n\treturn (\n\t\t<div data-slot=\"table-container\" className={cn('relative w-full overflow-x-auto', containerClassName)}>\n\t\t\t<table data-slot=\"table\" className={cn('w-full caption-bottom text-sm', className)} {...props} />\n\t\t</div>\n\t);\n}\n\nexport function TableHeader({ className, ...props }: React.ComponentProps<'thead'>) {\n\treturn <thead data-slot=\"table-header\" className={cn('[&_tr]:border-b', className)} {...props} />;\n}\n\nexport function TableBody({ className, ...props }: React.ComponentProps<'tbody'>) {\n\treturn <tbody data-slot=\"table-body\" className={cn('[&_tr:last-child]:border-0', className)} {...props} />;\n}\n\nexport function TableFooter({ className, ...props }: React.ComponentProps<'tfoot'>) {\n\treturn (\n\t\t<tfoot\n\t\t\tdata-slot=\"table-footer\"\n\t\t\tclassName={cn('bg-muted/50 border-t font-medium [&>tr]:last:border-b-0', className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport function TableRow({ className, ...props }: React.ComponentProps<'tr'>) {\n\treturn (\n\t\t<tr\n\t\t\tdata-slot=\"table-row\"\n\t\t\tclassName={cn('border-b border-grey-700 transition-colors', className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport function TableHead({ className, ...props }: React.ComponentProps<'th'>) {\n\treturn (\n\t\t<th\n\t\t\tdata-slot=\"table-head\"\n\t\t\tclassName={cn(\n\t\t\t\t'h-10 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport function TableHeadSortable<TData extends RowData>({\n\theader,\n\tonColumnClick,\n\t...props\n}: React.ComponentProps<'th'> & {\n\theader: Header<TData, unknown>;\n\tonColumnClick?: (accessorKey: string, willSortByAscending: boolean) => void;\n}) {\n\tconst onClickSort = useCallback(() => {\n\t\theader.column.toggleSorting(header.column.getIsSorted() === 'asc');\n\t\tconst willSortByAscending = header.column.getIsSorted() === false || header.column.getIsSorted() !== 'asc';\n\t\t// @ts-expect-error The accessorKey isn't accessible.\n\t\tonColumnClick?.(header.column.columnDef.accessorKey, willSortByAscending);\n\t}, [header, onColumnClick]);\n\tconst enableSorting = header.column.columnDef.enableSorting;\n\tconst enableResizing = header.column.columnDef.enableResizing;\n\tconst content = header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext());\n\tconst resetSize = useCallback(() => {\n\t\theader.column.resetSize();\n\t}, [header]);\n\treturn (\n\t\t<TableHead\n\t\t\t{...props}\n\t\t\tstyle={{ width: `${header.getSize()}px` }}\n\t\t\tclassName={enableSorting ? 'px-0' : 'px-2'}\n\t\t>\n\t\t\t<div className=\"flex items-center justify-between\">\n\t\t\t\t{enableSorting\n\t\t\t\t\t? (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t'rounded-none',\n\t\t\t\t\t\t\t\t!header.column.getIsSorted() || header.column.getIsSorted() === 'asc'\n\t\t\t\t\t\t\t\t\t? 'cursor-n-resize'\n\t\t\t\t\t\t\t\t\t: 'cursor-s-resize',\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\tonClick={onClickSort}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{content}\n\t\t\t\t\t\t\t{header.column.getIsSorted() === 'asc'\n\t\t\t\t\t\t\t\t? <ArrowUp />\n\t\t\t\t\t\t\t\t: header.column.getIsSorted() === 'desc'\n\t\t\t\t\t\t\t\t? <ArrowDown />\n\t\t\t\t\t\t\t\t: <ArrowUpDown className=\"text-gray-600\" />}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t)\n\t\t\t\t\t: content}\n\t\t\t\t{enableResizing && (\n\t\t\t\t\t<Button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tclassName=\"cursor-col-resize\"\n\t\t\t\t\t\tonMouseDown={header.getResizeHandler()} // for desktop\n\t\t\t\t\t\tonTouchStart={header.getResizeHandler()} // for mobile\n\t\t\t\t\t\tonDoubleClick={resetSize}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\ttransform: header.column.getIsResizing()\n\t\t\t\t\t\t\t\t? `translateX(${header.getContext().table.getState().columnSizingInfo.deltaOffset}px)`\n\t\t\t\t\t\t\t\t: '',\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<GripVerticalIcon />\n\t\t\t\t\t</Button>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</TableHead>\n\t);\n}\n\nexport function TableCell({ className, ...props }: React.ComponentProps<'td'>) {\n\treturn (\n\t\t<td\n\t\t\tdata-slot=\"table-cell\"\n\t\t\tclassName={cn(\n\t\t\t\t'align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport function TableCaption({ className, ...props }: React.ComponentProps<'caption'>) {\n\treturn (\n\t\t<caption data-slot=\"table-caption\" className={cn('text-muted-foreground mt-4 text-sm', className)} {...props} />\n\t);\n}\n","'use client';\n\nimport { Loading } from '@/components/Loading';\n\nimport { Table, TableBody, TableCell, TableHeader, TableHeadSortable, TableRow } from '@/components/ui/table';\nimport { cn } from '@/lib/cn';\nimport {\n\tColumnDef,\n\tflexRender,\n\tgetCoreRowModel,\n\tgetSortedRowModel,\n\tPaginationState,\n\tRow,\n\tSortingState,\n\tuseReactTable,\n} from '@tanstack/react-table';\nimport React, { Dispatch, SetStateAction } from 'react';\n\ninterface BrowseDataTableProps<TData, TValue> {\n\tcolumns: ColumnDef<TData, TValue>[];\n\tdata: TData[];\n\tisFetching?: boolean;\n\ttotalPages?: number;\n\ttotalRecords?: number;\n\tonRowClick?: (row: Row<TData>) => void;\n\tonColumnClick?: (accessorKey: string, isDescending: boolean) => void;\n\tpaginationState?: {\n\t\tpageIndex: number;\n\t\tpageSize: number;\n\t};\n\tsortingState?: SortingState;\n\tsetPagination?: Dispatch<SetStateAction<PaginationState>>;\n\tchildren?: React.ReactNode;\n}\n\nexport function SimpleBrowseDataTable<TData, TValue>({\n\tcolumns,\n\tdata,\n\tisFetching,\n\tonRowClick,\n\tonColumnClick,\n\tsortingState,\n\tchildren,\n}: BrowseDataTableProps<TData, TValue>) {\n\tconst table = useReactTable({\n\t\tdata,\n\t\tcolumns,\n\t\tgetCoreRowModel: getCoreRowModel(),\n\t\tgetSortedRowModel: getSortedRowModel(),\n\t\tinitialState: {\n\t\t\tsorting: sortingState,\n\t\t},\n\t});\n\n\treturn (\n\t\t<>\n\t\t\t<div className=\"flex items-center justify-end space-x-2 pb-4\">\n\t\t\t\t<div className=\"grow lg:hidden\"></div>\n\t\t\t\t{children}\n\t\t\t\t<div className=\"grow hidden lg:visible\"></div>\n\t\t\t</div>\n\t\t\t<Table containerClassName=\"rounded-md bg-card dark:bg-black-dark\">\n\t\t\t\t<TableHeader>\n\t\t\t\t\t{table.getHeaderGroups().map((headerGroup) => (\n\t\t\t\t\t\t<TableRow key={headerGroup.id} className=\"border-none\">\n\t\t\t\t\t\t\t{headerGroup.headers.map((header) => (\n\t\t\t\t\t\t\t\t<TableHeadSortable key={header.id} header={header} onColumnClick={onColumnClick} />\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</TableRow>\n\t\t\t\t\t))}\n\t\t\t\t</TableHeader>\n\t\t\t\t<TableBody className=\"bg-background dark:bg-black border border-border dark:border-grey-700\">\n\t\t\t\t\t{table.getRowModel().rows?.length\n\t\t\t\t\t\t? (table.getRowModel().rows.map((row) => (\n\t\t\t\t\t\t\t<TableRow\n\t\t\t\t\t\t\t\tkey={row.id}\n\t\t\t\t\t\t\t\tdata-state={row.getIsSelected() && 'selected'}\n\t\t\t\t\t\t\t\tonClick={() => onRowClick?.(row)}\n\t\t\t\t\t\t\t\tclassName={cn('hover:bg-muted/10 data-[state=selected]:bg-muted', onRowClick && 'cursor-pointer')}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{row.getVisibleCells().map((cell) => (\n\t\t\t\t\t\t\t\t\t<TableCell\n\t\t\t\t\t\t\t\t\t\tkey={cell.id}\n\t\t\t\t\t\t\t\t\t\tclassName=\"py-2 px-2 overflow-x-hidden max-w-32 text-ellipsis whitespace-nowrap\"\n\t\t\t\t\t\t\t\t\t\tstyle={{ width: `${cell.column.getSize()}px` }}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{flexRender(cell.column.columnDef.cell, cell.getContext())}\n\t\t\t\t\t\t\t\t\t</TableCell>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</TableRow>\n\t\t\t\t\t\t)))\n\t\t\t\t\t\t: (\n\t\t\t\t\t\t\t<TableRow>\n\t\t\t\t\t\t\t\t<TableCell colSpan={columns.length} className=\"h-24 text-center\">\n\t\t\t\t\t\t\t\t\t{isFetching\n\t\t\t\t\t\t\t\t\t\t? (\n\t\t\t\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t\t\t\t<Loading className=\"p-12\" />\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t: <span>No results.</span>}\n\t\t\t\t\t\t\t\t</TableCell>\n\t\t\t\t\t\t\t</TableRow>\n\t\t\t\t\t\t)}\n\t\t\t\t</TableBody>\n\t\t\t</Table>\n\t\t</>\n\t);\n}\n","import { BadgeStatusVariantValues } from '@/components/ui/utils/badgeStatus';\n\nexport function translateStripeStatusToVariant(status?: string): BadgeStatusVariantValues {\n\tswitch (status) {\n\t\tcase 'paid':\n\t\t\treturn 'success';\n\t\tcase 'void':\n\t\tcase 'uncollectible':\n\t\t\treturn 'destructive';\n\t\tcase 'draft':\n\t\tcase 'open':\n\t\tdefault:\n\t\t\treturn 'default';\n\t}\n}\n","export function toUSD(input: number): string {\n\treturn new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(input);\n}\n","export function translateSecondsToAgo(secondsElapsed: number, timeMs: number): string {\n\t// Note: I used the boundaries that moment.js uses.\n\tif (secondsElapsed < 45) {\n\t\treturn 'a few seconds ago';\n\t}\n\tif (secondsElapsed < 120) {\n\t\treturn 'a minute ago';\n\t}\n\tconst minutesElapsed = Math.floor(secondsElapsed / 60);\n\tif (minutesElapsed < 60) {\n\t\treturn `${minutesElapsed} minutes ago`;\n\t}\n\tif (minutesElapsed < 120) {\n\t\treturn 'an hour ago';\n\t}\n\tconst hoursElapsed = Math.floor(secondsElapsed / 3600);\n\tif (hoursElapsed > 48) {\n\t\treturn new Date(timeMs).toLocaleString();\n\t}\n\treturn `${hoursElapsed} hours ago`;\n}\n","import { Badge } from '@/components/ui/badge';\nimport { SchemaInvoice, SchemaInvoiceLine } from '@/integrations/api/api.gen';\nimport { translateStripeStatusToVariant } from '@/integrations/stripe/translateStripeStatusToVariant';\nimport { toUSD } from '@/lib/toUSD';\nimport { translateSecondsToAgo } from '@/lib/translateSecondsToAgo';\nimport { ColumnDef } from '@tanstack/react-table';\n\nexport const dataTableColumns: Array<ColumnDef<SchemaInvoice>> = [\n\t{\n\t\theader: 'Invoice Id',\n\t\taccessorKey: 'id',\n\t\tenableSorting: false,\n\t},\n\t{\n\t\theader: 'Status',\n\t\taccessorKey: 'status',\n\t\tenableSorting: false,\n\t\tcell: ({ cell }) => (\n\t\t\t<Badge variant={translateStripeStatusToVariant(cell.getValue<string>())}>{cell.getValue<string>()}</Badge>\n\t\t),\n\t},\n\t{\n\t\theader: 'Date',\n\t\taccessorKey: 'periodStart',\n\t\tenableSorting: false,\n\t\tcell: ({ cell }) => {\n\t\t\tconst periodStart = cell.row.original.periodStart * 1000;\n\t\t\tconst periodEnd = cell.row.original.periodEnd * 1000;\n\t\t\tconst secondsSinceStart = (Date.now() - periodStart) / 1000;\n\t\t\tconst secondsSinceEnd = (Date.now() - periodEnd) / 1000;\n\t\t\tif (Math.abs(secondsSinceStart - secondsSinceEnd) < 1000) {\n\t\t\t\treturn translateSecondsToAgo(secondsSinceStart, periodStart);\n\t\t\t}\n\t\t\treturn [\n\t\t\t\tperiodStart ? translateSecondsToAgo(secondsSinceStart, periodStart) : '-',\n\t\t\t\tperiodEnd ? translateSecondsToAgo(secondsSinceEnd, periodEnd) : '-',\n\t\t\t].join(' to ');\n\t\t},\n\t},\n\t{\n\t\theader: 'Amount Due',\n\t\taccessorKey: 'amountDue',\n\t\tenableSorting: false,\n\t\tcell: ({ cell }) => toUSD(cell.getValue<number>() ? cell.getValue<number>() / 100 : 0),\n\t},\n\t{\n\t\theader: 'Amount Paid',\n\t\taccessorKey: 'amountPaid',\n\t\tenableSorting: false,\n\t\tcell: ({ cell }) => toUSD(cell.getValue<number>() ? cell.getValue<number>() / 100 : 0),\n\t},\n\t{\n\t\theader: 'Lines',\n\t\taccessorKey: 'lines',\n\t\tenableSorting: false,\n\t\tcell: ({ cell }) => {\n\t\t\tconst invoiceLines = cell.getValue<SchemaInvoiceLine[]>();\n\t\t\tconst formattedLines: string[] = [];\n\t\t\tfor (const invoiceLine of invoiceLines) {\n\t\t\t\tformattedLines.push(`${invoiceLine.quantity}x ${invoiceLine.description} @ ${toUSD(invoiceLine.amount / 100)}`);\n\t\t\t}\n\t\t\treturn formattedLines.join('\\n');\n\t\t},\n\t},\n];\n","import { sleep } from '@/lib/sleep';\nimport { useCallback } from 'react';\nimport { toast } from 'sonner';\n\nexport function useRefreshClick(refetch: () => Promise<unknown>) {\n\treturn useCallback(async () => {\n\t\ttoast.loading('Refreshing...', { id: 'refreshing' });\n\t\tconst startedAt = Date.now();\n\t\tawait refetch();\n\t\tif (Date.now() - startedAt < 500) {\n\t\t\tawait sleep(500);\n\t\t}\n\t\ttoast.success('Refreshed!', { id: 'refreshing' });\n\t}, [refetch]);\n}\n","import { apiClient } from '@/config/apiClient';\nimport { SchemaInvoice } from '@/integrations/api/api.gen';\nimport { queryOptions } from '@tanstack/react-query';\n\nexport async function getStripeInvoices(organizationId: string): Promise<SchemaInvoice[]> {\n\tconst { data } = await apiClient.get(`/Invoice/${organizationId}` as `/Invoice/{id}`);\n\t// TODO: The API isn't able to describe this array result accurately yet.\n\treturn data as unknown as SchemaInvoice[];\n}\n\nexport function getStripeInvoicesQueryOptions(organizationId: string | undefined | false, refetch?: boolean) {\n\treturn queryOptions({\n\t\tqueryKey: [organizationId, 'invoices'],\n\t\tqueryFn: () => getStripeInvoices(organizationId as string),\n\t\tretry: false,\n\t\tenabled: !!organizationId,\n\t\trefetchInterval: refetch ? 10000 : undefined,\n\t});\n}\n","import { ContactUs } from '@/components/ContactUs';\nimport { Loading } from '@/components/Loading';\nimport { SimpleBrowseDataTable } from '@/components/SimpleBrowseDataTable';\nimport { Button } from '@/components/ui/button';\nimport { dataTableColumns } from '@/features/organization/billing/invoices/constants/tableDefinition';\nimport { getOrganizationQueryOptions } from '@/features/organization/queries/getOrganizationQuery';\nimport { useRefreshClick } from '@/hooks/useRefreshClick';\nimport { ENTERPRISE } from '@/integrations/api/orgType';\nimport { getStripeInvoicesQueryOptions } from '@/integrations/stripe/useGetStripeInvoices';\nimport { useQuery } from '@tanstack/react-query';\nimport { useParams } from '@tanstack/react-router';\nimport { RefreshCwIcon } from 'lucide-react';\n\nexport function Invoices() {\n\tconst { organizationId } = useParams({ strict: false });\n\tconst { data: organization } = useQuery(getOrganizationQueryOptions(organizationId));\n\tconst {\n\t\tdata,\n\t\trefetch,\n\t\tisLoading,\n\t\tisFetching,\n\t\tisRefetching,\n\t} = useQuery(getStripeInvoicesQueryOptions(organization?.type !== ENTERPRISE && organization?.id, false));\n\n\tconst onRefreshClick = useRefreshClick(refetch);\n\n\tif (organization?.type === ENTERPRISE) {\n\t\treturn (\n\t\t\t<span>\n\t\t\t\tYou are part of an enterprise organization! We don&rsquo;t currently show your invoices on this page. Want to\n\t\t\t\texplore your solution with Harper more? <ContactUs />, we would love to talk!\n\t\t\t</span>\n\t\t);\n\t}\n\tif (isLoading) {\n\t\treturn <Loading centered />;\n\t}\n\tif (!data || !data.length) {\n\t\treturn (\n\t\t\t<span>\n\t\t\t\tYour invoices will be shown here once one is available! Want to explore your solution with Harper more?{' '}\n\t\t\t\t<ContactUs overEmail={true} />, we would love to talk!\n\t\t\t</span>\n\t\t);\n\t}\n\treturn (\n\t\t<SimpleBrowseDataTable data={data} columns={dataTableColumns}>\n\t\t\t<Button variant=\"defaultOutline\" onClick={onRefreshClick} accessKey=\"r\" disabled={isFetching || isRefetching}>\n\t\t\t\t<RefreshCwIcon />\n\t\t\t\t<span className=\"hidden lg:inline-block\">\n\t\t\t\t\t<u>R</u>efresh\n\t\t\t\t</span>\n\t\t\t</Button>\n\t\t</SimpleBrowseDataTable>\n\t);\n}\n","import type { orgLayoutRoute } from '@/features/organization/routes';\nimport { createRoute } from '@tanstack/react-router';\nimport { ConfirmSetupIntent } from './confirm/ConfirmSetupIntent';\nimport { OrgBillingIndex } from './index';\nimport { Invoices } from './invoices/Invoices';\nimport { PaymentMethodsDisplay } from './paymentMethod/PaymentMethodsDisplay';\n\nexport function createBillingRouteTree(parentRoute: typeof orgLayoutRoute) {\n\tconst rootRoute = createRoute({\n\t\tgetParentRoute: () => parentRoute,\n\t\tpath: 'billing',\n\t\thead: () => ({ meta: [{ title: 'Billing — Harper Fabric' }] }),\n\t\tcomponent: OrgBillingIndex,\n\t});\n\tconst paymentMethodsRoute = createRoute({\n\t\tgetParentRoute: () => rootRoute,\n\t\tpath: '/',\n\t\thead: () => ({ meta: [{ title: 'Payment Methods — Harper Fabric' }] }),\n\t\tcomponent: PaymentMethodsDisplay,\n\t});\n\tconst invoicesRoute = createRoute({\n\t\tgetParentRoute: () => rootRoute,\n\t\tpath: 'invoices',\n\t\thead: () => ({ meta: [{ title: 'Invoices — Harper Fabric' }] }),\n\t\tcomponent: Invoices,\n\t});\n\tconst confirmRoute = createRoute({\n\t\tgetParentRoute: () => rootRoute,\n\t\tpath: 'confirm',\n\t\thead: () => ({ meta: [{ title: 'Confirm Payment — Harper Fabric' }] }),\n\t\tcomponent: ConfirmSetupIntent,\n\t});\n\n\treturn rootRoute.addChildren([\n\t\tpaymentMethodsRoute,\n\t\tinvoicesRoute,\n\t\tconfirmRoute,\n\t]);\n}\n","import { apiClient } from '@/config/apiClient';\nimport { SchemaOrganizationRole } from '@/integrations/api/api.gen';\nimport { queryOptions } from '@tanstack/react-query';\n\nasync function getOrganizationRoles(organizationId: string): Promise<SchemaOrganizationRole[]> {\n\tconst { data } = await apiClient.get(`/OrganizationRole/${organizationId}` as '/OrganizationRole/'); // TODO: The API is not describing itself accurately.\n\treturn data;\n}\n\nexport function getOrganizationRolesQueryOptions(organizationId: string) {\n\treturn queryOptions({\n\t\tqueryKey: [organizationId, 'roles'],\n\t\tqueryFn: () => getOrganizationRoles(organizationId),\n\t\tretry: false,\n\t\trefetchInterval: 10 * 1000, // 10 seconds\n\t});\n}\n","import { SchemaOrganizationRole } from '@/integrations/api/api.gen';\nimport { ColumnDef, createColumnHelper } from '@tanstack/react-table';\n\nconst columnHelper = createColumnHelper<SchemaOrganizationRole>();\n\nexport const dataTableColumns: Array<ColumnDef<SchemaOrganizationRole>> = [\n\t{\n\t\theader: 'Role Name',\n\t\taccessorKey: 'roleName',\n\t\tenableSorting: false,\n\t},\n\tcolumnHelper.display({\n\t\theader: 'Users Assigned',\n\t\tenableSorting: false,\n\t\tid: 'userIds',\n\t\tcell: (props) => {\n\t\t\tif (!props.row.original.userIds || props.row.original.userIds.length === 0) {\n\t\t\t\treturn 'No users assigned';\n\t\t\t}\n\t\t\treturn props.row.original.userIds.length;\n\t\t},\n\t}),\n];\n","import { apiClient } from '@/config/apiClient';\nimport { useMutation } from '@tanstack/react-query';\nimport { OrganizationRoleUpdatePayloadType } from './OrganizationRoleFormSchema';\n\nexport async function onAddOrganizationRoleSubmit(formData: OrganizationRoleUpdatePayloadType) {\n\tconst { data } = await apiClient.post('/Role/', formData);\n\treturn data;\n}\n\nexport function useAddOrganizationRole() {\n\treturn useMutation({\n\t\tmutationFn: onAddOrganizationRoleSubmit,\n\t});\n}\n","import { z } from 'zod';\n\nexport const OrganizationRoleOverviewSchema = z.object({\n\tname: z\n\t\t.string()\n\t\t.nonempty({\n\t\t\terror: 'Please enter a role name.',\n\t\t})\n\t\t.regex(/^[a-zA-Z_]*$/, {\n\t\t\terror: 'Role must contain only letters and underscores.',\n\t\t})\n\t\t.max(30, { error: 'Role name cannot be longer than 30 characters.' }),\n\tupdate: z.boolean(),\n\tdelete: z.boolean(),\n});\n\nexport const OrganizationRoleSpecificPermissionsSchema = z.object({\n\troles: z.object({\n\t\tcreate: z.boolean(),\n\t\tdelete: z.boolean(),\n\t\tupdate: z.boolean(),\n\t\tview: z.boolean(),\n\t}),\n\tclusters: z.object({\n\t\tcreate: z.boolean(),\n\t\tdelete: z.boolean(),\n\t\tupdate: z.boolean(),\n\t\tview: z.boolean(),\n\t\tresources: z.array(z.object({\n\t\t\tid: z.string(),\n\t\t\tdelete: z.boolean(),\n\t\t\tupdate: z.boolean(),\n\t\t\tview: z.boolean(),\n\t\t\tinstances: z.object({\n\t\t\t\tcreate: z.boolean(),\n\t\t\t\tdelete: z.boolean(),\n\t\t\t\tupdate: z.boolean(),\n\t\t\t\tview: z.boolean(),\n\t\t\t}),\n\t\t})),\n\t}),\n});\n\nexport type OrganizationRoleUpdatePayloadType =\n\t& z.infer<typeof OrganizationRoleOverviewSchema>\n\t& z.infer<typeof OrganizationRoleSpecificPermissionsSchema>\n\t& { organizationId: string };\n\nexport type OrganizationRoleOverviewType = z.infer<typeof OrganizationRoleOverviewSchema>;\nexport type OrganizationRoleSpecificPermissionsType = z.infer<typeof OrganizationRoleSpecificPermissionsSchema>;\n","import { useSystemTheme } from '@/hooks/useSystemTheme';\nimport { useTheme } from '@/hooks/useTheme';\n\n/** Returns the Monaco Editor theme string matching the current Studio theme. */\nexport function useMonacoTheme(): 'vs-dark' | 'light' {\n\tconst [theme] = useTheme();\n\tconst systemTheme = useSystemTheme();\n\tconst isDark = theme === 'dark' || (theme === 'system' && systemTheme === 'dark');\n\treturn isDark ? 'vs-dark' : 'light';\n}\n","import type { EditorProps } from '@monaco-editor/react';\nimport { lazy, Suspense } from 'react';\n\n/**\n * Lazy, self-hosted Monaco editor.\n *\n * `@/lib/monaco/setup` pulls in monaco-editor (~860 KB gzip) and points\n * `@monaco-editor/react` at the bundled instance instead of the CDN. Importing\n * it here — behind `React.lazy` rather than statically from `main.tsx` — keeps\n * Monaco out of the initial bundle; it loads the first time an editor renders.\n *\n * `setup` has side effects (`MonacoEnvironment` + `loader.config`) that must run\n * before `<Editor>` calls `loader.init()`, so we await it before resolving the\n * real component.\n *\n * Use this instead of importing `Editor` from `@monaco-editor/react` directly so\n * the bundler never links Monaco into an eager chunk. Types (`EditorProps`,\n * `OnMount`, …) are erased at build time and can still be imported directly.\n */\nconst LazyEditor = lazy(async () => {\n\tawait import('@/lib/monaco/setup');\n\t// `@monaco-editor/react` exports the editor as its default export (its named\n\t// `Editor` export is not guaranteed across versions/bundler configs).\n\tconst monacoReact = await import('@monaco-editor/react');\n\treturn { default: monacoReact.default };\n});\n\nexport function MonacoEditor(props: EditorProps) {\n\treturn (\n\t\t<Suspense fallback={props.loading ?? null}>\n\t\t\t<LazyEditor {...props} />\n\t\t</Suspense>\n\t);\n}\n\nexport default MonacoEditor;\nexport { MonacoEditor as Editor };\n","import { Button } from '@/components/ui/button';\nimport { Dialog, DialogContent, DialogDescription, DialogFooter, DialogTitle } from '@/components/ui/dialog';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { useAddOrganizationRole } from '@/features/organization/mutations/addOrganizationRole';\nimport {\n\tOrganizationRoleOverviewSchema,\n\tOrganizationRoleOverviewType,\n\tOrganizationRoleSpecificPermissionsType,\n\tOrganizationRoleUpdatePayloadType,\n} from '@/features/organization/mutations/OrganizationRoleFormSchema';\nimport { useMonacoTheme } from '@/hooks/useMonacoTheme';\nimport { Editor } from '@/lib/monaco/MonacoEditor';\nimport { safeParse } from '@/lib/string/safeParse';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { useParams } from '@tanstack/react-router';\nimport { useCallback, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\n\nconst defaultPermissions: OrganizationRoleSpecificPermissionsType = {\n\troles: {\n\t\tcreate: true,\n\t\tview: true,\n\t\tupdate: true,\n\t\tdelete: true,\n\t},\n\tclusters: {\n\t\tcreate: true,\n\t\tview: true,\n\t\tupdate: true,\n\t\tdelete: true,\n\t\tresources: [],\n\t},\n};\n\nexport function AddOrganizationRoleModal({\n\tisModalOpen,\n\tsetIsModalOpen,\n}: {\n\tisModalOpen: boolean;\n\tsetIsModalOpen: (isOpen: boolean) => void;\n}) {\n\tconst monacoTheme = useMonacoTheme();\n\tconst queryClient = useQueryClient();\n\tconst { organizationId }: { organizationId: string } = useParams({ strict: false });\n\tconst [isValidJSON, setIsValidJSON] = useState(true);\n\tconst [updatedPermissions, setUpdatedPermissions] = useState<string>(JSON.stringify(defaultPermissions, null, 2));\n\n\tconst { mutate: addOrganizationRole, isPending } = useAddOrganizationRole();\n\n\tconst form = useForm({\n\t\tresolver: zodResolver(OrganizationRoleOverviewSchema),\n\t\tdefaultValues: {\n\t\t\tname: '',\n\t\t\tupdate: false,\n\t\t\tdelete: false,\n\t\t},\n\t});\n\n\tconst onValidate = useCallback(\n\t\t(markers: unknown[]) => {\n\t\t\tsetIsValidJSON(markers.length === 0);\n\t\t},\n\t\t[setIsValidJSON],\n\t);\n\n\tconst onSubmitRoleEdits = useCallback(\n\t\tasync (formData: OrganizationRoleOverviewType) => {\n\t\t\tconst parsedPermissions = safeParse<OrganizationRoleSpecificPermissionsType>(updatedPermissions);\n\t\t\tif (!parsedPermissions) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst updatedFormData: OrganizationRoleUpdatePayloadType = {\n\t\t\t\t...formData,\n\t\t\t\t...parsedPermissions,\n\t\t\t\torganizationId: organizationId,\n\t\t\t};\n\t\t\tif (formData && isValidJSON) {\n\t\t\t\taddOrganizationRole(updatedFormData, {\n\t\t\t\t\tonSuccess: () => {\n\t\t\t\t\t\ttoast.success('Organization role added successfully!');\n\t\t\t\t\t\tsetIsModalOpen(false);\n\t\t\t\t\t\tvoid queryClient.invalidateQueries({\n\t\t\t\t\t\t\tqueryKey: [organizationId, 'roles'],\n\t\t\t\t\t\t\trefetchType: 'active',\n\t\t\t\t\t\t});\n\t\t\t\t\t\tform.reset();\n\t\t\t\t\t},\n\t\t\t\t\tonError: (error: Error) => {\n\t\t\t\t\t\ttoast.error(`Failed to add organization role: ${error.message}`);\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\t[isValidJSON, updatedPermissions, addOrganizationRole, form, queryClient, setIsModalOpen, organizationId],\n\t);\n\n\treturn (\n\t\t<Dialog onOpenChange={setIsModalOpen} open={isModalOpen}>\n\t\t\t<DialogContent>\n\t\t\t\t<DialogTitle>Add New Organization Role</DialogTitle>\n\t\t\t\t<DialogDescription>Set the new organization role permissions.</DialogDescription>\n\t\t\t\t<Form {...form}>\n\t\t\t\t\t<form\n\t\t\t\t\t\tid=\"org-add-role-form\"\n\t\t\t\t\t\tname=\"org-add-role-form\"\n\t\t\t\t\t\tclassName=\"grid grid-cols-2 gap-4 my-4\"\n\t\t\t\t\t\tonSubmit={form.handleSubmit(onSubmitRoleEdits)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"name\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem className=\"col-span-2\">\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Role Name</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Input type=\"text\" className=\"\" {...field} />\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"update\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Can Update Organization</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"w-6 ml-2\"\n\t\t\t\t\t\t\t\t\t\t\tchecked={field.value}\n\t\t\t\t\t\t\t\t\t\t\tonChange={(e) => field.onChange(e.target.checked)}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"delete\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Can Delete Organization</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"w-6 ml-2\"\n\t\t\t\t\t\t\t\t\t\t\tchecked={field.value}\n\t\t\t\t\t\t\t\t\t\t\tonChange={(e) => field.onChange(e.target.checked)}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<div className=\"col-span-2\">\n\t\t\t\t\t\t\t<Editor\n\t\t\t\t\t\t\t\ttheme={monacoTheme}\n\t\t\t\t\t\t\t\theight=\"300px\"\n\t\t\t\t\t\t\t\tdefaultLanguage=\"json\"\n\t\t\t\t\t\t\t\tonValidate={onValidate}\n\t\t\t\t\t\t\t\tonChange={(value) => {\n\t\t\t\t\t\t\t\t\tif (value) {\n\t\t\t\t\t\t\t\t\t\tsetUpdatedPermissions(value);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\tdefaultValue={JSON.stringify(defaultPermissions, null, 2)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<DialogFooter className=\"col-span-2\">\n\t\t\t\t\t\t\t<div className=\"flex justify-between w-full\">\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tvariant=\"destructiveOutline\"\n\t\t\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tonClick={() => setIsModalOpen(false)}\n\t\t\t\t\t\t\t\t\tdisabled={isPending}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tvariant=\"submit\"\n\t\t\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\t\t\tdisabled={isPending || !isValidJSON || !form.formState.isValid}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tSave Changes\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</DialogFooter>\n\t\t\t\t\t</form>\n\t\t\t\t</Form>\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n}\n","import { apiClient } from '@/config/apiClient';\nimport { useMutation } from '@tanstack/react-query';\n\nexport async function onDeleteOrganizationRole({ roleId }: { roleId: string }) {\n\tconst { data } = await apiClient.delete(`/Role/${roleId}` as '/Role/{id}', {\n\t\t// @ts-expect-error would love to figure this out\n\t\tid: roleId,\n\t\tdeleted: true,\n\t});\n\treturn data;\n}\n\nexport function useDeleteOrganizationRole() {\n\treturn useMutation<unknown, Error, { roleId: string }>({\n\t\tmutationFn: ({ roleId }: { roleId: string }) => onDeleteOrganizationRole({ roleId }),\n\t});\n}\n","import { apiClient } from '@/config/apiClient';\nimport { SchemaRole } from '@/integrations/api/api.gen';\nimport { useMutation } from '@tanstack/react-query';\nimport { OrganizationRoleUpdatePayloadType } from './OrganizationRoleFormSchema';\n\ninterface UpdateOrganizationRoleParams {\n\troleId: string;\n\tupdatedRoleInfo: OrganizationRoleUpdatePayloadType;\n}\n\nexport async function onUpdateOrganizationRole({\n\troleId,\n\tupdatedRoleInfo,\n}: UpdateOrganizationRoleParams) {\n\tconst { data } = await apiClient.put(`/Role/${roleId}` as '/Role/{id}', updatedRoleInfo);\n\treturn data as SchemaRole;\n}\n\nexport function useUpdateOrganizationRole() {\n\treturn useMutation<\n\t\tSchemaRole,\n\t\tError,\n\t\tUpdateOrganizationRoleParams\n\t>({\n\t\tmutationFn: ({ roleId, updatedRoleInfo }: UpdateOrganizationRoleParams) =>\n\t\t\tonUpdateOrganizationRole({ roleId, updatedRoleInfo }),\n\t});\n}\n","import { apiClient } from '@/config/apiClient';\nimport { SchemaRole } from '@/integrations/api/api.gen';\nimport { queryOptions } from '@tanstack/react-query';\n\nexport interface GetOrganizationRoleInfoResponse extends SchemaRole {\n\tname: string;\n\torganizationId: string;\n}\n\nexport function getOrganizationRoleInfoQueryOptions({\n\torganizationId,\n\troleId,\n}: {\n\torganizationId: string;\n\troleId: string;\n}) {\n\treturn queryOptions({\n\t\tqueryKey: [organizationId, 'roles', roleId] as const,\n\t\tqueryFn: () => getOrganizationRoleInfo(roleId),\n\t\trefetchInterval: 10 * 1000,\n\t});\n}\n\nexport async function getOrganizationRoleInfo(roleId?: string) {\n\tconst { data } = await apiClient.get(`/Role/${roleId}` as '/Role/{id}');\n\treturn data as GetOrganizationRoleInfoResponse;\n}\n","import { Button } from '@/components/ui/button';\nimport { DialogDescription, DialogFooter, DialogTitle } from '@/components/ui/dialog';\n\nexport function ConfirmDeletionContent({\n\tonRoleDeleteClick,\n\tsetIsConfirmingRoleDeletion,\n\tisRoleDeletionPending,\n}: {\n\tonRoleDeleteClick: () => void;\n\tsetIsConfirmingRoleDeletion: (isOpen: boolean) => void;\n\tisRoleDeletionPending: boolean;\n}) {\n\treturn (\n\t\t<>\n\t\t\t<DialogTitle>Confirm Role Deletion</DialogTitle>\n\t\t\t<DialogDescription>Are you sure you want to delete this role? This action cannot be undone.</DialogDescription>\n\t\t\t<DialogFooter>\n\t\t\t\t<Button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tvariant=\"defaultOutline\"\n\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\tonClick={() => setIsConfirmingRoleDeletion(false)}\n\t\t\t\t>\n\t\t\t\t\tCancel\n\t\t\t\t</Button>\n\t\t\t\t<Button\n\t\t\t\t\tvariant=\"destructiveOutline\"\n\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\tonClick={onRoleDeleteClick}\n\t\t\t\t\tdisabled={isRoleDeletionPending}\n\t\t\t\t>\n\t\t\t\t\t{isRoleDeletionPending ? 'Deleting...' : 'Delete Role'}\n\t\t\t\t</Button>\n\t\t\t</DialogFooter>\n\t\t</>\n\t);\n}\n","import { Button } from '@/components/ui/button';\nimport { Dialog, DialogContent, DialogFooter, DialogTitle } from '@/components/ui/dialog';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { useDeleteOrganizationRole } from '@/features/organization/mutations/deleteOrganizationRole';\nimport {\n\tOrganizationRoleOverviewSchema,\n\tOrganizationRoleOverviewType,\n\tOrganizationRoleSpecificPermissionsType,\n\tOrganizationRoleUpdatePayloadType,\n} from '@/features/organization/mutations/OrganizationRoleFormSchema';\nimport { useUpdateOrganizationRole } from '@/features/organization/mutations/updateOrganizationRole';\nimport { getOrganizationRoleInfoQueryOptions } from '@/features/organization/queries/getOrganizationRoleInfo';\nimport { useCloudAuth } from '@/hooks/useAuth';\nimport { useMonacoTheme } from '@/hooks/useMonacoTheme';\nimport { useOrganizationRolePermissions } from '@/hooks/usePermissions';\nimport { SchemaOrganizationRole } from '@/integrations/api/api.gen';\nimport { Editor } from '@/lib/monaco/MonacoEditor';\nimport { safeParse } from '@/lib/string/safeParse';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useQueryClient, useSuspenseQuery } from '@tanstack/react-query';\nimport { useCallback, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { ConfirmDeletionContent } from './ConfirmDeletionContent';\n\nexport function EditOrganizationRoleModal({\n\tdata,\n\tisModalOpen,\n\tcloseModal,\n}: {\n\tdata: SchemaOrganizationRole;\n\tisModalOpen: boolean;\n\tcloseModal: (madeChanges: boolean) => void;\n}) {\n\tconst queryClient = useQueryClient();\n\tconst { data: roleInfo } = useSuspenseQuery(\n\t\tgetOrganizationRoleInfoQueryOptions({ roleId: data.id, organizationId: data.organizationId }),\n\t);\n\tconst auth = useCloudAuth();\n\tconst isSelf = auth.user && auth.user?.roles?.[data.organizationId]?.role === data.roleName;\n\tconst { update, remove } = useOrganizationRolePermissions(data.organizationId);\n\tconst { mutate: updateOrganizationRole, isPending: isRoleUpdatePending } = useUpdateOrganizationRole();\n\tconst { mutate: deleteOrganizationRole, isPending: isRoleDeletionPending } = useDeleteOrganizationRole();\n\n\tconst monacoTheme = useMonacoTheme();\n\tconst [isConfirmingRoleDeletion, setIsConfirmingRoleDeletion] = useState(false);\n\n\tconst form = useForm({\n\t\tresolver: zodResolver(OrganizationRoleOverviewSchema),\n\t\tdefaultValues: {\n\t\t\tname: data.roleName,\n\t\t\tupdate: roleInfo.organization.update || false,\n\t\t\tdelete: roleInfo.organization.delete || false,\n\t\t},\n\t});\n\n\tconst onRoleDeleteClick = useCallback(() => {\n\t\tdeleteOrganizationRole(\n\t\t\t{ roleId: data.id },\n\t\t\t{\n\t\t\t\tonSuccess: () => {\n\t\t\t\t\ttoast.success('Role deleted successfully!');\n\t\t\t\t\tcloseModal(true);\n\t\t\t\t\tform.reset();\n\t\t\t\t},\n\t\t\t\tonError: (error: Error | unknown) => {\n\t\t\t\t\ttoast.error('Error', {\n\t\t\t\t\t\tdescription: `Failed to delete role: ${error instanceof Error ? error.message : String(error)}.`,\n\t\t\t\t\t\taction: {\n\t\t\t\t\t\t\tlabel: 'Dismiss',\n\t\t\t\t\t\t\tonClick: () => toast.dismiss(),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t}, [data.id, deleteOrganizationRole, form, closeModal]);\n\n\tconst [isValidJSON, setIsValidJSON] = useState(true);\n\tconst [updatedPermissions, setUpdatedPermissions] = useState<string>(\n\t\tJSON.stringify(\n\t\t\t{\n\t\t\t\troles: { ...roleInfo.organization.roles },\n\t\t\t\tclusters: { ...roleInfo.organization.clusters },\n\t\t\t} satisfies OrganizationRoleSpecificPermissionsType,\n\t\t\tnull,\n\t\t\t2,\n\t\t),\n\t);\n\n\tconst onValidate = useCallback(\n\t\t(markers: unknown[]) => {\n\t\t\tsetIsValidJSON(markers.length === 0);\n\t\t},\n\t\t[setIsValidJSON],\n\t);\n\n\tconst onSubmitRoleEdits = useCallback(\n\t\tasync (formData: OrganizationRoleOverviewType) => {\n\t\t\tif (!update) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst parsedPermissions = safeParse<OrganizationRoleSpecificPermissionsType>(updatedPermissions);\n\t\t\tif (!parsedPermissions) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst updatedFormData: OrganizationRoleUpdatePayloadType = {\n\t\t\t\t...formData,\n\t\t\t\t...parsedPermissions,\n\t\t\t\torganizationId: data.organizationId,\n\t\t\t};\n\n\t\t\tif (updatedPermissions && isValidJSON) {\n\t\t\t\tupdateOrganizationRole(\n\t\t\t\t\t{\n\t\t\t\t\t\troleId: data.id,\n\t\t\t\t\t\tupdatedRoleInfo: updatedFormData,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tonSuccess: async () => {\n\t\t\t\t\t\t\ttoast.success('Role updated successfully!');\n\t\t\t\t\t\t\tawait queryClient.invalidateQueries({\n\t\t\t\t\t\t\t\tqueryKey: [data.organizationId, 'roles', data.id],\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tcloseModal(false);\n\t\t\t\t\t\t\tform.reset();\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonError: (error: Error | unknown) => {\n\t\t\t\t\t\t\ttoast.error('Error', {\n\t\t\t\t\t\t\t\tdescription: `Failed to update role: ${error instanceof Error ? error.message : String(error)}.`,\n\t\t\t\t\t\t\t\taction: {\n\t\t\t\t\t\t\t\t\tlabel: 'Dismiss',\n\t\t\t\t\t\t\t\t\tonClick: () => toast.dismiss(),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\t[\n\t\t\tcloseModal,\n\t\t\tdata.id,\n\t\t\tdata.organizationId,\n\t\t\tform,\n\t\t\tisValidJSON,\n\t\t\tqueryClient,\n\t\t\troleInfo,\n\t\t\tupdate,\n\t\t\tupdatedPermissions,\n\t\t\tupdateOrganizationRole,\n\t\t],\n\t);\n\n\tconst onOpenChanges = useCallback(() => closeModal(false), [closeModal]);\n\n\treturn (\n\t\t<Dialog onOpenChange={onOpenChanges} open={isModalOpen}>\n\t\t\t<DialogContent>\n\t\t\t\t{isConfirmingRoleDeletion\n\t\t\t\t\t? (\n\t\t\t\t\t\t<ConfirmDeletionContent\n\t\t\t\t\t\t\tonRoleDeleteClick={onRoleDeleteClick}\n\t\t\t\t\t\t\tsetIsConfirmingRoleDeletion={setIsConfirmingRoleDeletion}\n\t\t\t\t\t\t\tisRoleDeletionPending={isRoleDeletionPending}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)\n\t\t\t\t\t: (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t<DialogTitle>{isSelf || !update ? 'View' : 'Edit'} Organization Role \"{data.roleName}\"</DialogTitle>\n\t\t\t\t\t\t\t<Form {...form}>\n\t\t\t\t\t\t\t\t<form\n\t\t\t\t\t\t\t\t\tid=\"org-edit-role-form\"\n\t\t\t\t\t\t\t\t\tname=\"org-edit-role-form\"\n\t\t\t\t\t\t\t\t\tclassName=\"grid grid-cols-2 gap-4 my-4\"\n\t\t\t\t\t\t\t\t\tonSubmit={form.handleSubmit(onSubmitRoleEdits)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\t\t\t\tname=\"name\"\n\t\t\t\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t\t\t\t<FormItem className=\"col-span-2\">\n\t\t\t\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Role Name</FormLabel>\n\t\t\t\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdisabled={true}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\treadOnly={true}\n\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\t\t\t\tname=\"update\"\n\t\t\t\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Can Update Organization</FormLabel>\n\t\t\t\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"w-6 ml-2\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdisabled={isSelf || !update}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\treadOnly={isSelf || !update}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tchecked={field.value}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tonChange={(e) => field.onChange(e.target.checked)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\t\t\t\tname=\"delete\"\n\t\t\t\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Can Delete Organization</FormLabel>\n\t\t\t\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"w-6 ml-2\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdisabled={isSelf || !update}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\treadOnly={isSelf || !update}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tchecked={field.value}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tonChange={(e) => field.onChange(e.target.checked)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t<div className=\"col-span-2\">\n\t\t\t\t\t\t\t\t\t\t<Editor\n\t\t\t\t\t\t\t\t\t\t\ttheme={monacoTheme}\n\t\t\t\t\t\t\t\t\t\t\theight=\"300px\"\n\t\t\t\t\t\t\t\t\t\t\tdefaultLanguage=\"json\"\n\t\t\t\t\t\t\t\t\t\t\tonValidate={onValidate}\n\t\t\t\t\t\t\t\t\t\t\tonChange={(value) => {\n\t\t\t\t\t\t\t\t\t\t\t\tif (value) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tsetUpdatedPermissions(value);\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\toptions={isSelf || !update ? { readOnly: true } : undefined}\n\t\t\t\t\t\t\t\t\t\t\tdefaultValue={updatedPermissions}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t{(!isSelf && (remove || update)) && (\n\t\t\t\t\t\t\t\t\t\t<DialogFooter className=\"col-span-2\">\n\t\t\t\t\t\t\t\t\t\t\t<div className=\"flex justify-between w-full\">\n\t\t\t\t\t\t\t\t\t\t\t\t{remove && (\n\t\t\t\t\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tvariant=\"destructiveOutline\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tonClick={() => setIsConfirmingRoleDeletion(true)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdisabled={isRoleUpdatePending}\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tDelete Role\n\t\t\t\t\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t{update && (\n\t\t\t\t\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tvariant=\"submit\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdisabled={!isValidJSON || isRoleUpdatePending || !form.formState.isValid\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t|| !form.formState.isDirty}\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tSave Changes\n\t\t\t\t\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t</DialogFooter>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</form>\n\t\t\t\t\t\t\t</Form>\n\t\t\t\t\t\t</>\n\t\t\t\t\t)}\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n}\n","import { Loading } from '@/components/Loading';\nimport { SimpleBrowseDataTable } from '@/components/SimpleBrowseDataTable';\nimport { SubNavMenu } from '@/components/SubNavMenu';\nimport { Button } from '@/components/ui/button';\nimport { getOrganizationRolesQueryOptions } from '@/features/organization/queries/getOrganizationRoles';\nimport { useOrganizationRolePermissions } from '@/hooks/usePermissions';\nimport { useRefreshClick } from '@/hooks/useRefreshClick';\nimport { SchemaOrganizationRole } from '@/integrations/api/api.gen';\nimport { useQueryClient, useSuspenseQuery } from '@tanstack/react-query';\nimport { useNavigate, useParams } from '@tanstack/react-router';\nimport { Row } from '@tanstack/react-table';\nimport { PlusIcon, RefreshCwIcon } from 'lucide-react';\nimport { Suspense, useCallback, useMemo, useState } from 'react';\nimport { dataTableColumns } from './constants/tableDefinition';\nimport { AddOrganizationRoleModal } from './modals/AddOrganizationRoleModal';\nimport { EditOrganizationRoleModal } from './modals/EditOrganizationRoleModal';\n\nexport function OrgConfigRolesIndex() {\n\tconst navigate = useNavigate();\n\tconst queryClient = useQueryClient();\n\n\tconst { organizationId, orgRoleId }: { organizationId: string; orgRoleId?: string } = useParams({ strict: false });\n\tconst { create } = useOrganizationRolePermissions(organizationId);\n\n\tconst {\n\t\tdata: orgRoles,\n\t\trefetch,\n\t\tisFetching,\n\t\tisRefetching,\n\t} = useSuspenseQuery(getOrganizationRolesQueryOptions(organizationId));\n\n\tconst selectedOrgRole = useMemo(\n\t\t() => orgRoles && orgRoles?.find((role) => role.id === orgRoleId),\n\t\t[orgRoles, orgRoleId],\n\t);\n\n\tconst isEditOrgRoleModalOpen = !!orgRoleId && !!selectedOrgRole;\n\n\tconst [isAddModalOpen, setIsAddModalOpen] = useState(false);\n\n\tconst onSelectOrgRole = useCallback(\n\t\tasync (newOrgRole: string | undefined, madeChanges: boolean) => {\n\t\t\tconst parts = [orgRoleId ? '..' : '', newOrgRole].filter(Boolean);\n\t\t\tawait navigate({ to: parts.join('/') });\n\t\t\tif (madeChanges) {\n\t\t\t\tawait queryClient.invalidateQueries({\n\t\t\t\t\tqueryKey: [organizationId, 'roles'],\n\t\t\t\t\trefetchType: 'active',\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\t[orgRoleId, navigate, queryClient],\n\t);\n\n\tconst onAddClicked = useCallback(() => {\n\t\tsetIsAddModalOpen(true);\n\t}, [setIsAddModalOpen]);\n\n\tconst onRowClick = useCallback(\n\t\t(rowData: Row<SchemaOrganizationRole>) => {\n\t\t\treturn onSelectOrgRole(rowData.original.id, false);\n\t\t},\n\t\t[onSelectOrgRole],\n\t);\n\n\tconst closeEditModal = useCallback((madeChanges: boolean) => {\n\t\treturn onSelectOrgRole(undefined, madeChanges);\n\t}, [onSelectOrgRole]);\n\n\tconst onRefreshClick = useRefreshClick(refetch);\n\n\treturn (\n\t\t<>\n\t\t\t<SubNavMenu />\n\t\t\t<div className=\"mt-32 px-4 pt-4 md:px-12 min-h-[calc(100vh-(--spacing(32)))]\">\n\t\t\t\t<Suspense fallback={<Loading className=\"flex flex-col items-center justify-center h-full\" text=\"Loading...\" />}>\n\t\t\t\t\t<SimpleBrowseDataTable data={orgRoles} columns={dataTableColumns} onRowClick={onRowClick}>\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tvariant=\"defaultOutline\"\n\t\t\t\t\t\t\tonClick={onRefreshClick}\n\t\t\t\t\t\t\taccessKey=\"r\"\n\t\t\t\t\t\t\tdisabled={isFetching || isRefetching}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<RefreshCwIcon />\n\t\t\t\t\t\t\t<span className=\"hidden lg:inline-block\">\n\t\t\t\t\t\t\t\t<u>R</u>efresh\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t{create && (\n\t\t\t\t\t\t\t<Button variant=\"positiveOutline\" onClick={onAddClicked} accessKey=\"a\" disabled={isAddModalOpen}>\n\t\t\t\t\t\t\t\t<PlusIcon />\n\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t<u>A</u>dd\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</SimpleBrowseDataTable>\n\t\t\t\t\t{create && (\n\t\t\t\t\t\t<AddOrganizationRoleModal\n\t\t\t\t\t\t\tisModalOpen={isAddModalOpen}\n\t\t\t\t\t\t\tsetIsModalOpen={setIsAddModalOpen}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t\t{isEditOrgRoleModalOpen && (\n\t\t\t\t\t\t<EditOrganizationRoleModal\n\t\t\t\t\t\t\tdata={selectedOrgRole}\n\t\t\t\t\t\t\tisModalOpen={isEditOrgRoleModalOpen}\n\t\t\t\t\t\t\tcloseModal={closeEditModal}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</Suspense>\n\t\t\t</div>\n\t\t</>\n\t);\n}\n","import { cn } from '@/lib/cn';\nimport * as SwitchPrimitive from '@radix-ui/react-switch';\nimport * as React from 'react';\n\nfunction Switch({\n\tclassName,\n\t...props\n}: React.ComponentProps<typeof SwitchPrimitive.Root>) {\n\treturn (\n\t\t<SwitchPrimitive.Root\n\t\t\tdata-slot=\"switch\"\n\t\t\tclassName={cn(\n\t\t\t\t'peer '\n\t\t\t\t\t+ 'data-[state=checked]:bg-green '\n\t\t\t\t\t+ 'data-[state=unchecked]:bg-input '\n\t\t\t\t\t+ 'focus-visible:border-ring '\n\t\t\t\t\t+ 'focus-visible:ring-ring/50 '\n\t\t\t\t\t+ 'dark:data-[state=unchecked]:bg-grey-500 inline-flex '\n\t\t\t\t\t+ 'h-[1.15rem] w-8 shrink-0 '\n\t\t\t\t\t+ 'items-center rounded-full '\n\t\t\t\t\t+ 'border border-transparent '\n\t\t\t\t\t+ 'shadow-xs '\n\t\t\t\t\t+ 'transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<SwitchPrimitive.Thumb\n\t\t\t\tdata-slot=\"switch-thumb\"\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'bg-white dark:data-[state=unchecked]:bg-white dark:data-[state=checked]:bg-white '\n\t\t\t\t\t\t+ 'pointer-events-none '\n\t\t\t\t\t\t+ 'block size-4 rounded-full ring-0 '\n\t\t\t\t\t\t+ 'transition-transform '\n\t\t\t\t\t\t+ 'data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0',\n\t\t\t\t)}\n\t\t\t/>\n\t\t</SwitchPrimitive.Root>\n\t);\n}\n\nexport { Switch };\n","/**\n * Direct link to the central-manager OAuth login endpoint for a per-org OAuth\n * provider (e.g. Okta), identified by its `oac-…` config id.\n *\n * This is the same URL surfaced to admins on the org settings page. We link\n * straight to it rather than routing through an SPA page that appends\n * `?redirect=…`: that query param gets folded into the OAuth `redirect_uri`\n * sent to the provider, which then no longer matches the registered Login\n * redirect URI and the provider rejects the request (Okta 400 \"redirect_uri\").\n */\nexport function getOAuthSignInUrl(oauthConfigId: string): string {\n\treturn `${import.meta.env.VITE_CENTRAL_MANAGER_API_URL}/oauth/${oauthConfigId}/login`;\n}\n","import { SubNavMenu } from '@/components/SubNavMenu';\nimport { Button } from '@/components/ui/button';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { Switch } from '@/components/ui/switch';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';\nimport { apiClient } from '@/config/apiClient';\nimport { getOrganizationQueryOptions } from '@/features/organization/queries/getOrganizationQuery';\nimport { useCloudAuth } from '@/hooks/useAuth';\nimport { useOrganizationPermissions } from '@/hooks/usePermissions';\nimport { SchemaOrganization } from '@/integrations/api/api.gen';\nimport { OAuthConfig } from '@/integrations/api/api.patch';\nimport { getOAuthSignInUrl } from '@/lib/urls/getOAuthSignInUrl';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useMutation, useQueryClient, useSuspenseQuery } from '@tanstack/react-query';\nimport { useParams } from '@tanstack/react-router';\nimport { CopyIcon, ExternalLinkIcon, PencilIcon, PlusIcon, XIcon } from 'lucide-react';\nimport { useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\n\n// PATCH /Organization/{orgId}/settings/oauth\n// id absent = create, id present = update. provider is required on every call.\nasync function patchOAuthConfig(orgId: string, payload: Partial<OAuthConfig> & { provider: string }) {\n\tconst { data } = await apiClient.patch(\n\t\t`/Organization/${orgId}/settings/oauth` as '/Organization/{id}',\n\t\tpayload as unknown as SchemaOrganization,\n\t);\n\treturn data as unknown as OAuthConfig;\n}\n\n// ── Add form ──────────────────────────────────────────────────────────────────\n\nconst addSchema = z.object({\n\tdomain: z.string().min(1, 'Domain is required'),\n\tclientId: z.string().min(1, 'Client ID is required'),\n\tclientSecret: z.string().min(1, 'Client secret is required'),\n\tscope: z.string().optional(),\n\t// required is always false on creation — admin must sign in via the provider first\n});\ntype AddForm = z.infer<typeof addSchema>;\n\n// ── Edit form ─────────────────────────────────────────────────────────────────\n\nconst editSchema = z.object({\n\tdomain: z.string().min(1, 'Domain is required'),\n\t// blank = keep existing (server ignores absent fields; don't echo masked '****' back)\n\tclientId: z.string().optional(),\n\tclientSecret: z.string().optional(),\n\tscope: z.string().optional(),\n});\ntype EditForm = z.infer<typeof editSchema>;\n\n// ── Component ─────────────────────────────────────────────────────────────────\n\nexport function OrgSettingsIndex() {\n\tconst { organizationId } = useParams({ strict: false });\n\tconst { user } = useCloudAuth();\n\tconst { update: canUpdate } = useOrganizationPermissions(organizationId);\n\tconst { data: organization } = useSuspenseQuery(getOrganizationQueryOptions(organizationId));\n\tconst queryClient = useQueryClient();\n\n\tconst [isAdding, setIsAdding] = useState(false);\n\tconst [editingId, setEditingId] = useState<string | null>(null);\n\n\tconst configs: OAuthConfig[] = organization.settings?.oauthConfigs ?? [];\n\n\tconst { mutate: patch, isPending } = useMutation({\n\t\tmutationFn: (payload: Partial<OAuthConfig> & { provider: string }) => patchOAuthConfig(organizationId, payload),\n\t\tonSuccess: () => void queryClient.invalidateQueries({ queryKey: [organizationId] }),\n\t\tonError: () => toast.error('Failed to update OAuth settings.'),\n\t});\n\n\t// Add\n\tconst addForm = useForm<AddForm>({\n\t\tresolver: zodResolver(addSchema),\n\t\tdefaultValues: { domain: '', clientId: '', clientSecret: '', scope: 'openid email profile' },\n\t});\n\n\tconst onAdd = (data: AddForm) => {\n\t\tpatch(\n\t\t\t{ provider: 'okta', ...data },\n\t\t\t{\n\t\t\t\tonSuccess: () => {\n\t\t\t\t\ttoast.success('OAuth provider added.');\n\t\t\t\t\taddForm.reset();\n\t\t\t\t\tsetIsAdding(false);\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t};\n\n\t// Edit\n\tconst editForm = useForm<EditForm>({ resolver: zodResolver(editSchema) });\n\n\tconst startEdit = (config: OAuthConfig) => {\n\t\tsetEditingId(config.id ?? null);\n\t\teditForm.reset({ domain: config.domain, clientId: '', clientSecret: '', scope: config.scope ?? '' });\n\t};\n\n\tconst onEdit = (config: OAuthConfig, data: EditForm) => {\n\t\tconst payload: Partial<OAuthConfig> & { provider: string; id: string } = {\n\t\t\tid: config.id!,\n\t\t\tprovider: config.provider,\n\t\t\tdomain: data.domain,\n\t\t\tscope: data.scope,\n\t\t};\n\t\t// Only include secrets if the user actually typed something (blank = keep existing)\n\t\tif (data.clientId) { payload.clientId = data.clientId; }\n\t\tif (data.clientSecret) { payload.clientSecret = data.clientSecret; }\n\n\t\tpatch(payload, {\n\t\t\tonSuccess: () => {\n\t\t\t\ttoast.success('OAuth provider updated.');\n\t\t\t\tsetEditingId(null);\n\t\t\t},\n\t\t});\n\t};\n\n\t// Toggle enabled / required\n\tconst toggleField = (config: OAuthConfig, field: 'enabled' | 'required') => {\n\t\tpatch({\n\t\t\tid: config.id!,\n\t\t\tprovider: config.provider,\n\t\t\t[field]: !config[field],\n\t\t});\n\t};\n\n\tconst getCallbackUrl = (oauthConfigId: string) =>\n\t\t`${import.meta.env.VITE_CENTRAL_MANAGER_API_URL}/oauth/${oauthConfigId}/callback`;\n\n\tconst copySignInUrl = async (url: string) => {\n\t\tawait navigator.clipboard.writeText(url);\n\t\ttoast.success('Sign-in URL copied.');\n\t};\n\n\tconst copyCallbackUrl = async (url: string) => {\n\t\tawait navigator.clipboard.writeText(url);\n\t\ttoast.success('Redirect URI copied.');\n\t};\n\n\tif (!canUpdate) {\n\t\treturn (\n\t\t\t<div className=\"mt-32 px-4 pt-4 md:px-12 min-h-[calc(100vh-theme(spacing.32))] text-foreground\">\n\t\t\t\tYou don&apos;t have permission to manage settings for this organization.\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t<SubNavMenu />\n\t\t\t<div className=\"mt-32 px-4 pt-4 md:px-12 min-h-[calc(100vh-theme(spacing.32))]\">\n\t\t\t\t<div className=\"max-w-2xl\">\n\t\t\t\t\t<h2 className=\"text-2xl text-foreground font-light mb-6\">Authentication</h2>\n\n\t\t\t\t\t<section>\n\t\t\t\t\t\t<div className=\"flex items-center justify-between mb-4\">\n\t\t\t\t\t\t\t<h3 className=\"text-lg text-foreground font-medium\">OAuth Providers</h3>\n\t\t\t\t\t\t\t{!isAdding && (\n\t\t\t\t\t\t\t\t<Button variant=\"positiveOutline\" size=\"sm\" onClick={() => setIsAdding(true)}>\n\t\t\t\t\t\t\t\t\t<PlusIcon />\n\t\t\t\t\t\t\t\t\tAdd Provider\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t{configs.length === 0 && !isAdding && (\n\t\t\t\t\t\t\t<p className=\"text-muted-foreground text-sm mb-4\">No OAuth providers configured.</p>\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{/* Existing provider cards */}\n\t\t\t\t\t\t{configs.map((config) => {\n\t\t\t\t\t\t\t// Required can only be toggled when the admin is already authenticated\n\t\t\t\t\t\t\t// via this provider — otherwise they'd lock themselves out.\n\t\t\t\t\t\t\tconst canToggleRequired = user?.oauthConfigId === config.id;\n\t\t\t\t\t\t\treturn editingId === config.id\n\t\t\t\t\t\t\t\t? (\n\t\t\t\t\t\t\t\t\t/* ── Inline edit form ── */\n\t\t\t\t\t\t\t\t\t<div key={config.id} className=\"border rounded-lg p-4 mb-3 text-foreground\">\n\t\t\t\t\t\t\t\t\t\t<div className=\"flex items-center justify-between mb-4\">\n\t\t\t\t\t\t\t\t\t\t\t<h4 className=\"font-medium\">Edit Provider</h4>\n\t\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t\tonClick={() => setEditingId(null)}\n\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"text-muted-foreground hover:text-foreground\"\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t<XIcon className=\"size-4\" />\n\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t<Form {...editForm}>\n\t\t\t\t\t\t\t\t\t\t\t<form onSubmit={editForm.handleSubmit((d) => onEdit(config, d))} className=\"space-y-4\">\n\t\t\t\t\t\t\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\t\t\t\t\t\t\tcontrol={editForm.control}\n\t\t\t\t\t\t\t\t\t\t\t\t\tname=\"domain\"\n\t\t\t\t\t\t\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<FormLabel>Domain</FormLabel>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Input placeholder=\"company.okta.com\" {...field} />\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\t\t\t\t\t\t\tcontrol={editForm.control}\n\t\t\t\t\t\t\t\t\t\t\t\t\tname=\"clientId\"\n\t\t\t\t\t\t\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<FormLabel>Client ID</FormLabel>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Input placeholder=\"Leave blank to keep existing\" {...field} />\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\t\t\t\t\t\t\tcontrol={editForm.control}\n\t\t\t\t\t\t\t\t\t\t\t\t\tname=\"clientSecret\"\n\t\t\t\t\t\t\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<FormLabel>Client Secret</FormLabel>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Input type=\"password\" placeholder=\"Leave blank to keep existing\" {...field} />\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\t\t\t\t\t\t\tcontrol={editForm.control}\n\t\t\t\t\t\t\t\t\t\t\t\t\tname=\"scope\"\n\t\t\t\t\t\t\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<FormLabel>Scope</FormLabel>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Input placeholder=\"openid email profile\" {...field} />\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"flex gap-2 pt-2\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<Button type=\"submit\" variant=\"positive\" disabled={isPending}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{isPending ? 'Saving...' : 'Save'}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<Button type=\"button\" variant=\"outline\" onClick={() => setEditingId(null)}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t</form>\n\t\t\t\t\t\t\t\t\t\t</Form>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t: (\n\t\t\t\t\t\t\t\t\t/* ── Provider display card ── */\n\t\t\t\t\t\t\t\t\t<div key={config.id} className=\"border rounded-lg p-4 mb-3 text-foreground\">\n\t\t\t\t\t\t\t\t\t\t<div className=\"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between sm:gap-4\">\n\t\t\t\t\t\t\t\t\t\t\t<div className=\"flex-1 min-w-0\">\n\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"flex items-center gap-2 mb-1\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"font-medium\">{config.domain}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"text-xs text-muted-foreground uppercase bg-muted px-2 py-0.5 rounded\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{config.provider}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{config.enabled === false && (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"text-xs text-destructive bg-destructive/10 px-2 py-0.5 rounded\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tDisabled\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t<p className=\"text-sm text-muted-foreground mb-2\">\n\t\t\t\t\t\t\t\t\t\t\t\t\tClient ID: <span className=\"text-foreground font-mono\">****</span>\n\t\t\t\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t\t\t\t\t{config.id && (\n\t\t\t\t\t\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"mt-3 rounded-md bg-muted px-3 py-2\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<p className=\"text-xs font-medium text-muted-foreground mb-1\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tOkta redirect URI\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<p className=\"text-xs text-muted-foreground mb-1.5\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tAdd to <span className=\"font-medium text-foreground\">Login redirect URIs</span>{' '}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tin your Okta app settings.\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"text-sm text-foreground font-mono truncate\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{getCallbackUrl(config.id)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonClick={() => void copyCallbackUrl(getCallbackUrl(config.id!))}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"hover:text-foreground shrink-0 text-muted-foreground\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttitle=\"Copy redirect URI\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<CopyIcon className=\"size-3.5\" />\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"mt-2 rounded-md bg-muted px-3 py-2\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<p className=\"text-xs font-medium text-muted-foreground mb-1.5\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tUser login link\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\thref={getOAuthSignInUrl(config.id)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\trel=\"noreferrer\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"text-sm text-foreground truncate hover:underline\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{getOAuthSignInUrl(config.id)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"flex items-center gap-1.5 shrink-0 text-muted-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonClick={() => void copySignInUrl(getOAuthSignInUrl(config.id!))}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"hover:text-foreground\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttitle=\"Copy login link\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<CopyIcon className=\"size-3.5\" />\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\thref={getOAuthSignInUrl(config.id)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\trel=\"noreferrer\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"hover:text-foreground\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttitle=\"Open login link\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<ExternalLinkIcon className=\"size-3.5\" />\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t<div className=\"flex items-center gap-3 sm:shrink-0\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label className=\"flex items-center gap-2 text-sm text-foreground cursor-pointer\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<Switch\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tchecked={config.enabled !== false}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tonCheckedChange={() => toggleField(config, 'enabled')}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdisabled={isPending}\n\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t\tEnabled\n\t\t\t\t\t\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t\t\t\t\t\t\t<Tooltip>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName={`inline-flex items-center gap-2 text-sm text-foreground ${\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcanToggleRequired ? 'cursor-pointer' : 'cursor-not-allowed opacity-50'\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}`}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Switch\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tchecked={!!config.required}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonCheckedChange={() => toggleField(config, 'required')}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdisabled={isPending || !canToggleRequired}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tRequired\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</TooltipTrigger>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{!canToggleRequired && (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<TooltipContent>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tSign in via {config.provider} first to enable Required\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</TooltipContent>\n\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tonClick={() => startEdit(config)}\n\t\t\t\t\t\t\t\t\t\t\t\t\tdisabled={isPending}\n\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<PencilIcon className=\"size-4\" />\n\t\t\t\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})}\n\n\t\t\t\t\t\t{/* Add form */}\n\t\t\t\t\t\t{isAdding && (\n\t\t\t\t\t\t\t<div className=\"border rounded-lg p-4 text-foreground\">\n\t\t\t\t\t\t\t\t<div className=\"flex items-center justify-between mb-4\">\n\t\t\t\t\t\t\t\t\t<h4 className=\"font-medium\">Add Okta Provider</h4>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t\tsetIsAdding(false);\n\t\t\t\t\t\t\t\t\t\t\taddForm.reset();\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\tclassName=\"text-muted-foreground hover:text-foreground\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<XIcon className=\"size-4\" />\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<p className=\"text-xs text-muted-foreground mb-4\">\n\t\t\t\t\t\t\t\t\tAfter saving, copy the <span className=\"font-medium text-foreground\">Okta redirect URI</span>{' '}\n\t\t\t\t\t\t\t\t\tfrom the provider card and add it to your Okta app&apos;s{' '}\n\t\t\t\t\t\t\t\t\t<span className=\"font-medium text-foreground\">Login redirect URIs</span>.\n\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t<Form {...addForm}>\n\t\t\t\t\t\t\t\t\t<form onSubmit={addForm.handleSubmit(onAdd)} className=\"space-y-4\">\n\t\t\t\t\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\t\t\t\t\tcontrol={addForm.control}\n\t\t\t\t\t\t\t\t\t\t\tname=\"domain\"\n\t\t\t\t\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<FormLabel>Domain</FormLabel>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Input placeholder=\"company.okta.com\" autoFocus {...field} />\n\t\t\t\t\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\t\t\t\t\tcontrol={addForm.control}\n\t\t\t\t\t\t\t\t\t\t\tname=\"clientId\"\n\t\t\t\t\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<FormLabel>Client ID</FormLabel>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Input placeholder=\"Okta Client ID\" {...field} />\n\t\t\t\t\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\t\t\t\t\tcontrol={addForm.control}\n\t\t\t\t\t\t\t\t\t\t\tname=\"clientSecret\"\n\t\t\t\t\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<FormLabel>Client Secret</FormLabel>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Input type=\"password\" placeholder=\"Okta Client Secret\" {...field} />\n\t\t\t\t\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\t\t\t\t\tcontrol={addForm.control}\n\t\t\t\t\t\t\t\t\t\t\tname=\"scope\"\n\t\t\t\t\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<FormLabel>Scope</FormLabel>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Input placeholder=\"openid email profile\" {...field} />\n\t\t\t\t\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t<div className=\"flex gap-2 pt-2\">\n\t\t\t\t\t\t\t\t\t\t\t<Button type=\"submit\" variant=\"positive\" disabled={isPending}>\n\t\t\t\t\t\t\t\t\t\t\t\t{isPending ? 'Adding...' : 'Add Provider'}\n\t\t\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\tsetIsAdding(false);\n\t\t\t\t\t\t\t\t\t\t\t\t\taddForm.reset();\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</form>\n\t\t\t\t\t\t\t\t</Form>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</section>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</>\n\t);\n}\n","import { SchemaUser } from '@/integrations/api/api.gen';\nimport { ColumnDef, createColumnHelper } from '@tanstack/react-table';\n\nconst columnHelper = createColumnHelper<SchemaUser>();\n\nexport const dataTableColumns: Array<ColumnDef<SchemaUser>> = [\n\t{\n\t\theader: 'User Id',\n\t\taccessorKey: 'id',\n\t\tenableSorting: false,\n\t},\n\t{\n\t\theader: 'Email',\n\t\taccessorKey: 'email',\n\t\tenableSorting: false,\n\t},\n\t{\n\t\theader: 'First Name',\n\t\taccessorKey: 'firstname',\n\t\tenableSorting: false,\n\t},\n\t{\n\t\theader: 'Last Name',\n\t\taccessorKey: 'lastname',\n\t\tenableSorting: false,\n\t},\n\tcolumnHelper.display({\n\t\theader: 'Roles',\n\t\tenableSorting: false,\n\t\tid: 'roles',\n\t\tcell: (props) => props.row.original.roles?.map(r => r.roleName)?.sort()?.join(', '),\n\t}),\n\t{\n\t\theader: 'Status',\n\t\taccessorKey: 'status',\n\t\tenableSorting: false,\n\t},\n\t{\n\t\theader: 'Verified',\n\t\taccessorKey: 'isVerified',\n\t\tenableSorting: false,\n\t},\n];\n","import { apiClient } from '@/config/apiClient';\nimport { zodRequireEmail } from '@/lib/zod/email';\nimport { useMutation } from '@tanstack/react-query';\nimport z from 'zod';\n\nexport const AddOrganizationRoleSchema = z.object({\n\temail: zodRequireEmail\n\t\t.max(80, { error: 'Email cannot be longer than 80 characters.' }),\n\troleId: z.string().nonempty({ error: 'Please select a role.' }),\n});\n\nexport async function onAddUserToOrganizationRoleSubmit(formData: z.infer<typeof AddOrganizationRoleSchema>) {\n\tconst { data } = await apiClient.post('/OrganizationRole/', formData);\n\treturn data;\n}\n\nexport function useAddUserToOrganizationRole() {\n\treturn useMutation({\n\t\tmutationFn: (formData: z.infer<typeof AddOrganizationRoleSchema>) => onAddUserToOrganizationRoleSubmit(formData),\n\t});\n}\n","import { apiClient } from '@/config/apiClient';\nimport { zodRequireEmail } from '@/lib/zod/email';\nimport { useMutation } from '@tanstack/react-query';\nimport z from 'zod';\n\nexport const InviteOrganizationRoleSchema = z.object({\n\temail: zodRequireEmail\n\t\t.max(80, { error: 'Email cannot be longer than 80 characters.' }),\n\troleId: z.string().nonempty({ error: 'Please select a role.' }),\n});\n\nexport async function onInviteUserToOrganizationRoleSubmit(formData: z.infer<typeof InviteOrganizationRoleSchema>) {\n\tconst { data } = await apiClient.post('/UserInvite/', formData);\n\treturn data;\n}\n\nexport function useInviteUserToOrganizationRole() {\n\treturn useMutation({\n\t\tmutationFn: (formData: z.infer<typeof InviteOrganizationRoleSchema>) =>\n\t\t\tonInviteUserToOrganizationRoleSubmit(formData),\n\t});\n}\n","import { TextLoadingSkeleton } from '@/components/TextLoadingSkeleton';\nimport { Button } from '@/components/ui/button';\nimport {\n\tDialog,\n\tDialogContent,\n\tDialogDescription,\n\tDialogFooter,\n\tDialogHeader,\n\tDialogTitle,\n} from '@/components/ui/dialog';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport {\n\tSelect,\n\tSelectContent,\n\tSelectGroup,\n\tSelectItem,\n\tSelectLabel,\n\tSelectTrigger,\n\tSelectValue,\n} from '@/components/ui/select';\nimport {\n\tAddOrganizationRoleSchema,\n\tuseAddUserToOrganizationRole,\n} from '@/features/organization/mutations/addUserToOrganizationRole';\nimport { useInviteUserToOrganizationRole } from '@/features/organization/mutations/inviteUserToOrganizationRole';\nimport { getOrganizationRolesQueryOptions } from '@/features/organization/queries/getOrganizationRoles';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useSuspenseQuery } from '@tanstack/react-query';\nimport { useParams } from '@tanstack/react-router';\nimport { AxiosError } from 'axios';\nimport { MailWarningIcon, Save } from 'lucide-react';\nimport { Suspense, useCallback, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\n\nexport function AddUserModal({\n\tisModalOpen,\n\tonChangesSaved,\n\tsetIsModalOpen,\n}: {\n\tisModalOpen: boolean;\n\tonChangesSaved: () => void;\n\tsetIsModalOpen: (open: boolean) => void;\n}) {\n\tconst { organizationId }: { organizationId: string } = useParams({ strict: false });\n\tconst { data: orgRoles } = useSuspenseQuery(getOrganizationRolesQueryOptions(organizationId));\n\tconst [shouldInvite, setShouldInvite] = useState(false);\n\n\tconst form = useForm({\n\t\tresolver: zodResolver(AddOrganizationRoleSchema),\n\t\tdefaultValues: {\n\t\t\temail: '',\n\t\t\troleId: '',\n\t\t},\n\t});\n\tconst { mutate: addUser, isPending: isAddPending } = useAddUserToOrganizationRole();\n\tconst { mutate: inviteUser, isPending: isInvitePending } = useInviteUserToOrganizationRole();\n\n\tconst onSubmitClick = useCallback(\n\t\tasync (formData: z.infer<typeof AddOrganizationRoleSchema>) => {\n\t\t\tif (formData) {\n\t\t\t\t(shouldInvite ? inviteUser : addUser)(formData, {\n\t\t\t\t\tonSuccess: () => {\n\t\t\t\t\t\tconst lastRole = formData.roleId;\n\t\t\t\t\t\tform.reset();\n\t\t\t\t\t\t// Persist the selected role if they open the form again.\n\t\t\t\t\t\tform.setValue('roleId', lastRole);\n\t\t\t\t\t\tonChangesSaved();\n\t\t\t\t\t\ttoast.success('User invited successfully!');\n\t\t\t\t\t\tsetIsModalOpen(false);\n\t\t\t\t\t\tsetShouldInvite(false);\n\t\t\t\t\t},\n\t\t\t\t\tonError: (error) => {\n\t\t\t\t\t\tif ((error as AxiosError)?.status === 404) {\n\t\t\t\t\t\t\tsetShouldInvite(true);\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\t[addUser, form, inviteUser, onChangesSaved, setIsModalOpen, shouldInvite],\n\t);\n\n\treturn (\n\t\t<Dialog\n\t\t\tonOpenChange={() => {\n\t\t\t\tsetIsModalOpen(false);\n\t\t\t\tsetShouldInvite(false);\n\t\t\t\tform.reset();\n\t\t\t}}\n\t\t\topen={isModalOpen}\n\t\t>\n\t\t\t<DialogContent aria-describedby={undefined}>\n\t\t\t\t<Form {...form}>\n\t\t\t\t\t<form\n\t\t\t\t\t\tid=\"org-add-user-form\"\n\t\t\t\t\t\tname=\"org-add-user-form\"\n\t\t\t\t\t\tonSubmit={form.handleSubmit(onSubmitClick)}\n\t\t\t\t\t\tclassName=\"grid gap-4 my-4\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<DialogHeader>\n\t\t\t\t\t\t\t<DialogTitle>{shouldInvite ? 'Invite User' : 'Add User'}</DialogTitle>\n\t\t\t\t\t\t</DialogHeader>\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"email\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Email</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Input type=\"email\" enterKeyHint=\"next\" autoComplete=\"email\" {...field} />\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"roleId\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Roles</FormLabel>\n\n\t\t\t\t\t\t\t\t\t<Suspense fallback={<TextLoadingSkeleton />}>\n\t\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t\t<Select {...field} onValueChange={(role) => field.onChange(role)}>\n\t\t\t\t\t\t\t\t\t\t\t\t<SelectTrigger className=\"w-full\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<SelectValue placeholder=\"Choose Role\" />\n\t\t\t\t\t\t\t\t\t\t\t\t</SelectTrigger>\n\t\t\t\t\t\t\t\t\t\t\t\t<SelectContent>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<SelectGroup>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{/*TODO: Multi select*/}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<SelectLabel>Role</SelectLabel>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{orgRoles?.map((role) => (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<SelectItem key={role.id} value={role.id}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{role.roleName}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</SelectItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</SelectGroup>\n\t\t\t\t\t\t\t\t\t\t\t\t</SelectContent>\n\t\t\t\t\t\t\t\t\t\t\t</Select>\n\t\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t</Suspense>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t{shouldInvite && (\n\t\t\t\t\t\t\t<DialogDescription className=\"p-3 my-5 text-white rounded-md bg-amber-600 flex\">\n\t\t\t\t\t\t\t\t<MailWarningIcon className=\"inline-block size-12 pr-2\" />\n\t\t\t\t\t\t\t\t<span>This person doesn’t have a Fabric account. Do you want to invite them?</span>\n\t\t\t\t\t\t\t</DialogDescription>\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t<DialogFooter>\n\t\t\t\t\t\t\t<div className=\"flex justify-between w-full\">\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\t\t\t\tvariant=\"submit\"\n\t\t\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\t\t\tdisabled={isAddPending || isInvitePending}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Save /> {shouldInvite ? 'Invite User' : 'Add User'}\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</DialogFooter>\n\t\t\t\t\t</form>\n\t\t\t\t</Form>\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n}\n","import { apiClient } from '@/config/apiClient';\nimport { useMutation } from '@tanstack/react-query';\n\nexport async function onRemoveUserFromOrganizationRole({ roleId, userId }: { roleId: string; userId: string }) {\n\t// TODO: The API doesn't describe this endpoint in its docs.\n\tconst { data } = await apiClient.delete(\n\t\t`/OrganizationRole/role/${roleId}/user/${userId}` as '/OrganizationRole/{id}',\n\t);\n\treturn data;\n}\n\nexport function useRemoveUserFromOrganizationRole() {\n\treturn useMutation<unknown, Error, { roleId: string; userId: string }>({\n\t\tmutationFn: ({ roleId, userId }: {\n\t\t\troleId: string;\n\t\t\tuserId: string;\n\t\t}) => onRemoveUserFromOrganizationRole({ roleId, userId }),\n\t});\n}\n","import { ChangeEvent, useCallback, useState } from 'react';\n\nexport function useCheckboxCallback(defaultValue?: boolean) {\n\tconst [state, setState] = useState<boolean>(defaultValue || false);\n\tconst onClick = useCallback((e: boolean | ChangeEvent<HTMLInputElement>) => {\n\t\tsetState(typeof e === 'boolean' ? e : e.target.checked);\n\t}, []);\n\treturn [state, onClick] as const;\n}\n","import { Input } from '@/components/ui/input';\nimport { Label } from '@/components/ui/label';\nimport { useAddUserToOrganizationRole } from '@/features/organization/mutations/addUserToOrganizationRole';\nimport { useRemoveUserFromOrganizationRole } from '@/features/organization/mutations/removeUserFromOrganizationRole';\nimport { useCheckboxCallback } from '@/hooks/useCheckboxCallback';\nimport { SchemaOrganizationRole, SchemaUser } from '@/integrations/api/api.gen';\nimport { useEffect, useState } from 'react';\nimport { toast } from 'sonner';\n\nexport function OrgUserRoleCheckbox({\n\tdata,\n\treadOnly,\n\tcanRemove,\n\torgRole,\n\tselectedRoles,\n\tsetChangesMade,\n}: {\n\tdata: SchemaUser;\n\treadOnly: boolean;\n\tcanRemove: boolean;\n\torgRole: SchemaOrganizationRole;\n\tselectedRoles: Record<string, SchemaOrganizationRole>;\n\tsetChangesMade: (value: boolean) => void;\n}) {\n\tconst { mutate: addUser, isPending: isAddPending } = useAddUserToOrganizationRole();\n\tconst { mutate: removeUser, isPending: isRemovePending } = useRemoveUserFromOrganizationRole();\n\tconst userIsInRole = !!selectedRoles[orgRole.roleName];\n\tconst [wasChecked, setWasChecked] = useState(userIsInRole);\n\tconst [isChecked, onCheckedChanged] = useCheckboxCallback(userIsInRole);\n\tuseEffect(() => {\n\t\tif (isChecked !== wasChecked) {\n\t\t\tif (isChecked) {\n\t\t\t\taddUser(\n\t\t\t\t\t{ email: data.email, roleId: orgRole.id },\n\t\t\t\t\t{\n\t\t\t\t\t\tonSuccess: () => {\n\t\t\t\t\t\t\tsetWasChecked(isChecked);\n\t\t\t\t\t\t\tsetChangesMade(true);\n\t\t\t\t\t\t\ttoast.success(`Role added successfully`);\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tremoveUser(\n\t\t\t\t\t{ userId: data.id, roleId: orgRole.id },\n\t\t\t\t\t{\n\t\t\t\t\t\tonSuccess: () => {\n\t\t\t\t\t\t\tsetWasChecked(isChecked);\n\t\t\t\t\t\t\tsetChangesMade(true);\n\t\t\t\t\t\t\ttoast.success(`Role removed successfully`);\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}, [addUser, data.email, data.id, isChecked, orgRole.id, removeUser, setChangesMade, wasChecked]);\n\n\treturn (\n\t\t<Label key={orgRole.id} className=\"flex\">\n\t\t\t<Input\n\t\t\t\ttype=\"checkbox\"\n\t\t\t\tclassName=\"w-6\"\n\t\t\t\tdisabled={readOnly || isAddPending || isRemovePending || (!canRemove && isChecked)}\n\t\t\t\tchecked={isChecked}\n\t\t\t\tonChange={onCheckedChanged}\n\t\t\t/>\n\t\t\t<span className=\"pl-4 pr-8 flex-1 py-2.5\">{orgRole.roleName}</span>\n\t\t</Label>\n\t);\n}\n","import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog';\nimport { getOrganizationRolesQueryOptions } from '@/features/organization/queries/getOrganizationRoles';\nimport { OrgUserRoleCheckbox } from '@/features/organization/users/components/OrgUserRoleCheckbox';\nimport { useCloudAuth } from '@/hooks/useAuth';\nimport { useOrganizationRolePermissions } from '@/hooks/usePermissions';\nimport { SchemaUser } from '@/integrations/api/api.gen';\nimport { keyBy } from '@/lib/keyBy';\nimport { useSuspenseQuery } from '@tanstack/react-query';\nimport { useParams } from '@tanstack/react-router';\nimport { useMemo, useState } from 'react';\n\nexport function EditUserModal({\n\tcloseModal,\n\tdata,\n\tisModalOpen,\n\tonUserUpdated,\n}: {\n\tcloseModal: () => void;\n\tdata: SchemaUser;\n\tisModalOpen: boolean;\n\tonUserUpdated: () => void;\n}) {\n\tconst { organizationId }: { organizationId: string } = useParams({ strict: false });\n\tconst auth = useCloudAuth();\n\tconst { update, remove } = useOrganizationRolePermissions(organizationId);\n\tconst isSelf = auth.user?.email === data.email;\n\tconst { data: orgRoles } = useSuspenseQuery(getOrganizationRolesQueryOptions(organizationId));\n\tconst selectedRoles = useMemo(() => data.roles ? keyBy(data.roles, 'roleName') : {}, [data]);\n\tconst [changesMade, setChangesMade] = useState<boolean>(false);\n\n\t// TODO: Cancel invite\n\treturn (\n\t\t<Dialog onOpenChange={changesMade ? onUserUpdated : closeModal} open={isModalOpen}>\n\t\t\t<DialogContent className=\"sm:max-w-[750px]\">\n\t\t\t\t<DialogHeader>\n\t\t\t\t\t<DialogTitle>{update ? 'Edit ' : 'View '} {data.email} {isSelf ? '(yourself)' : ''}</DialogTitle>\n\t\t\t\t</DialogHeader>\n\n\t\t\t\t{update && (\n\t\t\t\t\t<DialogDescription>\n\t\t\t\t\t\tTo remove {isSelf ? 'your self' : 'this user'} from the organization, uncheck all of the boxes below.\n\t\t\t\t\t</DialogDescription>\n\t\t\t\t)}\n\n\t\t\t\t{orgRoles.map((orgRole) => (\n\t\t\t\t\t<OrgUserRoleCheckbox\n\t\t\t\t\t\tkey={orgRole.id}\n\t\t\t\t\t\treadOnly={!update}\n\t\t\t\t\t\tcanRemove={remove}\n\t\t\t\t\t\tdata={data}\n\t\t\t\t\t\torgRole={orgRole}\n\t\t\t\t\t\tselectedRoles={selectedRoles}\n\t\t\t\t\t\tsetChangesMade={setChangesMade}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n}\n","export function sortByEmail(a: { email: string }, b: { email: string }) {\n\treturn a.email > b.email ? 1 : -1;\n}\n","import { Loading } from '@/components/Loading';\nimport { SimpleBrowseDataTable } from '@/components/SimpleBrowseDataTable';\nimport { SubNavMenu } from '@/components/SubNavMenu';\nimport { Button } from '@/components/ui/button';\nimport { getOrganizationRolesQueryOptions } from '@/features/organization/queries/getOrganizationRoles';\nimport { dataTableColumns } from '@/features/organization/users/constants/tableDefinition';\nimport { AddUserModal } from '@/features/organization/users/modals/AddUserModal';\nimport { EditUserModal } from '@/features/organization/users/modals/EditUserModal';\nimport { useOrganizationRolePermissions } from '@/hooks/usePermissions';\nimport { useRefreshClick } from '@/hooks/useRefreshClick';\nimport { SchemaUser } from '@/integrations/api/api.gen';\nimport { sortByEmail } from '@/lib/arrays/sort/byEmail';\nimport { useSuspenseQuery } from '@tanstack/react-query';\nimport { useNavigate, useParams } from '@tanstack/react-router';\nimport { Row } from '@tanstack/react-table';\nimport { PlusIcon, RefreshCwIcon } from 'lucide-react';\nimport { Suspense, useCallback, useMemo, useState } from 'react';\n\nexport function OrgConfigUsersIndex() {\n\tconst navigate = useNavigate();\n\tconst { organizationId, orgUserId }: { organizationId: string; orgUserId?: string } = useParams({ strict: false });\n\tconst { update } = useOrganizationRolePermissions(organizationId);\n\tconst {\n\t\tdata: organizationRoles,\n\t\trefetch,\n\t\tisFetching,\n\t\tisRefetching,\n\t} = useSuspenseQuery(getOrganizationRolesQueryOptions(organizationId));\n\tconst cloudUsers = useMemo(() => {\n\t\tconst users: Record<SchemaUser['id'], SchemaUser> = {};\n\t\tfor (const organizationRole of organizationRoles) {\n\t\t\tif (organizationRole.users) {\n\t\t\t\tfor (const user of organizationRole.users) {\n\t\t\t\t\tif (!users[user.id]) {\n\t\t\t\t\t\tusers[user.id] = { ...user, roles: [] };\n\t\t\t\t\t}\n\t\t\t\t\tusers[user.id].roles!.push(organizationRole);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn Object.values(users).sort(sortByEmail);\n\t}, [organizationRoles]);\n\n\tconst selectedUser = useMemo(() => cloudUsers?.find((user) => user.id === orgUserId), [cloudUsers, orgUserId]);\n\n\tconst onSelectUser = useCallback(\n\t\t(newUserId: string | undefined) => {\n\t\t\tconst parts = [orgUserId ? '..' : '', newUserId].filter(Boolean);\n\t\t\tvoid navigate({ to: parts.join('/') });\n\t\t},\n\t\t[orgUserId, navigate],\n\t);\n\n\tconst isEditModalOpen = !!orgUserId && !!selectedUser;\n\n\tconst [isAddModalOpen, setIsAddModalOpen] = useState(false);\n\tconst [sortTableDataParams] = useState({\n\t\tattribute: 'email',\n\t\tdescending: false,\n\t});\n\tconst sortingState = useMemo(\n\t\t() => [\n\t\t\t{\n\t\t\t\tdesc: sortTableDataParams.descending,\n\t\t\t\tid: sortTableDataParams.attribute,\n\t\t\t},\n\t\t],\n\t\t[sortTableDataParams],\n\t);\n\n\tconst onAddClicked = useCallback(() => {\n\t\tsetIsAddModalOpen(true);\n\t}, [setIsAddModalOpen]);\n\tconst onUsedAdded = useCallback(() => {\n\t\tvoid refetch();\n\t\tsetIsAddModalOpen(false);\n\t}, [refetch, setIsAddModalOpen]);\n\n\tconst onRowClick = useCallback(\n\t\t(rowData: Row<SchemaUser>) => {\n\t\t\tonSelectUser(rowData.original.id);\n\t\t},\n\t\t[onSelectUser],\n\t);\n\tconst closeEditModal = useCallback(() => {\n\t\tonSelectUser(undefined);\n\t}, [onSelectUser]);\n\n\tconst onUserUpdated = useCallback(() => {\n\t\tvoid refetch();\n\t\tonSelectUser(undefined);\n\t}, [onSelectUser, refetch]);\n\n\tconst onRefreshClick = useRefreshClick(refetch);\n\n\treturn (\n\t\t<>\n\t\t\t<SubNavMenu />\n\t\t\t<div className=\"mt-32 px-4 pt-4 md:px-12 min-h-[calc(100vh-theme(spacing.32))]\">\n\t\t\t\t<Suspense fallback={<Loading className=\"flex flex-col items-center justify-center h-full\" text=\"Loading...\" />}>\n\t\t\t\t\t<SimpleBrowseDataTable<SchemaUser, unknown>\n\t\t\t\t\t\tdata={cloudUsers}\n\t\t\t\t\t\tisFetching={isFetching || isRefetching}\n\t\t\t\t\t\tcolumns={dataTableColumns}\n\t\t\t\t\t\tonRowClick={onRowClick}\n\t\t\t\t\t\tsortingState={sortingState}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tvariant=\"defaultOutline\"\n\t\t\t\t\t\t\tonClick={onRefreshClick}\n\t\t\t\t\t\t\taccessKey=\"r\"\n\t\t\t\t\t\t\tdisabled={isFetching || isRefetching}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<RefreshCwIcon />{' '}\n\t\t\t\t\t\t\t<span className=\"hidden lg:inline-block\">\n\t\t\t\t\t\t\t\t<u>R</u>efresh\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t{update && (\n\t\t\t\t\t\t\t<Button variant=\"positiveOutline\" onClick={onAddClicked} accessKey=\"a\" disabled={isAddModalOpen}>\n\t\t\t\t\t\t\t\t<PlusIcon />{' '}\n\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t<u>A</u>dd\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</SimpleBrowseDataTable>\n\t\t\t\t\t{update && (\n\t\t\t\t\t\t<AddUserModal\n\t\t\t\t\t\t\tisModalOpen={isAddModalOpen}\n\t\t\t\t\t\t\tonChangesSaved={onUsedAdded}\n\t\t\t\t\t\t\tsetIsModalOpen={setIsAddModalOpen}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t\t{isEditModalOpen && (\n\t\t\t\t\t\t<EditUserModal\n\t\t\t\t\t\t\tcloseModal={closeEditModal}\n\t\t\t\t\t\t\tdata={selectedUser}\n\t\t\t\t\t\t\tisModalOpen={isEditModalOpen}\n\t\t\t\t\t\t\tonUserUpdated={onUserUpdated}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</Suspense>\n\t\t\t</div>\n\t\t</>\n\t);\n}\n","import { cn } from '@/lib/cn';\n\nfunction Skeleton({ className, ...props }: React.ComponentProps<'div'>) {\n\treturn (\n\t\t<div\n\t\t\tdata-slot=\"skeleton\"\n\t\t\tclassName={cn('bg-primary/10 animate-pulse rounded-md', className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport { Skeleton };\n","import { Button } from '@/components/ui/button';\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';\nimport { getOAuthSignInUrl } from '@/lib/urls/getOAuthSignInUrl';\nimport { KeyRoundIcon } from 'lucide-react';\n\nexport function OAuthLockedOrgCard({\n\torganizationId,\n\torganizationName,\n\tproviders,\n}: {\n\torganizationId: string;\n\torganizationName?: string;\n\tproviders: Array<{ name: string; oauthConfigId: string }>;\n}) {\n\treturn (\n\t\t<Card className=\"relative h-full justify-between opacity-90\">\n\t\t\t<CardHeader>\n\t\t\t\t<CardDescription className=\"truncate\">{organizationId}</CardDescription>\n\t\t\t\t<CardTitle>\n\t\t\t\t\t<h2>{organizationName}</h2>\n\t\t\t\t</CardTitle>\n\t\t\t</CardHeader>\n\t\t\t<CardContent className=\"flex flex-col gap-2\">\n\t\t\t\t<p className=\"text-xs text-muted-foreground flex items-center gap-1.5 mb-1\">\n\t\t\t\t\t<KeyRoundIcon className=\"size-3 shrink-0\" />\n\t\t\t\t\tSign in with an OAuth provider to access this organization.\n\t\t\t\t</p>\n\t\t\t\t{providers.map((provider) => (\n\t\t\t\t\t<a key={provider.oauthConfigId} href={getOAuthSignInUrl(provider.oauthConfigId)}>\n\t\t\t\t\t\t<Button variant=\"outline\" className=\"w-full\">\n\t\t\t\t\t\t\tSign in with {provider.name}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</a>\n\t\t\t\t))}\n\t\t\t</CardContent>\n\t\t</Card>\n\t);\n}\n","import { z } from 'zod';\n\nexport const AddCouponSchema = z.object({\n\tcouponId: z\n\t\t.string()\n\t\t.nonempty({\n\t\t\tmessage: 'Please enter a coupon ID.',\n\t\t})\n\t\t.trim(),\n});\n\nexport type AddCouponType = z.infer<typeof AddCouponSchema>;\n","import { apiClient } from '@/config/apiClient';\nimport { useMutation } from '@tanstack/react-query';\n\nexport async function onAddCouponToOrganizationSubmit(\n\t{ organizationId, couponId }: { organizationId: string; couponId: string },\n) {\n\tconst { data } = await apiClient.post(\n\t\t'/Coupon' as any,\n\t\t{\n\t\t\torganizationId,\n\t\t\tcouponId,\n\t\t},\n\t\t{\n\t\t\tvalidateStatus: (status) => status >= 200 && status < 400 || status === 400 || status === 409,\n\t\t},\n\t);\n\treturn data;\n}\n\nexport function useAddCouponToOrganization() {\n\treturn useMutation({\n\t\tmutationFn: onAddCouponToOrganizationSubmit,\n\t});\n}\n","import { Button } from '@/components/ui/button';\nimport {\n\tDialog,\n\tDialogContent,\n\tDialogDescription,\n\tDialogFooter,\n\tDialogHeader,\n\tDialogTitle,\n} from '@/components/ui/dialog';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { AddCouponSchema, AddCouponType } from '@/features/organization/mutations/AddCouponSchema';\nimport { useAddCouponToOrganization } from '@/features/organization/mutations/addCouponToOrganization';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useCallback, useEffect } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\n\nexport function AddCouponModal({\n\torganizationId,\n\torganizationName,\n\tisOpen,\n\tonClose,\n}: {\n\torganizationId: string;\n\torganizationName?: string;\n\tisOpen: boolean;\n\tonClose: () => void;\n}) {\n\tconst { mutate, isPending } = useAddCouponToOrganization();\n\n\tconst form = useForm<AddCouponType>({\n\t\tresolver: zodResolver(AddCouponSchema),\n\t\tdefaultValues: {\n\t\t\tcouponId: '',\n\t\t},\n\t});\n\n\tconst { handleSubmit, control, reset } = form;\n\n\tuseEffect(() => {\n\t\tif (isOpen) {\n\t\t\treset({ couponId: '' });\n\t\t}\n\t}, [isOpen, reset]);\n\n\tconst onSubmit = useCallback(\n\t\t(values: AddCouponType) => {\n\t\t\tmutate(\n\t\t\t\t{ organizationId, couponId: values.couponId },\n\t\t\t\t{\n\t\t\t\t\tonSuccess: (error?: string) => {\n\t\t\t\t\t\tif (!error) {\n\t\t\t\t\t\t\ttoast.success('Success', {\n\t\t\t\t\t\t\t\tdescription: `Coupon \"${values.couponId}\" added to ${organizationName || organizationId}.`,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tonClose();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttoast.error('Error', {\n\t\t\t\t\t\t\t\tdescription: error || 'Failed to add coupon.',\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t\t[mutate, organizationId, organizationName, onClose],\n\t);\n\n\treturn (\n\t\t<Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>\n\t\t\t<DialogContent>\n\t\t\t\t<DialogHeader>\n\t\t\t\t\t<DialogTitle>Add Coupon</DialogTitle>\n\t\t\t\t\t<DialogDescription>\n\t\t\t\t\t\tAdd a coupon code to{' '}\n\t\t\t\t\t\t{organizationName || organizationId}. This coupon will be applied to the next billing cycle.\n\t\t\t\t\t\t<br />\n\t\t\t\t\t\tCoupons can be created in our{' '}\n\t\t\t\t\t\t<a\n\t\t\t\t\t\t\thref=\"https://dashboard.stripe.com/\"\n\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\trel=\"noreferrer\"\n\t\t\t\t\t\t\tclassName=\"text-purple hover:underline\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tStripe Dashboard\n\t\t\t\t\t\t</a>.\n\t\t\t\t\t</DialogDescription>\n\t\t\t\t</DialogHeader>\n\t\t\t\t<Form {...form}>\n\t\t\t\t\t<form onSubmit={handleSubmit(onSubmit)}>\n\t\t\t\t\t\t<div className=\"grid gap-4 py-4\">\n\t\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\t\t\tname=\"couponId\"\n\t\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t\t<FormItem className=\"grid items-center gap-4\">\n\t\t\t\t\t\t\t\t\t\t<FormLabel>Coupon ID</FormLabel>\n\t\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t\t\t\tplaceholder=\"e.g. 100OFF\"\n\t\t\t\t\t\t\t\t\t\t\t\tdisabled={isPending}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<DialogFooter>\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\tonClick={onClose}\n\t\t\t\t\t\t\t\tdisabled={isPending}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t<Button type=\"submit\" disabled={isPending}>\n\t\t\t\t\t\t\t\t{isPending ? 'Adding...' : 'Add Coupon'}\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t</DialogFooter>\n\t\t\t\t\t</form>\n\t\t\t\t</Form>\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n}\n","import { Badge } from '@/components/ui/badge';\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';\nimport {\n\tDropdownMenu,\n\tDropdownMenuContent,\n\tDropdownMenuItem,\n\tDropdownMenuLabel,\n\tDropdownMenuSeparator,\n\tDropdownMenuTrigger,\n} from '@/components/ui/dropdownMenu';\nimport { AddCouponModal } from '@/features/organization/modals/AddCouponModal';\nimport { useAdminMode } from '@/hooks/useAuth';\nimport { useOrganizationPermissions, useOrganizationRolePermissions } from '@/hooks/usePermissions';\nimport { capitalizeWords } from '@/lib/string/capitalizeWords';\nimport { Link } from '@tanstack/react-router';\nimport {\n\tArrowRight,\n\tCreditCardIcon,\n\tEllipsis,\n\tKeyRoundIcon,\n\tServerIcon,\n\tShieldCheckIcon,\n\tTicketIcon,\n\tTrash2Icon,\n\tUsersIcon,\n} from 'lucide-react';\nimport { useCallback, useState } from 'react';\n\nexport function OrgCard({\n\torganizationRole,\n\tonDeleteOrgModal,\n}: {\n\torganizationRole: { organizationId: string; organizationName?: string; roleName: string };\n\tonDeleteOrgModal: (OrganizationRole: { organizationId: string; organizationName?: string }) => void;\n}) {\n\tconst { organizationId, organizationName, roleName } = organizationRole;\n\tconst { remove, update: canUpdateOrganization } = useOrganizationPermissions(organizationId);\n\tconst showBilling = canUpdateOrganization;\n\tconst { view: showOrgUsersAndRoles } = useOrganizationRolePermissions(organizationId);\n\tconst isAdminMode = useAdminMode();\n\n\tconst [isCouponModalOpen, setIsCouponModalOpen] = useState(false);\n\n\tconst onDeleteClick = useCallback(() => {\n\t\tonDeleteOrgModal(organizationRole);\n\t}, [onDeleteOrgModal, organizationRole]);\n\n\treturn (\n\t\t<Card className=\"relative h-full justify-between hover:shadow-lg transition-shadow duration-200\">\n\t\t\t<CardHeader>\n\t\t\t\t<CardDescription className=\"flex items-center justify-between\">\n\t\t\t\t\t<span className=\"truncate\">{organizationId}</span>\n\t\t\t\t\t{remove && (\n\t\t\t\t\t\t<DropdownMenu>\n\t\t\t\t\t\t\t<DropdownMenuTrigger className=\"p-4 -m-4 -mr-6 hover:text-foreground\">\n\t\t\t\t\t\t\t\t<Ellipsis aria-label=\"Options\" />\n\t\t\t\t\t\t\t</DropdownMenuTrigger>\n\t\t\t\t\t\t\t<DropdownMenuContent>\n\t\t\t\t\t\t\t\t<DropdownMenuLabel className=\"text-gray-600 text-xs\">Options</DropdownMenuLabel>\n\t\t\t\t\t\t\t\t<DropdownMenuSeparator />\n\t\t\t\t\t\t\t\t<Link to={`${organizationId}`}>\n\t\t\t\t\t\t\t\t\t<DropdownMenuItem>\n\t\t\t\t\t\t\t\t\t\t<ServerIcon className=\"size-4 mr-2 text-blue-500\" />\n\t\t\t\t\t\t\t\t\t\tClusters\n\t\t\t\t\t\t\t\t\t</DropdownMenuItem>\n\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t{showOrgUsersAndRoles && (\n\t\t\t\t\t\t\t\t\t<Link to={`${organizationId}/roles`}>\n\t\t\t\t\t\t\t\t\t\t<DropdownMenuItem>\n\t\t\t\t\t\t\t\t\t\t\t<ShieldCheckIcon className=\"size-4 mr-2 text-purple\" />\n\t\t\t\t\t\t\t\t\t\t\tRoles\n\t\t\t\t\t\t\t\t\t\t</DropdownMenuItem>\n\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t{showOrgUsersAndRoles && (\n\t\t\t\t\t\t\t\t\t<Link to={`${organizationId}/users`}>\n\t\t\t\t\t\t\t\t\t\t<DropdownMenuItem>\n\t\t\t\t\t\t\t\t\t\t\t<UsersIcon className=\"size-4 mr-2 text-orange-500\" />\n\t\t\t\t\t\t\t\t\t\t\tUsers\n\t\t\t\t\t\t\t\t\t\t</DropdownMenuItem>\n\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t{showBilling && (\n\t\t\t\t\t\t\t\t\t<Link to={`${organizationId}/billing`}>\n\t\t\t\t\t\t\t\t\t\t<DropdownMenuItem>\n\t\t\t\t\t\t\t\t\t\t\t<CreditCardIcon className=\"size-4 mr-2 text-green-500\" />\n\t\t\t\t\t\t\t\t\t\t\tBilling\n\t\t\t\t\t\t\t\t\t\t</DropdownMenuItem>\n\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t{canUpdateOrganization && (\n\t\t\t\t\t\t\t\t\t<Link to={`${organizationId}/settings`}>\n\t\t\t\t\t\t\t\t\t\t<DropdownMenuItem>\n\t\t\t\t\t\t\t\t\t\t\t<KeyRoundIcon className=\"size-4 mr-2 text-yellow-500\" />\n\t\t\t\t\t\t\t\t\t\t\tSettings\n\t\t\t\t\t\t\t\t\t\t</DropdownMenuItem>\n\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t{isAdminMode && (\n\t\t\t\t\t\t\t\t\t<DropdownMenuItem onClick={() => setIsCouponModalOpen(true)}>\n\t\t\t\t\t\t\t\t\t\t<TicketIcon className=\"size-4 mr-2 text-pink-500\" />\n\t\t\t\t\t\t\t\t\t\tAdd Coupon\n\t\t\t\t\t\t\t\t\t</DropdownMenuItem>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t<DropdownMenuSeparator />\n\t\t\t\t\t\t\t\t{remove && (\n\t\t\t\t\t\t\t\t\t<DropdownMenuItem\n\t\t\t\t\t\t\t\t\t\tclassName=\"focus:bg-red/70 focus:text-white\"\n\t\t\t\t\t\t\t\t\t\tonClick={onDeleteClick}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<Trash2Icon className=\"size-4 mr-2 text-red-500\" />\n\t\t\t\t\t\t\t\t\t\tDelete\n\t\t\t\t\t\t\t\t\t</DropdownMenuItem>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</DropdownMenuContent>\n\t\t\t\t\t\t</DropdownMenu>\n\t\t\t\t\t)}\n\t\t\t\t</CardDescription>\n\t\t\t\t<CardTitle>\n\t\t\t\t\t<h2>{organizationName}</h2>\n\t\t\t\t</CardTitle>\n\t\t\t</CardHeader>\n\t\t\t<CardContent className=\"flex justify-between\">\n\t\t\t\t<Badge>{capitalizeWords(roleName)}</Badge>\n\t\t\t\t<Link\n\t\t\t\t\tto={organizationId}\n\t\t\t\t\tclassName=\"text-sm\"\n\t\t\t\t\taria-label={`View ${organizationName}`}\n\t\t\t\t\ttitle={`View ${organizationName}`}\n\t\t\t\t>\n\t\t\t\t\t<span className=\"py-2 transition-all duration-100 ease-in-out border-0 hover:border-b-2\">\n\t\t\t\t\t\tView <ArrowRight className=\"inline-block\" />\n\t\t\t\t\t</span>\n\t\t\t\t</Link>\n\t\t\t</CardContent>\n\t\t\t<AddCouponModal\n\t\t\t\torganizationId={organizationId}\n\t\t\t\torganizationName={organizationName}\n\t\t\t\tisOpen={isCouponModalOpen}\n\t\t\t\tonClose={() => setIsCouponModalOpen(false)}\n\t\t\t/>\n\t\t</Card>\n\t);\n}\n","import { apiClient } from '@/config/apiClient';\nimport { useMutation } from '@tanstack/react-query';\n\nexport async function onDeleteOrganization(orgId: string) {\n\tconst { data } = await apiClient.delete(`/Organization/${orgId}` as '/Organization/{id}');\n\treturn data;\n}\n\nexport function useDeleteOrganizationMutation() {\n\treturn useMutation({\n\t\tmutationFn: (orgId: string) => onDeleteOrganization(orgId),\n\t});\n}\n","import { apiClient } from '@/config/apiClient';\nimport { SchemaOrganization } from '@/integrations/api/api.gen';\nimport { useMutation } from '@tanstack/react-query';\n\nasync function onNewOrganizationSubmit(newOrg: Omit<SchemaOrganization, 'id' | 'type'>): Promise<SchemaOrganization> {\n\tconst { data } = await apiClient.post('/Organization/', {\n\t\t...newOrg,\n\t});\n\treturn data;\n}\n\nexport function useCreateNewOrganizationMutation() {\n\treturn useMutation<SchemaOrganization, Error, Omit<SchemaOrganization, 'id' | 'type'>>({\n\t\tmutationFn: (clusterInfo) => onNewOrganizationSubmit(clusterInfo),\n\t});\n}\n","import { z } from 'zod';\n\nexport const specifiedSubdomain = z\n\t.string()\n\t.max(62, { error: 'Must be at most 62 characters long.' })\n\t.regex(/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/, {\n\t\terror:\n\t\t\t'Please only use lowercase letters, digits and dashes (-) in the subdomain. Must not start or end with a dash.',\n\t});\n\nexport const NewOrganizationSchema = z.object({\n\tname: z\n\t\t.string()\n\t\t.max(255, {\n\t\t\terror: 'Name cannot be longer than 255 characters.',\n\t\t}),\n\tsubdomain: z.union([\n\t\tz.literal(''),\n\t\tz.undefined(),\n\t\tspecifiedSubdomain,\n\t]).optional(),\n});\n","import { Button } from '@/components/ui/button';\nimport { DialogFooter } from '@/components/ui/dialog';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { currentUserQueryKey } from '@/features/auth/queries/getCurrentUser';\nimport { authStore, OverallAppSignIn } from '@/features/auth/store/authStore';\nimport { useCreateNewOrganizationMutation } from '@/features/organizations/hooks/useCreateNewOrganization';\nimport { NewOrganizationSchema, specifiedSubdomain } from '@/features/organizations/mutations/newOrganizationSchema';\nimport { useCloudAuth } from '@/hooks/useAuth';\nimport { collapseKebabsToMaxLength } from '@/lib/string/collapseKebabsToMaxLength';\nimport { toKebabCase } from '@/lib/string/to-kebab-case';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { useNavigate } from '@tanstack/react-router';\nimport { ArrowRight } from 'lucide-react';\nimport { useCallback, useEffect, useMemo } from 'react';\nimport { useForm } from 'react-hook-form';\nimport z from 'zod';\n\nexport function NewOrgForm() {\n\tconst { user } = useCloudAuth();\n\tconst navigate = useNavigate();\n\n\tconst form = useForm({\n\t\tresolver: zodResolver(NewOrganizationSchema),\n\t\tdefaultValues: {\n\t\t\tname: '',\n\t\t\tsubdomain: '',\n\t\t},\n\t});\n\tconst { setFocus, watch } = form;\n\n\tuseEffect(() => {\n\t\tsetFocus('name');\n\t}, [setFocus]);\n\n\tconst defaultName = `${user?.firstname} ${user?.lastname} Org`;\n\tconst name = watch('name') || defaultName;\n\tconst subdomain = watch('subdomain');\n\tconst calculatedNames = useMemo(() => {\n\t\tconst suggestedSubdomain = collapseKebabsToMaxLength(\n\t\t\ttoKebabCase(name),\n\t\t\tspecifiedSubdomain.maxLength!,\n\t\t);\n\t\treturn {\n\t\t\tsuggestedSubdomain,\n\t\t\tfullHostName: `future-cluster-names.${subdomain || suggestedSubdomain}.harperfabric.com`,\n\t\t};\n\t}, [name, subdomain]);\n\n\tconst { mutate: submitNewOrganizationData, isPending } = useCreateNewOrganizationMutation();\n\tconst queryClient = useQueryClient();\n\n\tconst submitForm = useCallback(async (formData: z.infer<typeof NewOrganizationSchema>) => {\n\t\tsubmitNewOrganizationData({\n\t\t\tname: formData.name || defaultName,\n\t\t\tsubdomain: formData.subdomain || calculatedNames.suggestedSubdomain,\n\t\t}, {\n\t\t\tonSuccess: (newOrg) => {\n\t\t\t\tqueryClient.invalidateQueries({ queryKey: currentUserQueryKey, refetchType: 'active' });\n\t\t\t\tauthStore.reloadUser(OverallAppSignIn);\n\t\t\t\tvoid navigate({ to: `/${newOrg.id}` });\n\t\t\t},\n\t\t});\n\t}, [calculatedNames.suggestedSubdomain, queryClient, submitNewOrganizationData, defaultName, navigate]);\n\n\treturn (\n\t\t<>\n\t\t\t<Form {...form}>\n\t\t\t\t<form\n\t\t\t\t\tid=\"org-add-form\"\n\t\t\t\t\tname=\"org-add-form\"\n\t\t\t\t\tonSubmit={form.handleSubmit(submitForm)}\n\t\t\t\t\tclassName=\"grid gap-6 text-foreground max-w-xl\"\n\t\t\t\t>\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\tname=\"name\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Name</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\tmaxLength={NewOrganizationSchema.shape.name.maxLength!}\n\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"words\"\n\t\t\t\t\t\t\t\t\t\tplaceholder={defaultName}\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\tname=\"subdomain\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Subdomain</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\tmaxLength={specifiedSubdomain.maxLength!}\n\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"none\"\n\t\t\t\t\t\t\t\t\t\tplaceholder={calculatedNames.suggestedSubdomain}\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t<FormLabel className=\"pb-1\">Full Host Name</FormLabel>\n\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t<span>{calculatedNames.fullHostName}</span>\n\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t</FormItem>\n\n\t\t\t\t\t<DialogFooter>\n\t\t\t\t\t\t<Button type=\"submit\" variant=\"submit\" className=\"rounded-full\" disabled={isPending}>\n\t\t\t\t\t\t\tCreate New Organization <ArrowRight />\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</DialogFooter>\n\t\t\t\t</form>\n\t\t\t</Form>\n\t\t</>\n\t);\n}\n","import { SubNavMenu } from '@/components/SubNavMenu';\nimport { NewOrgForm } from '@/features/organizations/components/NewOrgForm';\n\nexport function NewOrg() {\n\treturn (\n\t\t<>\n\t\t\t<SubNavMenu />\n\t\t\t<section className=\"mt-32 px-4 pt-4 md:px-12 min-h-[calc(100vh-theme(spacing.32))]\">\n\t\t\t\t<NewOrgForm />\n\t\t\t</section>\n\t\t</>\n\t);\n}\n","import { apiClient } from '@/config/apiClient';\nimport { Organization } from '@/integrations/api/api.patch';\nimport { keepPreviousData, queryOptions } from '@tanstack/react-query';\n\n// Server-side page size for the fabric admin \"all organizations\" view. Sized\n// to roughly one screen of cards: full rows at every breakpoint (3 per row at\n// md, 4 at lg, 6 at 2xl).\nexport const ALL_ORGANIZATIONS_PAGE_SIZE = 12;\n\nexport interface AllOrganizationsPage {\n\torganizations: Organization[];\n\thasNextPage: boolean;\n}\n\n/**\n * Builds the Harper REST query for one page of the admin organization list.\n * Harper collections return a bare array (no total count), so we request one\n * record past the page boundary to learn whether a next page exists.\n */\nexport function buildAllOrganizationsUrl(pageIndex: number, nameFilter: string): string {\n\tconst start = pageIndex * ALL_ORGANIZATIONS_PAGE_SIZE;\n\tconst conditions = [\n\t\t// The name filter must precede the status condition: with status first,\n\t\t// the API ignores the name condition entirely.\n\t\t...(nameFilter ? [`name=ct=${encodeURIComponent(nameFilter)}`] : []),\n\t\t// Terminated organizations stick around with status DELETED; hide them.\n\t\t'status=ne=DELETED',\n\t\t'sort(name)',\n\t\t`limit(${start},${start + ALL_ORGANIZATIONS_PAGE_SIZE + 1})`,\n\t];\n\treturn `/Admin/Organization/?${conditions.join('&')}`;\n}\n\nexport async function getAllOrganizations(pageIndex: number, nameFilter: string): Promise<AllOrganizationsPage> {\n\tconst { data } = await apiClient.get(buildAllOrganizationsUrl(pageIndex, nameFilter) as '/Organization/');\n\treturn {\n\t\torganizations: data.slice(0, ALL_ORGANIZATIONS_PAGE_SIZE),\n\t\thasNextPage: data.length > ALL_ORGANIZATIONS_PAGE_SIZE,\n\t};\n}\n\nexport function getAllOrganizationsQueryOptions(pageIndex: number, nameFilter: string) {\n\treturn queryOptions({\n\t\tqueryKey: ['admin-all-organizations', nameFilter, pageIndex],\n\t\tqueryFn: () => getAllOrganizations(pageIndex, nameFilter),\n\t\t// Keep the previous page on screen while the next one loads.\n\t\tplaceholderData: keepPreviousData,\n\t\tretry: false,\n\t});\n}\n","import { useEffect, useState } from 'react';\n\n/**\n * useDebounce hook\n * Returns a debounced version of a changing value after the specified delay.\n *\n * Example:\n * const debouncedSearch = useDebounce(search, 300);\n */\nexport function useDebounce<T>(value: T, delay: number = 300, hasher?: (value: T) => string): T {\n\tconst [debouncedValue, setDebouncedValue] = useState<T>(value);\n\n\tconst hashed = hasher ? hasher(value) : value;\n\tuseEffect(() => {\n\t\tconst timer = setTimeout(() => setDebouncedValue(value), delay);\n\t\treturn () => clearTimeout(timer);\n\t\t// We watch the hashed value, and the delay, so that we can decide when to bust the state.\n\t\t// We don't watch value directly because \"hashed\" watches it for us.\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [hashed, delay]);\n\n\treturn debouncedValue;\n}\n","// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function shallowCompareObjects(a: any, b: any): boolean {\n\t// Handle edge cases\n\tif (a === b) { return true; }\n\tif (!a || !b) { return false; }\n\n\tconst aKeys = Object.keys(a);\n\tconst bKeys = Object.keys(b);\n\n\tif (aKeys.length !== bKeys.length) {\n\t\treturn false;\n\t}\n\n\t// Check if every key in a exists in b and has the same value\n\tfor (const key of aKeys) {\n\t\tif (!bKeys.includes(key) || a[key] !== b[key]) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n","import { shallowCompareObjects } from '@/lib/arrays/shallowCompareObjects';\nimport { Dispatch, SetStateAction, useEffect, useState } from 'react';\n\nexport function useEffectedState<S>(initialState: S, deps: unknown): [S, Dispatch<SetStateAction<S>>] {\n\tconst [currentDeps, setDeps] = useState(deps);\n\tconst [currentState, setCurrentState] = useState<S>(initialState);\n\n\t// Use the proper React hook so we can update the state more permanently.\n\tuseEffect(() => {\n\t\tif (!shallowCompareObjects(currentDeps, deps)) {\n\t\t\t// We watch and decide if the deps change on our own, which lets us wipe out the old state at the same time.\n\t\t\t// eslint-disable-next-line react-hooks/set-state-in-effect\n\t\t\tsetDeps(deps);\n\t\t\tsetCurrentState(initialState);\n\t\t}\n\t}, [currentDeps, deps, initialState]);\n\n\t// But also watch it so we can immediately patch the state.\n\tif (!shallowCompareObjects(currentDeps, deps)) {\n\t\treturn [initialState, setCurrentState];\n\t}\n\n\treturn [currentState, setCurrentState];\n}\n","import { WatchedValueKeys, WatchedValuesTypeMap } from '@/lib/storage/watchedValueKeys';\nimport { useCallback, useEffect } from 'react';\n\nconst listenersMap: Record<string, Array<(newValue: unknown, trigger?: unknown) => void>> = {};\n\nexport function useListener<K extends keyof WatchedValuesTypeMap, T extends WatchedValuesTypeMap[K]>(\n\tname: K,\n\tlistener: (newValue: T, trigger?: unknown) => void,\n\tdeps: unknown,\n) {\n\t// eslint-disable-next-line react-hooks/preserve-manual-memoization,react-hooks/exhaustive-deps\n\tconst callback = useCallback((newValue: T, trigger?: unknown) => listener(newValue, trigger), [deps]);\n\tuseEffect(() => {\n\t\tif (!listenersMap[name]) {\n\t\t\tlistenersMap[name] = [];\n\t\t}\n\t\tlistenersMap[name].push(callback as (newValue: unknown, trigger?: unknown) => void);\n\n\t\treturn function cleanUp() {\n\t\t\tconst index = listenersMap[name].indexOf(callback as (newValue: unknown, trigger?: unknown) => void);\n\t\t\tif (index >= 0) {\n\t\t\t\tlistenersMap[name].splice(index, 1);\n\t\t\t}\n\t\t};\n\t}, [name, listener, callback]);\n}\n\nexport function emitToListeners<K extends keyof WatchedValuesTypeMap, T extends WatchedValuesTypeMap[K]>(\n\tname: K,\n\tvalue: T,\n\ttrigger?: unknown,\n): void {\n\tconst listeners = listenersMap[name];\n\tif (listeners) {\n\t\tfor (const listener of listeners) {\n\t\t\tlistener(value, trigger);\n\t\t}\n\t}\n}\n\nexport function curryEmitToListeners<K extends keyof WatchedValuesTypeMap, T extends WatchedValuesTypeMap[K]>(\n\tname: K,\n\tvalue: T,\n\ttrigger?: unknown,\n): (e?: unknown) => void {\n\treturn (e?: unknown) => emitToListeners(name, value, trigger ?? e);\n}\n\nexport function useEmitToListeners<K extends keyof WatchedValuesTypeMap, T extends WatchedValuesTypeMap[K]>(\n\tname: WatchedValueKeys,\n\tvalue: T,\n\ttrigger?: unknown,\n): () => void {\n\treturn useCallback((e?: unknown) => emitToListeners(name, value, trigger ?? e), [name, value, trigger]);\n}\n","import { SessionStorageKeys } from '@/lib/storage/sessionStorageKeys';\nimport { safeParse } from '@/lib/string/safeParse';\n\n/**\n * Retrieves a value from session storage.\n * @param key\n * @param defaultValue\n */\nexport function getSessionStorage<T, K extends keyof SessionStorageKeys>(key: K, defaultValue: T): T {\n\tconst lastSetValue = safeParse<T>(sessionStorage.getItem(String(key)));\n\treturn lastSetValue ?? defaultValue;\n}\n","import { SessionStorageKeys } from '@/lib/storage/sessionStorageKeys';\n\n/**\n * Stores a value in session storage for later retrieval.\n * @param key\n * @param current\n */\nexport function setSessionStorage<T, K extends keyof SessionStorageKeys>(key: K, current: T): void {\n\tif (current === null || current === undefined) {\n\t\tsessionStorage.removeItem(String(key));\n\t} else {\n\t\tsessionStorage.setItem(String(key), JSON.stringify(current));\n\t}\n}\n","import { useEffectedState } from '@/hooks/useEffectedState';\nimport { emitToListeners, useListener } from '@/lib/events/listener';\nimport { getSessionStorage } from '@/lib/storage/getSessionStorage';\nimport { SessionStorageKeys } from '@/lib/storage/sessionStorageKeys';\nimport { setSessionStorage } from '@/lib/storage/setSessionStorage';\nimport { useEffect } from 'react';\n\n/**\n * Uses state that gets bootstrapped from and persists to session storage with the key you specify.\n * @param key\n * @param defaultValue\n */\nexport function useSessionStorage<T, K extends keyof SessionStorageKeys>(\n\tkey: K,\n\tdefaultValue: T,\n): [T, (value: ((prevState: T) => T) | T) => void] {\n\tconst state = useEffectedState<T>(getSessionStorage(key, defaultValue), [key]);\n\tconst [current, setCurrent] = state;\n\n\tuseEffect(() => {\n\t\tsetSessionStorage(key, current);\n\t\temitToListeners(`Session:${key}` as 'Session:{key}', current);\n\t}, [key, current]);\n\n\tuseListener(`Session:${key}` as 'Session:{key}', function watchForInternalStorageChanges(newValue: T) {\n\t\tif (current !== newValue) {\n\t\t\tsetCurrent(newValue);\n\t\t}\n\t}, [current, key, defaultValue]);\n\n\tuseEffect(function watchForExternalStorageChanges() {\n\t\tconst storageListener = (event: StorageEvent) => {\n\t\t\tif (event.key === key) {\n\t\t\t\tsetCurrent(getSessionStorage(key, defaultValue));\n\t\t\t}\n\t\t};\n\t\twindow.addEventListener('storage', storageListener);\n\t\treturn () => {\n\t\t\twindow.removeEventListener('storage', storageListener);\n\t\t};\n\t}, [key, setCurrent, defaultValue]);\n\n\treturn state;\n}\n","import { ConfirmDeletionModal } from '@/components/ConfirmDeletionModal';\nimport { SubNavMenu } from '@/components/SubNavMenu';\nimport { Button } from '@/components/ui/button';\nimport { Input } from '@/components/ui/input';\nimport { Skeleton } from '@/components/ui/skeleton';\nimport { Switch } from '@/components/ui/switch';\nimport { getCurrentUserQueryOptions } from '@/features/auth/queries/getCurrentUser';\nimport { OAuthLockedOrgCard } from '@/features/organizations/components/OAuthLockedOrgCard';\nimport { OrgCard } from '@/features/organizations/components/OrgCard';\nimport { useDeleteOrganizationMutation } from '@/features/organizations/mutations/deleteOrganization';\nimport { NewOrg } from '@/features/organizations/NewOrg';\nimport {\n\tALL_ORGANIZATIONS_PAGE_SIZE,\n\tgetAllOrganizationsQueryOptions,\n} from '@/features/organizations/queries/getAllOrganizations';\nimport { useAdminMode } from '@/hooks/useAuth';\nimport { useDebounce } from '@/hooks/useDebounce';\nimport { useSessionStorage } from '@/hooks/useSessionStorage';\nimport { curryFilterByFuzzySearch } from '@/lib/string/filterByFuzzySearch';\nimport { useQuery, useQueryClient, useSuspenseQuery } from '@tanstack/react-query';\nimport { Link, Navigate, useSearch } from '@tanstack/react-router';\nimport { ArrowLeftIcon, ArrowRightIcon, PlusIcon } from 'lucide-react';\nimport { FormEvent, useCallback, useMemo, useState } from 'react';\nimport { toast } from 'sonner';\n\nexport function OrganizationsIndex() {\n\tconst queryClient = useQueryClient();\n\tconst { data: user } = useSuspenseQuery(getCurrentUserQueryOptions());\n\tconst { mutate: deleteOrg, isPending: isDeletingOrgPending } = useDeleteOrganizationMutation();\n\n\tconst [isDeleteOrgModalOpen, setIsDeleteOrgModalOpen] = useState(false);\n\tconst [deleteOrgInfo, setDeleteOrgInfo] = useState<\n\t\tnull | {\n\t\t\torganizationId: string;\n\t\t\torganizationName?: string;\n\t\t}\n\t>(null);\n\n\tconst [filterByNameValue, setFilterByNameValue] = useState('');\n\tconst clearFilterByNameValue = useCallback(() => setFilterByNameValue(''), []);\n\n\tconst isAdminMode = useAdminMode();\n\tconst [showAllOrgs, setShowAllOrgs] = useSessionStorage('ShowAllOrganizations', false);\n\tconst [pageIndex, setPageIndex] = useState(0);\n\tconst showAll = isAdminMode && showAllOrgs;\n\n\tconst onShowAllOrgsChanged = useCallback((checked: boolean) => {\n\t\tsetShowAllOrgs(checked);\n\t\tsetPageIndex(0);\n\t}, [setShowAllOrgs]);\n\n\t// In the admin view, filtering happens server-side; debounce so we don't\n\t// issue a request per keystroke.\n\tconst debouncedFilterValue = useDebounce(filterByNameValue, 300);\n\tconst { data: allOrgsPage, isPending: isAllOrgsPending } = useQuery({\n\t\t...getAllOrganizationsQueryOptions(pageIndex, debouncedFilterValue),\n\t\tenabled: showAll,\n\t});\n\n\tconst { organizationRoles, oauthLockedOrgs } = useMemo(() => {\n\t\tconst roles = user?.roles || {};\n\t\tconst normal: Array<{ organizationId: string; organizationName?: string; roleName: string }> = [];\n\t\tconst locked: Array<\n\t\t\t{ organizationId: string; organizationName?: string; providers: Array<{ name: string; oauthConfigId: string }> }\n\t\t> = [];\n\n\t\tfor (const [organizationId, role] of Object.entries(roles)) {\n\t\t\t// Fabric admins / super users bypass an org's OAuth requirement, so never\n\t\t\t// lock their cards — render the org normally even when it requires OAuth.\n\t\t\tif ('oauthProviders' in role && !isAdminMode) {\n\t\t\t\tlocked.push({ organizationId, organizationName: role.organizationName, providers: role.oauthProviders! });\n\t\t\t} else {\n\t\t\t\tnormal.push({ organizationId, organizationName: role.organizationName, roleName: role.role ?? 'fabric admin' });\n\t\t\t}\n\t\t}\n\n\t\tconst filteredNormal = normal\n\t\t\t.filter(curryFilterByFuzzySearch(['organizationId', 'organizationName'], filterByNameValue))\n\t\t\t.sort((a, b) => ((a.organizationName || '') > (b.organizationName || '') ? 1 : -1));\n\n\t\treturn { organizationRoles: filteredNormal, oauthLockedOrgs: locked };\n\t}, [filterByNameValue, user?.roles, isAdminMode]);\n\n\t// Roles for organizations the fabric admin is fetching server-side. Falls\n\t// back to \"fabric admin\" for organizations the user has no role in.\n\tconst allOrganizationRoles = useMemo(() => {\n\t\tconst roles = user?.roles || {};\n\t\treturn (allOrgsPage?.organizations || []).map((org) => ({\n\t\t\torganizationId: org.id,\n\t\t\torganizationName: org.name,\n\t\t\troleName: roles[org.id]?.role || 'fabric admin',\n\t\t}));\n\t}, [allOrgsPage?.organizations, user?.roles]);\n\n\tconst displayedOrganizationRoles = showAll ? allOrganizationRoles : organizationRoles;\n\n\tconst onFilterByNameChanged = useCallback((e: FormEvent<HTMLInputElement>) => {\n\t\t// Keep the raw casing: the fuzzy filter lowercases internally, and the\n\t\t// server-side admin filter wants the value as typed.\n\t\tsetFilterByNameValue(e.currentTarget.value || '');\n\t\tsetPageIndex(0);\n\t}, []);\n\n\tconst handleDeleteOrg = useCallback(\n\t\t(org: { organizationId: string; organizationName?: string }) => {\n\t\t\tif (org?.organizationId) {\n\t\t\t\tdeleteOrg(org.organizationId, {\n\t\t\t\t\tonSuccess: () => {\n\t\t\t\t\t\ttoast.success('Success', {\n\t\t\t\t\t\t\tdescription: `Organization successfully deleted.`,\n\t\t\t\t\t\t\tduration: 5000,\n\t\t\t\t\t\t\taction: {\n\t\t\t\t\t\t\t\tlabel: 'Dismiss',\n\t\t\t\t\t\t\t\tonClick: () => toast.dismiss(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t\tvoid queryClient.invalidateQueries({ queryKey: [] });\n\t\t\t\t\t\tsetIsDeleteOrgModalOpen(false);\n\t\t\t\t\t},\n\t\t\t\t\tonError: () => setIsDeleteOrgModalOpen(false),\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\t[deleteOrg, queryClient, setIsDeleteOrgModalOpen],\n\t);\n\n\tconst onDeleteOrgModal = useCallback((orgRole: { organizationId: string; organizationName?: string }) => {\n\t\tsetDeleteOrgInfo(orgRole);\n\t\tsetIsDeleteOrgModalOpen(true);\n\t}, []);\n\n\tconst { createCluster }: { createCluster?: string } = useSearch({ strict: false });\n\n\tif (!showAll && organizationRoles.length === 1 && !filterByNameValue.length && createCluster) {\n\t\treturn <Navigate to={`/${organizationRoles[0].organizationId}/new-cluster`} replace={true} />;\n\t}\n\n\tif (!showAll && !organizationRoles.length && !oauthLockedOrgs.length && !filterByNameValue.length) {\n\t\treturn <NewOrg />;\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t<SubNavMenu>\n\t\t\t\t<div className=\"flex w-full items-center justify-end gap-2\">\n\t\t\t\t\t{isAdminMode && (\n\t\t\t\t\t\t<label className=\"flex shrink-0 cursor-pointer items-center gap-2 text-xs\">\n\t\t\t\t\t\t\t<Switch\n\t\t\t\t\t\t\t\tchecked={showAllOrgs}\n\t\t\t\t\t\t\t\tonCheckedChange={onShowAllOrgsChanged}\n\t\t\t\t\t\t\t\taria-label=\"Show all organizations\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<span className=\"hidden sm:inline-block\">All Orgs</span>\n\t\t\t\t\t\t</label>\n\t\t\t\t\t)}\n\t\t\t\t\t<Input\n\t\t\t\t\t\tplaceholder=\"Filter by name\"\n\t\t\t\t\t\tclassName=\"inline-block w-full text-xs\"\n\t\t\t\t\t\tvalue={filterByNameValue}\n\t\t\t\t\t\tonChange={onFilterByNameChanged}\n\t\t\t\t\t/>\n\t\t\t\t\t<Link to=\"/new-org\">\n\t\t\t\t\t\t<Button variant=\"positive\" accessKey=\"n\">\n\t\t\t\t\t\t\t<PlusIcon />\n\t\t\t\t\t\t\t<span className=\"hidden sm:inline-block\">\n\t\t\t\t\t\t\t\t<u>N</u>ew <span className=\"hidden md:inline-block\">Organization</span>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</Link>\n\t\t\t\t</div>\n\t\t\t</SubNavMenu>\n\t\t\t<section className=\"mt-32 px-4 pt-4 md:px-12 min-h-[calc(100vh-theme(spacing.32))]\">\n\t\t\t\t<div className=\"grid grid-cols-1 gap-4 md:grid-cols-12\">\n\t\t\t\t\t{/* OAuth-locked orgs only apply to the user's own orgs, not the admin show-all listing. */}\n\t\t\t\t\t{!showAll && oauthLockedOrgs.map((lockedOrg) => (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tkey={lockedOrg.organizationId}\n\t\t\t\t\t\t\tclassName=\"col-span-1 md:col-span-4 lg:col-span-3 2xl:col-span-2\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<OAuthLockedOrgCard\n\t\t\t\t\t\t\t\torganizationId={lockedOrg.organizationId}\n\t\t\t\t\t\t\t\torganizationName={lockedOrg.organizationName}\n\t\t\t\t\t\t\t\tproviders={lockedOrg.providers}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t))}\n\t\t\t\t\t{showAll && isAllOrgsPending\n\t\t\t\t\t\t? Array.from({ length: ALL_ORGANIZATIONS_PAGE_SIZE }, (_, index) => (\n\t\t\t\t\t\t\t<Skeleton\n\t\t\t\t\t\t\t\tkey={index}\n\t\t\t\t\t\t\t\tclassName=\"col-span-1 h-40 md:col-span-4 lg:col-span-3 2xl:col-span-2\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t))\n\t\t\t\t\t\t: displayedOrganizationRoles.map((organizationRole) => (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tkey={organizationRole.organizationId}\n\t\t\t\t\t\t\t\tclassName=\"col-span-1 md:col-span-4 lg:col-span-3 2xl:col-span-2\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<OrgCard organizationRole={organizationRole} onDeleteOrgModal={onDeleteOrgModal} />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t))}\n\t\t\t\t\t{!displayedOrganizationRoles.length && !(showAll && isAllOrgsPending) && (showAll || !oauthLockedOrgs.length)\n\t\t\t\t\t\t&& (\n\t\t\t\t\t\t\t<div className=\"col-span-1 md:col-span-12 text-center\">\n\t\t\t\t\t\t\t\t<h2 className=\"my-4 text-xl\">No matches found.</h2>\n\t\t\t\t\t\t\t\t<Button variant=\"outline\" onClick={clearFilterByNameValue}>Clear Filters</Button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t{showAll && (pageIndex > 0 || allOrgsPage?.hasNextPage) && (\n\t\t\t\t\t<div className=\"flex items-center justify-center gap-4 py-6\">\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tvariant=\"defaultOutline\"\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\tclassName=\"select-none\"\n\t\t\t\t\t\t\tdisabled={pageIndex === 0}\n\t\t\t\t\t\t\tonClick={() => setPageIndex((index) => index - 1)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<ArrowLeftIcon />\n\t\t\t\t\t\t\tPrevious\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t<span className=\"text-sm text-gray-500 dark:text-gray-400\">Page {pageIndex + 1}</span>\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tvariant=\"defaultOutline\"\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\tclassName=\"select-none\"\n\t\t\t\t\t\t\tdisabled={!allOrgsPage?.hasNextPage}\n\t\t\t\t\t\t\tonClick={() => setPageIndex((index) => index + 1)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tNext\n\t\t\t\t\t\t\t<ArrowRightIcon />\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</section>\n\t\t\t{deleteOrgInfo && (\n\t\t\t\t<ConfirmDeletionModal\n\t\t\t\t\ttypeOfThingBeingDeleted=\"organization\"\n\t\t\t\t\tnameOfThingBeingDeleted={deleteOrgInfo.organizationName}\n\t\t\t\t\tisModalOpen={isDeleteOrgModalOpen}\n\t\t\t\t\tsetIsModalOpen={() => setIsDeleteOrgModalOpen(false)}\n\t\t\t\t\tdeletionConfirmed={() => handleDeleteOrg(deleteOrgInfo)}\n\t\t\t\t\tdeletionPending={isDeletingOrgPending}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</>\n\t);\n}\n","import { Loading } from '@/components/Loading';\nimport { Navbar } from '@/components/Navbar';\nimport { useOverallAuth } from '@/hooks/useAuth';\nimport { useLocalStorage } from '@/hooks/useLocalStorage';\nimport { LocalStorageKeys } from '@/lib/storage/localStorageKeys';\nimport { Outlet, useSearch } from '@tanstack/react-router';\nimport { useEffect } from 'react';\n\nexport function Dashboard() {\n\tconst { isLoading: isUserLoading } = useOverallAuth();\n\tconst { createCluster }: { createCluster?: string } = useSearch({ strict: false });\n\tconst [, setSavedClusterState] = useLocalStorage<unknown | null>(LocalStorageKeys.SavedClusterState, null);\n\tuseEffect(() => {\n\t\tif (createCluster) {\n\t\t\tsetSavedClusterState(createCluster);\n\t\t}\n\t}, [createCluster, setSavedClusterState]);\n\n\tif (isUserLoading) {\n\t\treturn <Loading className=\"fixed z-50 translate-1/2\" />;\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t<header className=\"fixed top-0 z-40 w-full h-20 p-4 bg-gradient-to-r from-violet-100 to-white border-b border-violet-200 dark:from-purple-950 dark:to-zinc-900 dark:border-purple-950 md:px-12\">\n\t\t\t\t<Navbar />\n\t\t\t</header>\n\t\t\t<main>\n\t\t\t\t<Outlet />\n\t\t\t</main>\n\t\t</>\n\t);\n}\n","import { currentUrlAfterHash } from '@/lib/urls/currentUrlAfterHash';\n\nconst ignoredUrls = [\n\t'/',\n\t'/forgot-password',\n\t'/reset-password',\n\t'/sign-in',\n\t'/sign-up',\n\t'/verify-email',\n];\n\nexport function buildRedirectInSearch() {\n\tconst url = currentUrlAfterHash();\n\treturn !ignoredUrls.includes(url) && { redirect: url };\n}\n","import { OverallAppSignIn } from '@/features/auth/store/authStore';\nimport { Dashboard } from '@/features/layouts/Dashboard';\nimport { buildRedirectInSearch } from '@/lib/urls/buildRedirectInSearch';\nimport { rootRoute } from '@/router/rootRoute';\nimport { createRoute, redirect } from '@tanstack/react-router';\n\nexport const dashboardLayout = createRoute({\n\tgetParentRoute: () => rootRoute,\n\tid: '_dashboardLayout',\n\tcomponent: Dashboard,\n\tbeforeLoad: ({ context }) => {\n\t\tconst auth = context.authentication[OverallAppSignIn];\n\t\tif (auth && !auth.isLoading && !auth.user) {\n\t\t\tthrow redirect({\n\t\t\t\tto: '/sign-in',\n\t\t\t\tsearch: buildRedirectInSearch(),\n\t\t\t});\n\t\t}\n\t},\n});\n","import { OrganizationsIndex } from '@/features/organizations/index';\nimport { NewOrg } from '@/features/organizations/NewOrg';\nimport { dashboardLayout } from '@/router/dashboardRoute';\nimport { createRoute } from '@tanstack/react-router';\n\nexport const orgsLayoutRoute = createRoute({\n\tgetParentRoute: () => dashboardLayout,\n\tid: '_orgsLayout',\n});\n\nconst orgsIndexRoute = createRoute({\n\tgetParentRoute: () => orgsLayoutRoute,\n\tpath: '/',\n\thead: () => ({ meta: [{ title: 'Organizations — Harper Fabric' }] }),\n\tcomponent: OrganizationsIndex,\n});\n\nconst newOrgRoute = createRoute({\n\tgetParentRoute: () => orgsLayoutRoute,\n\tpath: '/new-org',\n\thead: () => ({ meta: [{ title: 'New Organization — Harper Fabric' }] }),\n\tcomponent: NewOrg,\n});\n\nexport const orgsRoutes = [\n\torgsIndexRoute,\n\tnewOrgRoute,\n];\n","import { createBillingRouteTree } from '@/features/organization/billing/routes';\nimport {\n\tgetOrganizationQueryOptions,\n\tisValidOrganizationId,\n} from '@/features/organization/queries/getOrganizationQuery';\nimport { OrgConfigRolesIndex } from '@/features/organization/roles';\nimport { OrgSettingsIndex } from '@/features/organization/settings';\nimport { OrgConfigUsersIndex } from '@/features/organization/users';\nimport { orgsLayoutRoute } from '@/features/organizations/routes';\nimport { createRoute, redirect } from '@tanstack/react-router';\n\nexport const orgLayoutRoute = createRoute({\n\tgetParentRoute: () => orgsLayoutRoute,\n\tpath: '$organizationId',\n\tbeforeLoad: async (opts) => {\n\t\tconst { organizationId } = opts.params;\n\t\t// A stray `/undefined` URL would otherwise fetch `/Organization/undefined`\n\t\t// (`ensureQueryData` ignores the query's `enabled` flag). Bounce to the org\n\t\t// picker instead of rendering a broken org shell. Redirecting rather than\n\t\t// returning a partial context also keeps `organization` strictly defined\n\t\t// for every route that loads under here.\n\t\tif (!isValidOrganizationId(organizationId)) {\n\t\t\tthrow redirect({ to: '/' });\n\t\t}\n\t\treturn {\n\t\t\torganization: await opts.context.queryClient.ensureQueryData(\n\t\t\t\tgetOrganizationQueryOptions(organizationId),\n\t\t\t),\n\t\t};\n\t},\n});\n\nconst orgRolesRoute = createRoute({\n\tgetParentRoute: () => orgLayoutRoute,\n\tpath: '/roles',\n\thead: () => ({ meta: [{ title: 'Organization Roles — Harper Fabric' }] }),\n\tcomponent: OrgConfigRolesIndex,\n});\nconst orgRoleRoute = createRoute({\n\tgetParentRoute: () => orgLayoutRoute,\n\tpath: '/roles/$orgRoleId',\n\thead: () => ({ meta: [{ title: 'Organization Roles — Harper Fabric' }] }),\n\tcomponent: OrgConfigRolesIndex,\n});\n\nconst orgUsersRoute = createRoute({\n\tgetParentRoute: () => orgLayoutRoute,\n\tpath: '/users',\n\thead: () => ({ meta: [{ title: 'Organization Users — Harper Fabric' }] }),\n\tcomponent: OrgConfigUsersIndex,\n});\nconst orgUserRoute = createRoute({\n\tgetParentRoute: () => orgLayoutRoute,\n\tpath: '/users/$orgUserId',\n\thead: () => ({ meta: [{ title: 'Organization Users — Harper Fabric' }] }),\n\tcomponent: OrgConfigUsersIndex,\n});\n\nconst orgSettingsRoute = createRoute({\n\tgetParentRoute: () => orgLayoutRoute,\n\tpath: '/settings',\n\tcomponent: OrgSettingsIndex,\n});\n\nexport const orgRoutes = [\n\tcreateBillingRouteTree(orgLayoutRoute),\n\torgRolesRoute,\n\torgRoleRoute,\n\torgUsersRoute,\n\torgUserRoute,\n\torgSettingsRoute,\n];\n","import { clusterLayoutRoute } from '@/features/cluster/clusterLayoutRoute';\nimport { ClustersList as ClusterList } from '@/features/clusters/ClustersList';\nimport { UpsertCluster } from '@/features/clusters/upsert';\nimport { orgLayoutRoute } from '@/features/organization/routes';\nimport { createRoute } from '@tanstack/react-router';\n\nexport const clustersLayoutRoute = createRoute({\n\tgetParentRoute: () => orgLayoutRoute,\n\tid: '_clusterLayout',\n});\n\nconst clustersIndexRoute = createRoute({\n\tgetParentRoute: () => clustersLayoutRoute,\n\tpath: '/',\n\thead: () => ({ meta: [{ title: 'Clusters — Harper Fabric' }] }),\n\tcomponent: ClusterList,\n});\n\nconst newClusterRoute = createRoute({\n\tgetParentRoute: () => orgLayoutRoute,\n\tpath: '/new-cluster',\n\thead: () => ({ meta: [{ title: 'New Cluster — Harper Fabric' }] }),\n\tcomponent: UpsertCluster,\n});\n\nconst editClusterRoute = createRoute({\n\tgetParentRoute: () => clusterLayoutRoute,\n\tpath: '/edit',\n\thead: () => ({ meta: [{ title: 'Edit Cluster — Harper Fabric' }] }),\n\tcomponent: UpsertCluster,\n});\n\nconst editClusterVersionRoute = createRoute({\n\tgetParentRoute: () => clusterLayoutRoute,\n\tpath: '/edit/$mode',\n\thead: () => ({ meta: [{ title: 'Edit Cluster — Harper Fabric' }] }),\n\tcomponent: UpsertCluster,\n});\n\n// Each route must be wired into the tree (in rootRouteTree) under the same route\n// its `getParentRoute` declares — otherwise TanStack Router 1.170 mis-parses the\n// tree and drops path params. So these are grouped by their declared parent.\n\n// Parent: clustersLayoutRoute\nexport const clustersRoutes = [\n\tclustersIndexRoute,\n];\n\n// Parent: orgLayoutRoute\nexport { newClusterRoute };\n\n// Parent: clusterLayoutRoute\nexport const clusterEditRoutes = [\n\teditClusterRoute,\n\teditClusterVersionRoute,\n];\n","import { Outlet } from '@tanstack/react-router';\n\nexport function ClusterLayout() {\n\treturn <Outlet />;\n}\n","import { clustersLayoutRoute } from '@/features/clusters/routes';\nimport { createRoute } from '@tanstack/react-router';\nimport { ClusterLayout } from './ClusterLayout';\nimport { getClusterInfoQueryOptions } from './queries/getClusterInfoQuery';\n\nexport const clusterLayoutRoute = createRoute({\n\tgetParentRoute: () => clustersLayoutRoute,\n\tpath: '$clusterId',\n\tcomponent: ClusterLayout,\n\tbeforeLoad: async ({ context, params }) => {\n\t\treturn {\n\t\t\tcluster: await context.queryClient.ensureQueryData(getClusterInfoQueryOptions(params.clusterId)),\n\t\t};\n\t},\n});\n","import { SubNavMenu } from '@/components/SubNavMenu';\nimport { cx } from 'class-variance-authority';\nimport { ReactNode } from 'react';\n\nexport function NestedContentWithSubNavMenu({ children, className }: { children: ReactNode; className?: string }) {\n\treturn (\n\t\t<>\n\t\t\t<SubNavMenu />\n\t\t\t<div\n\t\t\t\tclassName={cx('mt-32 px-4 py-4 md:px-12 min-h-[calc(100vh-(--spacing(32)))] flex justify-center', className)}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t</>\n\t);\n}\n","/**\n * A list of common second-level domains used in country-code TLDs (ccTLDs).\n * This helps identify if a domain like 'example.co.uk' should be treated\n * as a root domain (returning '@') or if 'co' is the subdomain.\n */\nconst COMMON_SLDS = new Set([\n\t'com',\n\t'co',\n\t'org',\n\t'net',\n\t'edu',\n\t'gov',\n\t'mil',\n\t'me',\n\t'biz',\n\t'info',\n\t'ac',\n\t'or',\n\t'ne',\n\t'go',\n\t'lg',\n\t'asn',\n\t'id',\n\t'nom',\n\t'sch',\n\t'ltd',\n\t'plc',\n]);\n\nexport function extractDomainFromTLD(domain: string): string | '@' {\n\tconst parts = domain.split('.');\n\tif (parts.length <= 2) {\n\t\treturn '@';\n\t}\n\n\tconst lastPart = parts[parts.length - 1];\n\tconst secondToLastPart = parts[parts.length - 2];\n\n\tconst isMultiPartTld = lastPart.length === 2 && COMMON_SLDS.has(secondToLastPart);\n\tconst rootPartCount = isMultiPartTld ? 3 : 2;\n\n\tif (parts.length <= rootPartCount) {\n\t\treturn '@';\n\t}\n\n\treturn parts.slice(0, -rootPartCount).join('.');\n}\n","import { Button } from '@/components/ui/button';\nimport { useCopyToClipboard } from '@/hooks/useCopyToClipboard';\nimport { Cluster, SchemaOrganizationDomain } from '@/integrations/api/api.patch';\nimport { extractDomainFromTLD } from '@/lib/string/extractDomainFromTLD';\nimport { CopyIcon } from 'lucide-react';\n\nexport function AssociateDomainWithCluster({ cluster: { fqdn }, domain: { domain, id } }: {\n\tcluster: Cluster;\n\tdomain: SchemaOrganizationDomain;\n}) {\n\tconst recordName = extractDomainFromTLD(domain);\n\tconst [onCopyName, onCopyTarget, onCopyId] = useCopyToClipboard(recordName, fqdn || '', id);\n\n\treturn (\n\t\t<div className=\"grid gap-4 grid-cols-1 md:grid-cols-[80px_1fr] pb-6\">\n\t\t\t<div className=\"text-muted-foreground md:col-span-2 text-wrap\">\n\t\t\t\tThis domain has been verified! Now to associate it with this cluster, add the following to your DNS registrar:\n\t\t\t</div>\n\n\t\t\t<div className=\"col-span-1\">Type:</div>\n\t\t\t<div className=\"col-span-1\">CNAME</div>\n\n\t\t\t<div className=\"col-span-1\">Name:</div>\n\t\t\t<div className=\"col-span-1 flex gap-2 items-center\">\n\t\t\t\t<div className=\"flex items-center gap-1 bg-muted rounded-md px-3 py-1 flex-1 overflow-hidden\">\n\t\t\t\t\t<input\n\t\t\t\t\t\tclassName=\"bg-transparent border-none outline-none w-full cursor-text truncate\"\n\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\treadOnly={true}\n\t\t\t\t\t\tname=\"recordName\"\n\t\t\t\t\t\tvalue={recordName}\n\t\t\t\t\t\tonClick={onCopyName}\n\t\t\t\t\t/>\n\t\t\t\t\t<Button type=\"button\" variant=\"ghost\" className=\"h-6 w-6 p-0 shrink-0\" onClick={onCopyName}>\n\t\t\t\t\t\t<CopyIcon className=\"w-3.5 h-3.5\" />\n\t\t\t\t\t</Button>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div className=\"col-span-1\">TTL:</div>\n\t\t\t<div className=\"col-span-1\">Auto</div>\n\n\t\t\t<div className=\"col-span-1\">Target:</div>\n\t\t\t<div className=\"col-span-1 flex gap-2 items-center\">\n\t\t\t\t<div className=\"flex items-center gap-1 bg-muted rounded-md px-3 py-1 flex-1 overflow-hidden\">\n\t\t\t\t\t<input\n\t\t\t\t\t\tclassName=\"bg-transparent border-none outline-none w-full cursor-text truncate\"\n\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\treadOnly={true}\n\t\t\t\t\t\tname=\"recordTarget\"\n\t\t\t\t\t\tvalue={fqdn}\n\t\t\t\t\t\tonClick={onCopyTarget}\n\t\t\t\t\t/>\n\t\t\t\t\t<Button type=\"button\" variant=\"ghost\" className=\"h-6 w-6 p-0 shrink-0\" onClick={onCopyTarget}>\n\t\t\t\t\t\t<CopyIcon className=\"w-3.5 h-3.5\" />\n\t\t\t\t\t</Button>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div className=\"col-span-1 text-xs\">Domain ID:</div>\n\t\t\t<div className=\"col-span-1 flex gap-2 items-center\">\n\t\t\t\t<div className=\"flex items-center gap-1 bg-muted rounded-md px-3 py-0.5 text-xs text-muted-foreground italic flex-1 overflow-hidden\">\n\t\t\t\t\t<input\n\t\t\t\t\t\tclassName=\"bg-transparent border-none outline-none w-full cursor-text truncate\"\n\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\treadOnly={true}\n\t\t\t\t\t\tname=\"domainId\"\n\t\t\t\t\t\tvalue={id}\n\t\t\t\t\t\tonClick={onCopyId}\n\t\t\t\t\t/>\n\t\t\t\t\t<Button type=\"button\" variant=\"ghost\" className=\"h-5 w-5 p-0 shrink-0\" onClick={onCopyId}>\n\t\t\t\t\t\t<CopyIcon className=\"w-3 h-3\" />\n\t\t\t\t\t</Button>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div className=\"text-muted-foreground md:col-span-2 text-wrap italic text-sm\">\n\t\t\t\tSelect this domain using the checkbox to the left, then click \"Bind\" in the top right to finish associating it\n\t\t\t\twith this cluster.\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n","import { Button } from '@/components/ui/button';\nimport { ChallengeCertificate } from '@/features/cluster/domains/queries/getChallengeCertificates';\nimport { useCopyToClipboard } from '@/hooks/useCopyToClipboard';\nimport { Cluster, SchemaOrganizationDomain } from '@/integrations/api/api.patch';\nimport { extractDomainFromTLD } from '@/lib/string/extractDomainFromTLD';\nimport { CopyIcon } from 'lucide-react';\nimport { useMemo } from 'react';\n\nexport function CertificateProgress({\n\tcertificate,\n\tdomain,\n\tcluster,\n}: {\n\tcertificate: ChallengeCertificate;\n\tdomain: SchemaOrganizationDomain;\n\tcluster: Cluster;\n}) {\n\tconst recordName = extractDomainFromTLD(domain.domain);\n\tconst [onCopyName, onCopyTarget, onCopyId] = useCopyToClipboard(\n\t\trecordName,\n\t\tcluster.fqdn || '',\n\t\tdomain.id,\n\t);\n\n\tconst progress = useMemo(() => {\n\t\tif (certificate.issueDate && !certificate.inProgress) {\n\t\t\treturn {\n\t\t\t\twidth: '100%',\n\t\t\t\tcolor: 'bg-green/80',\n\t\t\t\tpulse: false,\n\t\t\t\ttext: 'Certificate Issued',\n\t\t\t};\n\t\t}\n\t\tif (certificate.inProgress) {\n\t\t\treturn {\n\t\t\t\twidth: '100%',\n\t\t\t\tcolor: 'bg-yellow/80',\n\t\t\t\tpulse: true,\n\t\t\t\ttext: 'Generating Certificate...',\n\t\t\t};\n\t\t}\n\t\t// If neither issueDate nor inProgress, it's pending\n\t\treturn {\n\t\t\twidth: '100%',\n\t\t\tcolor: 'bg-gray-600',\n\t\t\tpulse: false,\n\t\t\ttext: 'Pending Certificate Generation...',\n\t\t};\n\t}, [certificate]);\n\n\treturn (\n\t\t<div className=\"w-full max-w-2xl border border-border/50 rounded-md p-4 bg-gray-900/20\">\n\t\t\t<div className=\"mb-4\">\n\t\t\t\t<div className=\"w-full h-1.5 rounded-full overflow-clip flex shadow-sm bg-gray-800\">\n\t\t\t\t\t<div\n\t\t\t\t\t\tstyle={{ width: progress.width }}\n\t\t\t\t\t\tclassName={`grow transition-[width] duration-1000 ease-in-out motion-reduce:transition-none ${progress.color} ${\n\t\t\t\t\t\t\tprogress.pulse ? 'animate-pulse' : ''\n\t\t\t\t\t\t}`}\n\t\t\t\t\t>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"text-[10px] text-muted-foreground font-light mt-1 italic\">{progress.text}</div>\n\t\t\t</div>\n\n\t\t\t<div className=\"grid gap-2 grid-cols-1 md:grid-cols-[80px_1fr] text-sm\">\n\t\t\t\t<div className=\"col-span-1 text-xs text-muted-foreground\">CNAME:</div>\n\t\t\t\t<div className=\"col-span-1 flex gap-2 items-center flex-wrap\">\n\t\t\t\t\t<div className=\"flex items-center gap-1 bg-muted px-2 py-0.5 rounded text-xs\">\n\t\t\t\t\t\t<span className=\"truncate max-w-[150px]\" title={recordName}>\n\t\t\t\t\t\t\t{recordName}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\tclassName=\"h-4 w-4 p-0\"\n\t\t\t\t\t\t\tonClick={onCopyName}\n\t\t\t\t\t\t\ttitle=\"Copy Name\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<CopyIcon className=\"w-3 h-3\" />\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</div>\n\t\t\t\t\t<ArrowIcon />\n\t\t\t\t\t<div className=\"flex items-center gap-1 bg-muted px-2 py-0.5 rounded text-xs\">\n\t\t\t\t\t\t<span className=\"truncate max-w-[200px]\" title={cluster.fqdn || ''}>\n\t\t\t\t\t\t\t{cluster.fqdn}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\tclassName=\"h-4 w-4 p-0\"\n\t\t\t\t\t\t\tonClick={onCopyTarget}\n\t\t\t\t\t\t\ttitle=\"Copy Target\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<CopyIcon className=\"w-3 h-3\" />\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div className=\"col-span-1 text-[10px] text-muted-foreground\">Domain ID:</div>\n\t\t\t\t<div className=\"col-span-1 flex gap-2 items-center\">\n\t\t\t\t\t<div className=\"flex items-center gap-1 bg-muted px-2 py-0.5 rounded text-[10px] text-muted-foreground italic\">\n\t\t\t\t\t\t<span className=\"truncate max-w-[200px]\">{domain.id}</span>\n\t\t\t\t\t\t<Button type=\"button\" variant=\"ghost\" size=\"sm\" className=\"h-3 w-3 p-0\" onClick={onCopyId} title=\"Copy ID\">\n\t\t\t\t\t\t\t<CopyIcon className=\"w-2.5 h-2.5\" />\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nfunction ArrowIcon() {\n\treturn (\n\t\t<svg\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\tstroke=\"currentColor\"\n\t\t\tstrokeWidth=\"2\"\n\t\t\tstrokeLinecap=\"round\"\n\t\t\tstrokeLinejoin=\"round\"\n\t\t\tclassName=\"w-3 h-3 text-muted-foreground\"\n\t\t>\n\t\t\t<path d=\"M5 12h14\" />\n\t\t\t<path d=\"m12 5 7 7-7 7\" />\n\t\t</svg>\n\t);\n}\n","import { InstanceClientIdConfig } from '@/config/instanceClientConfig';\nimport { queryOptions } from '@tanstack/react-query';\n\ninterface GetSearchByValueParams extends InstanceClientIdConfig {\n\tenabled: boolean;\n\tdatabaseName: string;\n\ttableName: string;\n\tsearchAttribute: string;\n\tsort: { attribute: string; descending: boolean };\n\tpageIndex: number;\n\tpageSize: number;\n\tonlyIfCached: boolean;\n\theaders?: Record<string, any>;\n}\n\ninterface SearchByValueRequest {\n\toperation: 'search_by_value';\n\tdatabase: string;\n\ttable: string;\n\tsearch_attribute: string;\n\tsearch_value: string;\n\tsort?: { attribute: string; descending: boolean };\n\toffset: number;\n\tlimit: number;\n\tget_attributes?: string[];\n\tonlyIfCached: boolean;\n\tnoCacheStore: boolean;\n}\n\nexport function getSearchByValueOptions(params: GetSearchByValueParams) {\n\tconst {\n\t\tenabled,\n\t\tentityId,\n\t\tdatabaseName,\n\t\ttableName,\n\t\tsearchAttribute,\n\t\tsort,\n\t\tpageIndex,\n\t\tpageSize,\n\t\tonlyIfCached,\n\t} = params;\n\treturn queryOptions({\n\t\tenabled,\n\t\tqueryKey: [\n\t\t\tentityId,\n\t\t\tdatabaseName,\n\t\t\ttableName,\n\t\t\t'search_by_value',\n\t\t\tsearchAttribute,\n\t\t\tsort.attribute || 'default',\n\t\t\tsort.descending || false,\n\t\t\tpageIndex || 0,\n\t\t\tpageSize || 0,\n\t\t\tonlyIfCached,\n\t\t] as const,\n\t\tretry: false,\n\t\tstaleTime: 60_000,\n\t\tgcTime: 5_000,\n\t\tqueryFn: () => getSearchByValue(params),\n\t});\n}\n\nexport async function getSearchByValue<T = Record<string, unknown>>({\n\tinstanceClient,\n\tdatabaseName,\n\ttableName,\n\tsearchAttribute,\n\tsort,\n\tpageIndex,\n\tpageSize,\n\tonlyIfCached,\n\theaders,\n}: Omit<GetSearchByValueParams, 'enabled'>) {\n\tconst customizedSort = sort.attribute.length && !(sort.attribute === searchAttribute && !sort.descending);\n\tconst response = await instanceClient.post<T[]>(\n\t\t'/',\n\t\t{\n\t\t\toperation: 'search_by_value',\n\t\t\tget_attributes: ['*'],\n\t\t\tdatabase: databaseName,\n\t\t\ttable: tableName,\n\t\t\tsearch_attribute: searchAttribute,\n\t\t\tsearch_value: '*',\n\t\t\tsort: customizedSort ? sort : undefined,\n\t\t\toffset: pageIndex * pageSize,\n\t\t\tlimit: pageSize,\n\t\t\tonlyIfCached: onlyIfCached,\n\t\t\tnoCacheStore: onlyIfCached,\n\t\t} satisfies SearchByValueRequest,\n\t\t{ timeout: 0, headers, validateStatus: (status) => status >= 200 && status < 400 || status === 404 },\n\t);\n\tif (response.status === 404) {\n\t\treturn { data: [] };\n\t}\n\treturn response;\n}\n","import { getInstanceClient } from '@/config/getInstanceClient';\nimport { getSearchByValue } from '@/integrations/api/instance/database/getSearchByValue';\nimport { queryOptions, useQuery } from '@tanstack/react-query';\n\nexport interface ChallengeCertificate {\n\tdomain: string;\n\tissueDate: string | null;\n\trenewalDate: string | null;\n\tchallengeToken: string;\n\tchallengeContent: string;\n\tinProgress: boolean;\n}\n\nexport function getChallengeCertificatesQueryOptions(clusterId?: string) {\n\treturn queryOptions({\n\t\tqueryKey: [clusterId, 'ChallengeCertificate'],\n\t\tqueryFn: async () => {\n\t\t\tif (!clusterId) { return []; }\n\t\t\tconst instanceClient = getInstanceClient({ id: clusterId, forceFabricConnect: true });\n\t\t\tconst { data } = await getSearchByValue<ChallengeCertificate>({\n\t\t\t\tsearchAttribute: 'domain',\n\t\t\t\tentityId: clusterId,\n\t\t\t\tdatabaseName: 'data',\n\t\t\t\ttableName: 'ChallengeCertificate',\n\t\t\t\tsort: { attribute: 'domain', descending: true },\n\t\t\t\tinstanceClient,\n\t\t\t\tonlyIfCached: false,\n\t\t\t\tpageIndex: 0,\n\t\t\t\tpageSize: 100,\n\t\t\t});\n\t\t\treturn data;\n\t\t},\n\t\tenabled: !!clusterId,\n\t\trefetchInterval: 5000,\n\t});\n}\n\nexport function useChallengeCertificates(clusterId?: string) {\n\treturn useQuery(getChallengeCertificatesQueryOptions(clusterId));\n}\n","import { Button } from '@/components/ui/button';\nimport { useCopyToClipboard } from '@/hooks/useCopyToClipboard';\nimport { Cluster, SchemaOrganizationDomain } from '@/integrations/api/api.patch';\nimport { extractDomainFromTLD } from '@/lib/string/extractDomainFromTLD';\nimport { CopyIcon } from 'lucide-react';\n\nexport function VerifyDomainOwnership(\n\t{ domain: { challengeToken, challengeTxtRecord, domain, id }, cluster: { fqdn } }: {\n\t\tdomain: SchemaOrganizationDomain;\n\t\tcluster: Cluster;\n\t},\n) {\n\tconst recordName = extractDomainFromTLD(domain);\n\tconst [onCopyTxtRecord, onCopyToken, onCopyName, onCopyTarget, onCopyId] = useCopyToClipboard(\n\t\tchallengeTxtRecord,\n\t\tchallengeToken,\n\t\trecordName,\n\t\tfqdn || '',\n\t\tid,\n\t);\n\n\treturn (\n\t\t<div className=\"grid gap-2 grid-cols-1 md:grid-cols-[80px_1fr] pb-6\">\n\t\t\t<div className=\"text-muted-foreground md:col-span-2 text-wrap\">\n\t\t\t\tProve that you own this domain by adding the following to your DNS registrar:\n\t\t\t</div>\n\n\t\t\t<div className=\"col-span-1\">Type:</div>\n\t\t\t<div className=\"col-span-1\">TXT</div>\n\n\t\t\t<div className=\"col-span-1\">Name:</div>\n\t\t\t<div className=\"col-span-1 flex gap-2 items-center\">\n\t\t\t\t<div className=\"flex items-center gap-1 bg-muted rounded-md px-3 py-1 flex-1 overflow-hidden\">\n\t\t\t\t\t<input\n\t\t\t\t\t\tclassName=\"bg-transparent border-none outline-none w-full cursor-text truncate\"\n\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\treadOnly={true}\n\t\t\t\t\t\tname=\"challengeName\"\n\t\t\t\t\t\tvalue={challengeTxtRecord}\n\t\t\t\t\t\tonClick={onCopyTxtRecord}\n\t\t\t\t\t/>\n\t\t\t\t\t<Button type=\"button\" size=\"sm\" variant=\"ghost\" className=\"h-6 w-6 p-0 shrink-0\" onClick={onCopyTxtRecord}>\n\t\t\t\t\t\t<CopyIcon className=\"w-3.5 h-3.5\" />\n\t\t\t\t\t</Button>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div className=\"col-span-1\">TTL:</div>\n\t\t\t<div className=\"col-span-1\">Auto</div>\n\n\t\t\t<div className=\"col-span-1\">Content:</div>\n\t\t\t<div className=\"col-span-1 flex gap-2 items-center\">\n\t\t\t\t<div className=\"flex items-center gap-1 bg-muted rounded-md px-3 py-1 flex-1 overflow-hidden\">\n\t\t\t\t\t<input\n\t\t\t\t\t\tclassName=\"bg-transparent border-none outline-none w-full cursor-text truncate\"\n\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\treadOnly={true}\n\t\t\t\t\t\tname=\"challengeToken\"\n\t\t\t\t\t\tvalue={challengeToken}\n\t\t\t\t\t\tonClick={onCopyToken}\n\t\t\t\t\t/>\n\t\t\t\t\t<Button type=\"button\" size=\"sm\" variant=\"ghost\" className=\"h-6 w-6 p-0 shrink-0\" onClick={onCopyToken}>\n\t\t\t\t\t\t<CopyIcon className=\"w-3.5 h-3.5\" />\n\t\t\t\t\t</Button>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div className=\"text-muted-foreground md:col-span-2 text-wrap mt-4\">\n\t\t\t\tWhile you're at it, you should also add the CNAME record to point to this cluster:\n\t\t\t</div>\n\n\t\t\t<div className=\"col-span-1\">Type:</div>\n\t\t\t<div className=\"col-span-1\">CNAME</div>\n\n\t\t\t<div className=\"col-span-1\">Name:</div>\n\t\t\t<div className=\"col-span-1 flex gap-2 items-center\">\n\t\t\t\t<div className=\"flex items-center gap-1 bg-muted rounded-md px-3 py-1 flex-1 overflow-hidden\">\n\t\t\t\t\t<input\n\t\t\t\t\t\tclassName=\"bg-transparent border-none outline-none w-full cursor-text truncate\"\n\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\treadOnly={true}\n\t\t\t\t\t\tname=\"recordName\"\n\t\t\t\t\t\tvalue={recordName}\n\t\t\t\t\t\tonClick={onCopyName}\n\t\t\t\t\t/>\n\t\t\t\t\t<Button type=\"button\" size=\"sm\" variant=\"ghost\" className=\"h-6 w-6 p-0 shrink-0\" onClick={onCopyName}>\n\t\t\t\t\t\t<CopyIcon className=\"w-3.5 h-3.5\" />\n\t\t\t\t\t</Button>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div className=\"col-span-1\">TTL:</div>\n\t\t\t<div className=\"col-span-1\">Auto</div>\n\n\t\t\t<div className=\"col-span-1\">Target:</div>\n\t\t\t<div className=\"col-span-1 flex gap-2 items-center\">\n\t\t\t\t<div className=\"flex items-center gap-1 bg-muted rounded-md px-3 py-1 flex-1 overflow-hidden\">\n\t\t\t\t\t<input\n\t\t\t\t\t\tclassName=\"bg-transparent border-none outline-none w-full cursor-text truncate\"\n\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\treadOnly={true}\n\t\t\t\t\t\tname=\"recordTarget\"\n\t\t\t\t\t\tvalue={fqdn}\n\t\t\t\t\t\tonClick={onCopyTarget}\n\t\t\t\t\t/>\n\t\t\t\t\t<Button type=\"button\" size=\"sm\" variant=\"ghost\" className=\"h-6 w-6 p-0 shrink-0\" onClick={onCopyTarget}>\n\t\t\t\t\t\t<CopyIcon className=\"w-3.5 h-3.5\" />\n\t\t\t\t\t</Button>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div className=\"col-span-1 text-xs\">Domain ID:</div>\n\t\t\t<div className=\"col-span-1 flex gap-2 items-center\">\n\t\t\t\t<div className=\"flex items-center gap-1 bg-muted rounded-md px-3 py-0.5 text-xs text-muted-foreground italic flex-1 overflow-hidden\">\n\t\t\t\t\t<input\n\t\t\t\t\t\tclassName=\"bg-transparent border-none outline-none w-full cursor-text truncate\"\n\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\treadOnly={true}\n\t\t\t\t\t\tname=\"domainId\"\n\t\t\t\t\t\tvalue={id}\n\t\t\t\t\t\tonClick={onCopyId}\n\t\t\t\t\t/>\n\t\t\t\t\t<Button type=\"button\" size=\"sm\" variant=\"ghost\" className=\"h-5 w-5 p-0 shrink-0\" onClick={onCopyId}>\n\t\t\t\t\t\t<CopyIcon className=\"w-3 h-3\" />\n\t\t\t\t\t</Button>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div className=\"text-muted-foreground md:col-span-2 text-wrap mt-2\">\n\t\t\t\tThen after your DNS TTL elapses, click the \"Validate\" button above.\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n","import { apiClient } from '@/config/apiClient';\nimport { useMutation } from '@tanstack/react-query';\n\ninterface Params {\n\tclusterId: string;\n\tdomainIds: string[];\n\tgenerateDomainCerts: boolean;\n}\n\nasync function setDomainIdsOnCluster({ clusterId, domainIds, generateDomainCerts }: Params) {\n\t// TODO: API does not describe this endpoint permutation\n\tconst { data } = await apiClient.put(`/Cluster/${clusterId}` as '/Cluster/{id}', {\n\t\tdomainIds,\n\t\tgenerateDomainCerts,\n\t}, { timeout: 0 });\n\treturn data;\n}\n\nexport function useSetDomainIdsOnCluster() {\n\treturn useMutation({\n\t\tmutationFn: (params: Params) => setDomainIdsOnCluster(params),\n\t});\n}\n","import { apiClient } from '@/config/apiClient';\nimport { useMutation } from '@tanstack/react-query';\nimport z from 'zod';\n\nexport const DeleteDomainSchema = z.object({\n\tdomainId: z.string(),\n});\n\nasync function deleteDomainSubmit(formData: z.infer<typeof DeleteDomainSchema>) {\n\t// TODO: API does not describe this endpoint.\n\tconst { data } = await apiClient.delete(`/Domain/${formData.domainId}` as any);\n\treturn data;\n}\n\nexport function useDeleteDomain() {\n\treturn useMutation({\n\t\tmutationFn: (formData: z.infer<typeof DeleteDomainSchema>) => deleteDomainSubmit(formData),\n\t});\n}\n","export function unique<T>(arr: T[]): T[] {\n\treturn [...new Set(arr)];\n}\n","import { Button } from '@/components/ui/button';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';\nimport { isRunning } from '@/components/ui/utils/badgeStatus';\nimport { AssociateDomainWithCluster } from '@/features/cluster/domains/AssociateDomainWithCluster';\nimport { CertificateProgress } from '@/features/cluster/domains/components/CertificateProgress';\nimport { useChallengeCertificates } from '@/features/cluster/domains/queries/getChallengeCertificates';\nimport { VerifyDomainOwnership } from '@/features/cluster/domains/VerifyDomainOwnership';\nimport { useSetDomainIdsOnCluster } from '@/features/clusters/mutations/setDomainIdsOnCluster';\nimport { useDeleteDomain } from '@/features/organization/mutations/deleteDomain';\nimport { Cluster, SchemaOrganizationDomain } from '@/integrations/api/api.patch';\nimport { clusterIsSelfManaged } from '@/integrations/api/clusterIsSelfManaged';\nimport { unique } from '@/lib/arrays/unique';\nimport { queryClient } from '@/react-query/queryClient';\nimport { ColumnDef, createColumnHelper } from '@tanstack/react-table';\nimport { useCallback, useMemo } from 'react';\nimport { toast } from 'sonner';\n\nconst columnHelper = createColumnHelper<SchemaOrganizationDomain>();\n\nexport function useDataTableColumns(\n\tcluster: Cluster,\n\tselectedDomainIds: string[],\n\tonToggleDomainSelection: (domainId: string) => void,\n): Array<ColumnDef<SchemaOrganizationDomain>> {\n\tconst { data: challengeCertificates } = useChallengeCertificates(cluster.id);\n\tconst isGeneratingCert = useMemo(\n\t\t() => !!challengeCertificates?.some((cert) => !cert.issueDate || cert.inProgress),\n\t\t[challengeCertificates],\n\t);\n\n\tconst { mutate: setDomainIds, isPending: addPending } = useSetDomainIdsOnCluster();\n\tconst { mutate: deleteDomain, isPending: deletePending } = useDeleteDomain();\n\tconst isPending = addPending || deletePending;\n\n\tconst bindDomainToThisCluster = useCallback((domainId: string, generateDomainCerts: boolean) => {\n\t\tif (!isRunning(cluster.status)) {\n\t\t\ttoast.error('Cluster is currently ' + cluster.status, { description: 'To bind a domain, it must be running.' });\n\t\t\treturn;\n\t\t}\n\t\tsetDomainIds({\n\t\t\tclusterId: cluster.id,\n\t\t\tdomainIds: unique((cluster.domainIds?.slice() || []).concat([domainId])),\n\t\t\tgenerateDomainCerts,\n\t\t}, {\n\t\t\tonSuccess: () => {\n\t\t\t\tvoid queryClient.invalidateQueries({ queryKey: [cluster.organizationId], refetchType: 'active' });\n\t\t\t\ttoast.success(\n\t\t\t\t\t'Domain bound!' + (generateDomainCerts\n\t\t\t\t\t\t? ' Certificates are being generated in the background now.'\n\t\t\t\t\t\t: ''),\n\t\t\t\t);\n\t\t\t},\n\t\t});\n\t}, [setDomainIds, cluster]);\n\n\tconst deleteDomainById = useCallback((domainId: string) => {\n\t\tdeleteDomain({\n\t\t\tdomainId: domainId,\n\t\t}, {\n\t\t\tonSuccess: () => {\n\t\t\t\tvoid queryClient.invalidateQueries({ queryKey: [cluster.organizationId, 'domains'], refetchType: 'active' });\n\t\t\t\ttoast.success('Domain removed!');\n\t\t\t},\n\t\t});\n\t}, [deleteDomain]);\n\n\tconst unbindDomainById = useCallback((domainId: string) => {\n\t\tsetDomainIds({\n\t\t\tclusterId: cluster.id,\n\t\t\tdomainIds: (cluster.domainIds?.slice() || []).filter((id) => id !== domainId),\n\t\t\tgenerateDomainCerts: false,\n\t\t}, {\n\t\t\tonSuccess: () => {\n\t\t\t\tvoid queryClient.invalidateQueries({ queryKey: [cluster.organizationId], refetchType: 'active' });\n\t\t\t\ttoast.success('Domain unbound!');\n\t\t\t},\n\t\t});\n\t}, [deleteDomain]);\n\n\treturn useMemo(() => [\n\t\tcolumnHelper.display({\n\t\t\tid: 'select',\n\t\t\theader: 'Bind',\n\t\t\tsize: 50,\n\t\t\tcell: (props) => {\n\t\t\t\tconst domain = props.row.original;\n\t\t\t\tconst canBind = domain.status === 'ACTIVE' && !domain.clusterId && !clusterIsSelfManaged(cluster);\n\t\t\t\tif (!canBind) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\treturn (\n\t\t\t\t\t<label className=\"p-10 -m-10\">\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\tchecked={selectedDomainIds.includes(domain.id)}\n\t\t\t\t\t\t\tonChange={() => onToggleDomainSelection(domain.id)}\n\t\t\t\t\t\t\tdisabled={isPending || isGeneratingCert}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</label>\n\t\t\t\t);\n\t\t\t},\n\t\t}),\n\t\tcolumnHelper.display({\n\t\t\theader: 'Domains',\n\t\t\tid: 'domain',\n\t\t\tenableSorting: false,\n\t\t\tsize: 150,\n\t\t\tcell: (props) => {\n\t\t\t\tconst domain = props.row.original;\n\t\t\t\treturn (\n\t\t\t\t\t<Tooltip>\n\t\t\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<div>{domain.domain}</div>\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tvariant=\"destructiveGhost\"\n\t\t\t\t\t\t\t\t\tclassName=\"text-muted-foreground text-xs\"\n\t\t\t\t\t\t\t\t\tdisabled={isPending || !!domain.clusterId}\n\t\t\t\t\t\t\t\t\tonClick={() => deleteDomainById(domain.id)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tRemove Domain\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t</TooltipTrigger>\n\t\t\t\t\t\t<TooltipContent\n\t\t\t\t\t\t\tside=\"bottom\"\n\t\t\t\t\t\t\talign=\"center\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{domain.clusterId\n\t\t\t\t\t\t\t\t? 'To delete this domain, please unbind it from all clusters first.'\n\t\t\t\t\t\t\t\t: 'Remember to clean up your DNS records!'}\n\t\t\t\t\t\t</TooltipContent>\n\t\t\t\t\t</Tooltip>\n\t\t\t\t);\n\t\t\t},\n\t\t}),\n\t\tcolumnHelper.display({\n\t\t\theader: 'Next Steps',\n\t\t\tenableSorting: false,\n\t\t\tsize: 500,\n\t\t\tid: 'nextSteps',\n\t\t\tcell: (props) => {\n\t\t\t\tconst domain = props.row.original;\n\n\t\t\t\tconst certForDomain = challengeCertificates?.find((c) => c.domain === domain.domain);\n\n\t\t\t\tif (domain.status === 'ACTIVE' && domain.clusterId) {\n\t\t\t\t\tif (cluster.id === domain.clusterId) {\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<div>Bound to this cluster</div>\n\t\t\t\t\t\t\t\t{certForDomain && (!certForDomain.issueDate || certForDomain.inProgress) && (\n\t\t\t\t\t\t\t\t\t<div className=\"py-2\">\n\t\t\t\t\t\t\t\t\t\t<CertificateProgress certificate={certForDomain} domain={domain} cluster={cluster} />\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tvariant=\"destructiveGhost\"\n\t\t\t\t\t\t\t\t\tclassName=\"text-muted-foreground text-xs\"\n\t\t\t\t\t\t\t\t\tdisabled={isPending}\n\t\t\t\t\t\t\t\t\tonClick={() => unbindDomainById(domain.id)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tUnbind Domain\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn `Bound to cluster ${domain.clusterId}`;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (domain.status === 'PENDING_VALIDATION') {\n\t\t\t\t\treturn <VerifyDomainOwnership domain={domain} cluster={cluster} />;\n\t\t\t\t}\n\n\t\t\t\tif (clusterIsSelfManaged(cluster)) {\n\t\t\t\t\treturn `Cannot be associated with this self-managed cluster.`;\n\t\t\t\t}\n\n\t\t\t\tif (domain.status === 'ACTIVE' && !domain.clusterId) {\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<AssociateDomainWithCluster\n\t\t\t\t\t\t\tcluster={cluster}\n\t\t\t\t\t\t\tdomain={domain}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// Otherwise... probably an unhandled status:\n\t\t\t\treturn domain.status;\n\t\t\t},\n\t\t}),\n\t], [\n\t\tcluster,\n\t\tbindDomainToThisCluster,\n\t\tisPending,\n\t\tchallengeCertificates,\n\t\tisGeneratingCert,\n\t\tselectedDomainIds,\n\t\tonToggleDomainSelection,\n\t]);\n}\n","import { apiClient } from '@/config/apiClient';\nimport { useMutation } from '@tanstack/react-query';\nimport z from 'zod';\n\nexport const AddOrganizationDomainSchema = z.object({\n\tdomain: z.string(),\n\torganizationId: z.string(),\n});\n\nexport async function onAddDomainToOrganizationSubmit(formData: z.infer<typeof AddOrganizationDomainSchema>) {\n\t// TODO: API does not describe this endpoint.\n\tconst { data } = await apiClient.post('/Domain/' as any, formData);\n\treturn data;\n}\n\nexport function useAddDomainToOrganization() {\n\treturn useMutation({\n\t\tmutationFn: (formData: z.infer<typeof AddOrganizationDomainSchema>) => onAddDomainToOrganizationSubmit(formData),\n\t});\n}\n","import { apiClient } from '@/config/apiClient';\n\nexport async function validateDomainInOrganization(domainId: string) {\n\t// TODO: API does not describe this endpoint.\n\tconst { data } = await apiClient.post(\n\t\t`/Domain/${domainId}/validate` as any,\n\t);\n\treturn data;\n}\n","import { apiClient } from '@/config/apiClient';\nimport { SchemaOrganizationDomain } from '@/integrations/api/api.patch';\nimport { queryOptions } from '@tanstack/react-query';\n\nasync function getOrganizationDomains(organizationId: string): Promise<SchemaOrganizationDomain[]> {\n\tconst { data } = await apiClient.get(`/Domain/?organizationId=${organizationId}` as any);\n\t// TODO: The API is not describing itself accurately.\n\treturn data;\n}\n\nexport function getOrganizationDomainsQueryOptions(organizationId: string) {\n\treturn queryOptions({\n\t\tqueryKey: [organizationId, 'domains'],\n\t\tqueryFn: () => getOrganizationDomains(organizationId),\n\t});\n}\n","import { SimpleBrowseDataTable } from '@/components/SimpleBrowseDataTable';\nimport { Button } from '@/components/ui/button';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { isRunning } from '@/components/ui/utils/badgeStatus';\nimport { useDataTableColumns } from '@/features/cluster/domains/constants/tableDefinition';\nimport { getClusterInfoQueryOptions } from '@/features/cluster/queries/getClusterInfoQuery';\nimport { useSetDomainIdsOnCluster } from '@/features/clusters/mutations/setDomainIdsOnCluster';\nimport {\n\tAddOrganizationDomainSchema,\n\tuseAddDomainToOrganization,\n} from '@/features/organization/mutations/addDomainToOrganization';\nimport { validateDomainInOrganization } from '@/features/organization/mutations/validateDomainInOrganization';\nimport { getOrganizationDomainsQueryOptions } from '@/features/organization/queries/getOrganizationDomains';\nimport { useOrganizationRolePermissions } from '@/hooks/usePermissions';\nimport { useRefreshClick } from '@/hooks/useRefreshClick';\nimport { SchemaOrganizationDomain } from '@/integrations/api/api.patch';\nimport { unique } from '@/lib/arrays/unique';\nimport { pluralize } from '@/lib/pluralize';\nimport { queryClient } from '@/react-query/queryClient';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useQuery, useSuspenseQuery } from '@tanstack/react-query';\nimport { useParams } from '@tanstack/react-router';\nimport { ListTodoIcon, PlusIcon, RefreshCwIcon, Save } from 'lucide-react';\nimport { useCallback, useMemo, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport z from 'zod';\n\nexport function DomainsManagement() {\n\tconst { organizationId, clusterId }: { organizationId: string; clusterId: string } = useParams({ strict: false });\n\tconst { data: cluster } = useSuspenseQuery(\n\t\tgetClusterInfoQueryOptions(clusterId, true),\n\t);\n\n\tconst { update } = useOrganizationRolePermissions(organizationId);\n\tconst {\n\t\tdata: organizationDomains,\n\t\trefetch,\n\t\tisFetching,\n\t\tisRefetching,\n\t} = useQuery(getOrganizationDomainsQueryOptions(organizationId));\n\n\tconst pendingDomains = useMemo(\n\t\t() => organizationDomains?.filter(o => o.status === 'PENDING_VALIDATION') || [],\n\t\t[organizationDomains],\n\t);\n\n\tconst [sortTableDataParams] = useState({\n\t\tattribute: 'domain',\n\t\tdescending: false,\n\t});\n\tconst sortingState = useMemo(\n\t\t() => [\n\t\t\t{\n\t\t\t\tdesc: sortTableDataParams.descending,\n\t\t\t\tid: sortTableDataParams.attribute,\n\t\t\t},\n\t\t],\n\t\t[sortTableDataParams],\n\t);\n\n\tconst onRefreshClick = useRefreshClick(refetch);\n\n\tconst [selectedDomainIds, setSelectedDomainIds] = useState<string[]>([]);\n\tconst onToggleDomainSelection = useCallback((domainId: string) => {\n\t\tsetSelectedDomainIds((prev) =>\n\t\t\tprev.includes(domainId) ? prev.filter((id) => id !== domainId) : [...prev, domainId]\n\t\t);\n\t}, []);\n\n\tconst { mutate: setDomainIds, isPending: isBindPending } = useSetDomainIdsOnCluster();\n\n\tconst onBindClick = useCallback(() => {\n\t\tif (!isRunning(cluster.status)) {\n\t\t\ttoast.error('Cluster is currently ' + cluster.status, { description: 'To bind a domain, it must be running.' });\n\t\t\treturn;\n\t\t}\n\n\t\tsetDomainIds({\n\t\t\tclusterId: cluster.id,\n\t\t\tdomainIds: unique((cluster.domainIds?.slice() || []).concat(selectedDomainIds)),\n\t\t\tgenerateDomainCerts: true,\n\t\t}, {\n\t\t\tonSuccess: () => {\n\t\t\t\tvoid queryClient.invalidateQueries({ queryKey: [cluster.organizationId], refetchType: 'active' });\n\t\t\t\ttoast.success('Domain(s) bound! Certificates are being generated in the background now.');\n\t\t\t\tsetSelectedDomainIds([]);\n\t\t\t},\n\t\t});\n\t}, [cluster, selectedDomainIds, setDomainIds]);\n\n\tconst { mutateAsync: addDomain, isPending: isAddPending } = useAddDomainToOrganization();\n\tconst form = useForm({\n\t\tresolver: zodResolver(AddOrganizationDomainSchema),\n\t\tdefaultValues: {\n\t\t\tdomain: '',\n\t\t\torganizationId,\n\t\t},\n\t});\n\n\tconst onSubmitClick = useCallback(\n\t\tasync (formData: z.infer<typeof AddOrganizationDomainSchema>) => {\n\t\t\tif (formData) {\n\t\t\t\tconst domains = formData.domain.split(/[,\\s]+/).map((d: string) => d.trim()).filter(Boolean);\n\t\t\t\tfor (const domain of domains) {\n\t\t\t\t\tawait addDomain({ ...formData, domain });\n\t\t\t\t}\n\t\t\t\tform.reset();\n\t\t\t\tawait refetch();\n\t\t\t\ttoast.success(\n\t\t\t\t\t`${\n\t\t\t\t\t\tpluralize(domains.length, 'Domain', 'Domains')\n\t\t\t\t\t} added! Please add the txt record above to your domain registrar.`,\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\t[addDomain, form, refetch],\n\t);\n\n\tconst onValidateClick = useCallback(async () => {\n\t\tconst message = `Validating ${pluralize(pendingDomains.length, 'domain', 'domains')}...`;\n\t\tconst id = 'validatingDomains';\n\t\tlet checked = 0;\n\t\tlet failed = 0;\n\t\tfor (const pendingDomain of pendingDomains) {\n\t\t\ttry {\n\t\t\t\ttoast.loading(message, {\n\t\t\t\t\tdescription: `${checked++} of ${pendingDomains.length} checked`,\n\t\t\t\t\tid,\n\t\t\t\t});\n\t\t\t\tawait validateDomainInOrganization(pendingDomain.id);\n\t\t\t} catch {\n\t\t\t\tfailed += 1;\n\t\t\t}\n\t\t}\n\t\tif (failed > 0) {\n\t\t\ttoast.error('Validation failed!', {\n\t\t\t\tdescription:\n\t\t\t\t\t`Please make sure the TXT record has been put in place. You may need to wait a bit for the DNS change to propagate.`,\n\t\t\t\tid,\n\t\t\t});\n\t\t} else {\n\t\t\tawait refetch();\n\t\t\ttoast.success('Validation succeeded!', {\n\t\t\t\tdescription: `Please take a look at the next steps for newly verified domains.`,\n\t\t\t\tid,\n\t\t\t});\n\t\t}\n\t}, [pendingDomains]);\n\n\tconst dataTableColumns = useDataTableColumns(cluster, selectedDomainIds, onToggleDomainSelection);\n\n\tconst domainValue = form.watch('domain');\n\tconst isApex = useMemo(() => {\n\t\tif (typeof domainValue !== 'string') { return false; }\n\t\tconst parts = domainValue.trim().split('.');\n\t\treturn parts.length === 2;\n\t}, [domainValue]);\n\n\tconst suggestWww = useCallback(() => {\n\t\tif (typeof domainValue === 'string') {\n\t\t\tform.setValue('domain', `${domainValue.trim()}, www.${domainValue.trim()}`);\n\t\t}\n\t}, [domainValue, form]);\n\n\treturn (\n\t\t<SimpleBrowseDataTable<SchemaOrganizationDomain, unknown>\n\t\t\tdata={organizationDomains || []}\n\t\t\tisFetching={isFetching || isRefetching}\n\t\t\tcolumns={dataTableColumns}\n\t\t\tsortingState={sortingState}\n\t\t>\n\t\t\t<div className=\"w-full flex flex-col md:flex-row items-center md:justify-between md:space-x-2 space-y-2 md:space-y-0\">\n\t\t\t\t{update && (\n\t\t\t\t\t<Form {...form}>\n\t\t\t\t\t\t<form\n\t\t\t\t\t\t\tid=\"cluster-add-domain-form\"\n\t\t\t\t\t\t\tname=\"cluster-add-domain-form\"\n\t\t\t\t\t\t\tonSubmit={form.handleSubmit(onSubmitClick)}\n\t\t\t\t\t\t\tclassName=\"flex gap-1 flex-col md:flex-row\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\t\tname=\"domain\"\n\t\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t\t<FormItem className=\"flex-1\">\n\t\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">New Domain Name</FormLabel>\n\t\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t\t<Input type=\"text\" enterKeyHint=\"done\" autoComplete=\"off\" {...field} />\n\t\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t\t{isApex && (\n\t\t\t\t\t\t\t\t\t\t\t<div className=\"mt-1 flex gap-4\">\n\t\t\t\t\t\t\t\t\t\t\t\tAdding an apex domain?\n\t\t\t\t\t\t\t\t\t\t\t\t<Button variant=\"positiveOutline\" type=\"button\" onClick={suggestWww}>\n\t\t\t\t\t\t\t\t\t\t\t\t\tAdd www as well\n\t\t\t\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t<FormMessage>\n\t\t\t\t\t\t\t\t\t\t\t<span className=\"text-muted-foreground italic\">\n\t\t\t\t\t\t\t\t\t\t\t\tType in a domain like example.com or your.example.com, and you'll be guided through validating\n\t\t\t\t\t\t\t\t\t\t\t\tand binding your cluster to it.\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t</FormMessage>\n\t\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<div className=\"flex-0 self-start flex gap-1 md:pt-6.5\">\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\t\t\t\tvariant=\"submit\"\n\t\t\t\t\t\t\t\t\tdisabled={isAddPending}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<PlusIcon /> Add\n\t\t\t\t\t\t\t\t</Button>\n\n\t\t\t\t\t\t\t\t{pendingDomains.length > 0 && (\n\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\tvariant=\"positiveOutline\"\n\t\t\t\t\t\t\t\t\t\tonClick={onValidateClick}\n\t\t\t\t\t\t\t\t\t\taccessKey=\"r\"\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdisabled={isFetching || isRefetching}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<ListTodoIcon />{' '}\n\t\t\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t\t\t<u>V</u>alidate\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tvariant=\"defaultOutline\"\n\t\t\t\t\t\t\t\t\tonClick={onRefreshClick}\n\t\t\t\t\t\t\t\t\taccessKey=\"r\"\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tdisabled={isFetching || isRefetching}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<RefreshCwIcon />{' '}\n\t\t\t\t\t\t\t\t\t<span className=\"hidden lg:inline-block\">\n\t\t\t\t\t\t\t\t\t\t<u>R</u>efresh\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</form>\n\t\t\t\t\t</Form>\n\t\t\t\t)}\n\n\t\t\t\t{selectedDomainIds.length > 0 && (\n\t\t\t\t\t<div className=\"flex-0 self-start md:pt-6.5\">\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tvariant=\"submit\"\n\t\t\t\t\t\t\tonClick={onBindClick}\n\t\t\t\t\t\t\tdisabled={isBindPending}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Save /> Bind {pluralize(selectedDomainIds.length, 'Domain', 'Domains')}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</SimpleBrowseDataTable>\n\t);\n}\n","import { NestedContentWithSubNavMenu } from '@/components/NestedContentWithSubNavMenu';\nimport { DomainsManagement } from './Management';\n\nexport function DomainsPage() {\n\treturn (\n\t\t<NestedContentWithSubNavMenu className=\"flex flex-col justify-start max-w-4xl\">\n\t\t\t<DomainsManagement />\n\t\t</NestedContentWithSubNavMenu>\n\t);\n}\n","import { zodRequirePassword } from '@/lib/zod/password';\nimport { zodRequireUsername } from '@/lib/zod/username';\nimport { z } from 'zod';\n\nexport const AddUserFormSchema = z\n\t.object({\n\t\tusername: zodRequireUsername,\n\t\trole: z\n\t\t\t.string()\n\t\t\t.nonempty({\n\t\t\t\terror: 'Please select a role.',\n\t\t\t}),\n\t\tpassword: zodRequirePassword\n\t\t\t.min(8, { error: 'Password must be at least 8 characters long.' }),\n\t\tconfirmPassword: z.string(),\n\t})\n\t.refine((data) => data.password === data.confirmPassword, {\n\t\terror: 'Passwords do not match.',\n\t\tpath: ['confirmPassword'],\n\t});\n","import { apiClient } from '@/config/apiClient';\n\nexport async function resetPasswordUpdater(clusterId: string) {\n\tawait apiClient.patch(`/ResetPasswordUpdater/${clusterId}` as '/ResetPasswordUpdater/{id}');\n}\n","import { InstanceClientConfig } from '@/config/instanceClientConfig';\nimport { useMutation } from '@tanstack/react-query';\n\ninterface AddUserFormData extends InstanceClientConfig {\n\tactive: boolean;\n\tpassword: string;\n\trole: string;\n\tusername: string;\n}\n\nexport async function onAddUserSubmit(formData: AddUserFormData) {\n\tconst { instanceClient, ...userData } = formData;\n\tconst { data } = await instanceClient.post('/', {\n\t\toperation: 'add_user',\n\t\t...userData,\n\t});\n\treturn data;\n}\n\nexport function useAddUserMutation() {\n\treturn useMutation({\n\t\tmutationFn: onAddUserSubmit,\n\t});\n}\n","import { InstanceClientConfig } from '@/config/instanceClientConfig';\nimport { useMutation } from '@tanstack/react-query';\n\nexport interface AlterUserRequestBody extends InstanceClientConfig {\n\tusername?: string;\n\tpassword?: string;\n\trole?: string;\n\tactive?: boolean;\n}\n\ninterface AlterUserResponse {\n\tmessage: string;\n\tskipped_hashes: string[];\n\ttxn_time: number;\n\tupdate_hashes: string[];\n}\n\nexport async function onAlterUser({\n\tusername,\n\tpassword,\n\trole,\n\tactive,\n\tinstanceClient,\n}: AlterUserRequestBody): Promise<AlterUserResponse> {\n\tconst { data } = await instanceClient.post('/', {\n\t\toperation: 'alter_user',\n\t\tusername,\n\t\tpassword,\n\t\trole,\n\t\tactive,\n\t});\n\treturn data as AlterUserResponse;\n}\n\nexport function useAlterUser() {\n\treturn useMutation({\n\t\tmutationFn: onAlterUser,\n\t});\n}\n","import { InstanceClientConfig } from '@/config/instanceClientConfig';\nimport { useMutation } from '@tanstack/react-query';\n\ninterface DeleteUserData extends InstanceClientConfig {\n\tusername: string;\n}\n\ninterface DeleteUserResponse {\n\tmessage: string;\n}\n\nexport async function onDeleteUser({ username, instanceClient }: DeleteUserData) {\n\tconst { data } = await instanceClient.post<DeleteUserResponse>('/', {\n\t\toperation: 'drop_user',\n\t\tusername,\n\t});\n\treturn data;\n}\n\nexport function useDeleteUserMutation() {\n\treturn useMutation({\n\t\tmutationFn: onDeleteUser,\n\t});\n}\n","import { defaultClusterUsername } from '@/config/constants';\nimport { InstanceClientConfig } from '@/config/instanceClientConfig';\nimport { resetPasswordUpdater } from '@/features/cluster/queries/resetPasswordUpdater';\nimport { useMutation } from '@tanstack/react-query';\nimport { onAddUserSubmit } from './addUser';\nimport { onAlterUser } from './alterUser';\nimport { onDeleteUser } from './deleteUser';\nimport { onInstanceLogoutSubmit } from './onInstanceLogoutSubmit';\nimport { LoginInfoResponse, onInstanceLoginSubmit } from './useInstanceLoginMutation';\n\ninterface InstanceResetPasswordParams extends InstanceClientConfig {\n\tclusterId: string;\n\tinitialUsername: string;\n\tdesiredUsername: string;\n\tnewPassword: string;\n\ttempPassword: string | undefined;\n}\n\nasync function onInstanceResetPassword({\n\tclusterId,\n\tinitialUsername,\n\tdesiredUsername,\n\tnewPassword,\n\ttempPassword,\n\tinstanceClient: initialInstanceClient,\n}: InstanceResetPasswordParams): Promise<LoginInfoResponse> {\n\t// Do we have a temporary password?\n\tif (!tempPassword) {\n\t\tthrow new Error('You may not have permission to set the password on this cluster.');\n\t}\n\tlet instanceClient = initialInstanceClient;\n\ttry {\n\t\t// Sign in with the temporary password,\n\t\tconst loginResponse = await onInstanceLoginSubmit({\n\t\t\tusername: initialUsername,\n\t\t\tpassword: tempPassword,\n\t\t\tinstanceClient,\n\t\t\tentityId: clusterId,\n\t\t});\n\t\tif (loginResponse.instanceClient) {\n\t\t\tinstanceClient = loginResponse.instanceClient;\n\t\t}\n\t\t// if the usernames match, we need to alter the user...\n\t\tif (desiredUsername === defaultClusterUsername) {\n\t\t\tawait onAlterUser({\n\t\t\t\tusername: desiredUsername,\n\t\t\t\tpassword: newPassword,\n\t\t\t\tinstanceClient,\n\t\t\t});\n\t\t} else {\n\t\t\t// ... or create a new user!\n\t\t\tawait onAddUserSubmit({\n\t\t\t\tusername: desiredUsername,\n\t\t\t\tpassword: newPassword,\n\t\t\t\trole: 'super_user',\n\t\t\t\tactive: true,\n\t\t\t\tinstanceClient,\n\t\t\t});\n\t\t\t// since we created a new user, we should log in with the new one\n\t\t\tawait onInstanceLoginSubmit({\n\t\t\t\tusername: desiredUsername,\n\t\t\t\tpassword: newPassword,\n\t\t\t\tinstanceClient,\n\t\t\t\tentityId: clusterId,\n\t\t\t});\n\t\t\t// clean up the old one\n\t\t\tawait onDeleteUser({\n\t\t\t\tusername: defaultClusterUsername,\n\t\t\t\tinstanceClient,\n\t\t\t});\n\t\t}\n\t\t// and finally, tell the central manager that we changed their password.\n\t\tawait resetPasswordUpdater(clusterId);\n\t\treturn loginResponse;\n\t} catch (err) {\n\t\t// If something went wrong, logout as well.\n\t\tawait onInstanceLogoutSubmit({\n\t\t\tentityId: clusterId,\n\t\t\tinstanceClient,\n\t\t});\n\t\tthrow err;\n\t}\n}\n\nexport function useInstanceResetPasswordMutation() {\n\treturn useMutation<LoginInfoResponse, Error, InstanceResetPasswordParams>({\n\t\tmutationFn: onInstanceResetPassword,\n\t});\n}\n","import { Breadcrumbs } from '@/components/Breadcrumbs';\nimport { Button } from '@/components/ui/button';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { defaultClusterUsername, defaultInstanceRouteUpOne } from '@/config/constants';\nimport { useInstanceClient } from '@/config/useInstanceClient';\nimport { authStore } from '@/features/auth/store/authStore';\nimport { useCloudAuth } from '@/hooks/useAuth';\nimport { AddUserFormSchema } from '@/integrations/api/instance/auth/addUserFormSchema';\nimport { useInstanceResetPasswordMutation } from '@/integrations/api/instance/auth/useInstanceResetPasswordMutation';\nimport { getOperationsUrlForCluster } from '@/lib/urls/getOperationsUrlForCluster';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useQuery } from '@tanstack/react-query';\nimport { Navigate, useNavigate, useParams, useRouter, useSearch } from '@tanstack/react-router';\nimport { ActivityIcon } from 'lucide-react';\nimport { useCallback, useEffect, useMemo } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\nimport { getClusterInfoQueryOptions } from './queries/getClusterInfoQuery';\n\nexport function FinishSetup() {\n\tconst { user } = useCloudAuth();\n\tconst { clusterId }: { clusterId: string } = useParams({ strict: false });\n\tconst { data: cluster } = useQuery(\n\t\tgetClusterInfoQueryOptions(clusterId, true),\n\t);\n\n\tconst navigate = useNavigate();\n\tconst operationsUrl = useMemo(() => getOperationsUrlForCluster(cluster), [cluster]);\n\tconst instanceClient = useInstanceClient({ operationsUrl });\n\n\tconst { redirect } = useSearch({ strict: false });\n\tconst router = useRouter();\n\n\tconst methods = useForm({\n\t\tresolver: zodResolver(AddUserFormSchema),\n\t\tdefaultValues: {\n\t\t\tconfirmPassword: '',\n\t\t\tpassword: '',\n\t\t\trole: 'super_user',\n\t\t\tusername: user?.email ?? '',\n\t\t},\n\t});\n\tconst { setFocus, control, handleSubmit } = methods;\n\n\tuseEffect(() => {\n\t\tsetFocus('password');\n\t}, [setFocus]);\n\n\tconst tempPassword = cluster?.instances?.find(i => i.tempPassword)?.tempPassword;\n\n\tconst { mutate: submitInstanceResetPassword, isPending } = useInstanceResetPasswordMutation();\n\n\tconst submitForm = useCallback(async (formData: z.infer<typeof AddUserFormSchema>) => {\n\t\tif (!operationsUrl) {\n\t\t\ttoast.error('Cluster is not yet fully loaded, please wait a moment before trying to sign in.');\n\t\t\treturn;\n\t\t}\n\t\tsubmitInstanceResetPassword({\n\t\t\tinstanceClient,\n\t\t\tclusterId,\n\t\t\tnewPassword: formData.password,\n\t\t\ttempPassword,\n\t\t\tinitialUsername: defaultClusterUsername,\n\t\t\tdesiredUsername: formData.username,\n\t\t}, {\n\t\t\tonSuccess: async ({ message, user }) => {\n\t\t\t\ttoast.success(message);\n\t\t\t\tauthStore.setUserForEntity(cluster!, user);\n\t\t\t\tvoid router.invalidate();\n\t\t\t\tawait navigate({ to: redirect?.startsWith('/') ? redirect : defaultInstanceRouteUpOne });\n\t\t\t},\n\t\t});\n\t}, [\n\t\tcluster,\n\t\tclusterId,\n\t\tinstanceClient,\n\t\tnavigate,\n\t\toperationsUrl,\n\t\tredirect,\n\t\trouter,\n\t\tsubmitInstanceResetPassword,\n\t\ttempPassword,\n\t]);\n\n\tif (cluster && !cluster.resetPassword) {\n\t\treturn <Navigate to=\"../sign-in\" replace={true} />;\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t<nav\n\t\t\t\taria-label=\"Breadcrumb\"\n\t\t\t\tclassName=\"fixed top-20 w-full h-12 z-39 px-4 md:px-12 bg-violet-50 border-b border-violet-100 dark:bg-grey-700 dark:border-none flex items-center\"\n\t\t\t>\n\t\t\t\t<Breadcrumbs />\n\t\t\t</nav>\n\t\t\t<div className=\"items-center justify-center flex mt-32 py-4 min-h-[calc(100vh-(--spacing(32)))]\">\n\t\t\t\t<div className=\"text-foreground w-xs\">\n\t\t\t\t\t<h1 className=\"text-2xl font-light\">Create Admin User</h1>\n\t\t\t\t\t<p className=\"text-muted-foreground\">\n\t\t\t\t\t\tYou are ready to create your first user in your new cluster. These credentials belong to you alone, and you\n\t\t\t\t\t\tcan create more users and roles once you create this first one.\n\t\t\t\t\t</p>\n\t\t\t\t\t<Form {...methods}>\n\t\t\t\t\t\t<form\n\t\t\t\t\t\t\tid=\"cluster-create-admin-form\"\n\t\t\t\t\t\t\tname=\"cluster-create-admin-form\"\n\t\t\t\t\t\t\tonSubmit={handleSubmit(submitForm)}\n\t\t\t\t\t\t\tclassName=\"my-4\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\t\t\tname=\"username\"\n\t\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t\t<FormItem className=\"my-4\">\n\t\t\t\t\t\t\t\t\t\t<FormLabel>Username</FormLabel>\n\t\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\t\tautoComplete=\"username\"\n\t\t\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\t\t\tname=\"password\"\n\t\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t\t<FormItem className=\"my-4\">\n\t\t\t\t\t\t\t\t\t\t<FormLabel>Password</FormLabel>\n\t\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\t\t\t\t\t\t\tautoComplete=\"new-password\"\n\t\t\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\t\t\tname=\"confirmPassword\"\n\t\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t\t<FormItem className=\"my-4\">\n\t\t\t\t\t\t\t\t\t\t<FormLabel>Confirm Password</FormLabel>\n\t\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\t\t\t\t\t\t\tautoComplete=\"new-password\"\n\t\t\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t\t<Button disabled={isPending} type=\"submit\" variant=\"submit\" className=\"w-full my-2 rounded-full\">\n\t\t\t\t\t\t\t\tCreate Admin User\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t</form>\n\t\t\t\t\t</Form>\n\n\t\t\t\t\t<p className=\"text-muted-foreground flex gap-2 align-middle\">\n\t\t\t\t\t\t<ActivityIcon size={36} className=\"flex-none\" />\n\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\tThese credentials will be used to sign into your cluster directly, providing you a secure connection from\n\t\t\t\t\t\t\tyour browser to your cluster.\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</>\n\t);\n}\n","'use client';\n\nimport { ColumnDef, flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table';\n\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';\n\ninterface DataTableProps<TData, TValue> {\n\tcolumns: ColumnDef<TData, TValue>[];\n\tdata: TData[];\n}\n\nexport function DataTable<TData, TValue>({ columns, data }: DataTableProps<TData, TValue>) {\n\tconst table = useReactTable({\n\t\tdata,\n\t\tcolumns,\n\t\tgetCoreRowModel: getCoreRowModel(),\n\t});\n\n\treturn (\n\t\t<div className=\"bg-card dark:bg-black-dark rounded-md\">\n\t\t\t<Table>\n\t\t\t\t<TableHeader>\n\t\t\t\t\t{table.getHeaderGroups().map((headerGroup) => (\n\t\t\t\t\t\t<TableRow key={headerGroup.id} className=\"border-none\">\n\t\t\t\t\t\t\t{headerGroup.headers.map((header) => {\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t<TableHead key={header.id} className=\"p-4\" style={{ width: `${header.getSize()}%` }}>\n\t\t\t\t\t\t\t\t\t\t{header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}\n\t\t\t\t\t\t\t\t\t</TableHead>\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t</TableRow>\n\t\t\t\t\t))}\n\t\t\t\t</TableHeader>\n\t\t\t\t<TableBody className=\"bg-background dark:bg-black\">\n\t\t\t\t\t{table.getRowModel().rows?.length\n\t\t\t\t\t\t? (\n\t\t\t\t\t\t\ttable.getRowModel().rows.map((row) => (\n\t\t\t\t\t\t\t\t<TableRow\n\t\t\t\t\t\t\t\t\tkey={row.id}\n\t\t\t\t\t\t\t\t\tdata-state={row.getIsSelected() && 'selected'}\n\t\t\t\t\t\t\t\t\tclassName=\"hover:bg-muted/10 data-[state=selected]:bg-muted\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{row.getVisibleCells().map((cell) => (\n\t\t\t\t\t\t\t\t\t\t<TableCell key={cell.id} className=\"p-4\" style={{ width: `${cell.column.getSize()}%` }}>\n\t\t\t\t\t\t\t\t\t\t\t{flexRender(cell.column.columnDef.cell, cell.getContext())}\n\t\t\t\t\t\t\t\t\t\t</TableCell>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</TableRow>\n\t\t\t\t\t\t\t))\n\t\t\t\t\t\t)\n\t\t\t\t\t\t: (\n\t\t\t\t\t\t\t<TableRow>\n\t\t\t\t\t\t\t\t<TableCell colSpan={columns.length} className=\"h-24 text-center\">\n\t\t\t\t\t\t\t\t\tNo results.\n\t\t\t\t\t\t\t\t</TableCell>\n\t\t\t\t\t\t\t</TableRow>\n\t\t\t\t\t\t)}\n\t\t\t\t</TableBody>\n\t\t\t</Table>\n\t\t</div>\n\t);\n}\n","export function EmptyCluster() {\n\treturn (\n\t\t<div className=\"flex-col items-center justify-center px-16 space-y-3 text-center pt-30\">\n\t\t\t<p>No instances found.</p>\n\t\t</div>\n\t);\n}\n","import { Button } from '@/components/ui/button';\nimport { defaultInstanceRoute } from '@/config/constants';\nimport { useInstanceClient } from '@/config/useInstanceClient';\nimport { authStore } from '@/features/auth/store/authStore';\nimport { useInstanceAuth } from '@/hooks/useAuth';\nimport { useOrganizationClusterInstancePermissions } from '@/hooks/usePermissions';\nimport { Instance } from '@/integrations/api/api.patch';\nimport { onInstanceLogoutSubmit } from '@/integrations/api/instance/auth/onInstanceLogoutSubmit';\nimport { getOperationsUrlForInstance } from '@/lib/urls/getOperationsUrlForInstance';\nimport { Link } from '@tanstack/react-router';\nimport { LoaderCircleIcon } from 'lucide-react';\nimport { useCallback, useMemo } from 'react';\n\nexport function InstanceLogInCell(\n\t{ isSelfManaged, instance }: { readonly isSelfManaged: boolean; readonly instance: Instance },\n) {\n\tconst { user: instanceUser, isLoading: instanceAuthIsLoading } = useInstanceAuth(instance.id);\n\tconst operationsUrl = useMemo(() => getOperationsUrlForInstance(instance), [instance]);\n\tconst instanceClient = useInstanceClient({ operationsUrl });\n\tconst { update } = useOrganizationClusterInstancePermissions();\n\tconst isFabricConnect = authStore.checkForFabricConnect(instance.id);\n\n\tconst onSignOutClick = useCallback(async () => {\n\t\tawait onInstanceLogoutSubmit({ instanceClient, entityId: instance.id });\n\t\tauthStore.setUserForEntity(instance, null);\n\t}, [instance, instanceClient]);\n\n\tif (\n\t\tinstanceAuthIsLoading || !instance.status\n\t\t|| !['CLONE_READY', 'RUNNING', 'UPDATED', 'PENDING_UPGRADE'].includes(instance.status)\n\t) {\n\t\treturn <LoaderCircleIcon className=\"animate-spin\" color=\"gray\" />;\n\t}\n\n\tif (!instanceUser || isFabricConnect) {\n\t\treturn (\n\t\t\t<span className=\"flex gap-4\">\n\t\t\t\t{update && !isSelfManaged && (\n\t\t\t\t\t<Link\n\t\t\t\t\t\tto={`../instance/${instance.id}${defaultInstanceRoute}`}\n\t\t\t\t\t\tclassName=\"text-sm\"\n\t\t\t\t\t\taria-label={`Connect to ${instance.name} instance`}\n\t\t\t\t\t\ttitle={`Connect to ${instance.name} instance`}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Button variant=\"positiveOutline\">Fabric Connect</Button>\n\t\t\t\t\t</Link>\n\t\t\t\t)}\n\t\t\t\t<Link\n\t\t\t\t\tto={`../instance/${instance.id}/sign-in`}\n\t\t\t\t\tclassName=\"text-sm\"\n\t\t\t\t\taria-label={`Sign in to ${instance.name} instance`}\n\t\t\t\t\ttitle={`Sign in to ${instance.name} instance`}\n\t\t\t\t>\n\t\t\t\t\t<Button variant={update ? 'defaultOutline' : 'positiveOutline'}>Direct Sign In</Button>\n\t\t\t\t</Link>\n\t\t\t</span>\n\t\t);\n\t}\n\n\treturn (\n\t\t<span className=\"flex gap-4\">\n\t\t\t<Link\n\t\t\t\tto={`../instance/${instance.id}${defaultInstanceRoute}`}\n\t\t\t\tclassName=\"text-sm\"\n\t\t\t\taria-label={`Go to ${instance.name} instance`}\n\t\t\t\ttitle={`Go to ${instance.name} instance`}\n\t\t\t>\n\t\t\t\t<Button variant=\"positiveOutline\">Direct Connect</Button>\n\t\t\t</Link>\n\t\t\t<Button\n\t\t\t\tvariant=\"destructiveOutline\"\n\t\t\t\tclassName=\"text-sm\"\n\t\t\t\taria-label={`Sign out from ${instance.name} instance`}\n\t\t\t\ttitle={`Sign out from ${instance.name} instance`}\n\t\t\t\tonClick={onSignOutClick}\n\t\t\t>\n\t\t\t\tDirect Sign Out\n\t\t\t</Button>\n\t\t</span>\n\t);\n}\n","import { InstanceClientIdConfig } from '@/config/instanceClientConfig';\nimport { queryOptions } from '@tanstack/react-query';\n\nexport interface SystemStatus {\n\tid: 'availability' | 'maintenance' | 'primary' | string;\n\tstatus: 'Available' | 'Unavailable' | string;\n\t__updatedtime__: number;\n\t__createdtime__: number;\n}\n\nconst enum ComponentStatusName {\n\t'hdb.http' = 'hdb.http',\n\t'hdb.authentication' = 'hdb.authentication',\n\t'hdb.replication' = 'hdb.replication',\n\t'hdb.logging' = 'hdb.logging',\n\t'hdb.mqtt' = 'hdb.mqtt',\n\t'hdb.operationsApi' = 'hdb.operationsApi',\n\t'status-check.rest' = 'status-check.rest',\n\t'status-check.jsResource' = 'status-check.jsResource',\n}\n\ninterface ComponentStatus {\n\tname: ComponentStatusName | string;\n\tcomponentName: ComponentStatusName | string;\n\tstatus: 'healthy' | string;\n\tlastChecked: {\n\t\tworkers: Record<string, number>;\n\t\tmain: number;\n\t};\n}\n\ninterface StatusResponse {\n\tsystemStatus: SystemStatus[];\n\trestartRequired: boolean;\n\tcomponentStatus: ComponentStatus[];\n\n\t[key: string]: unknown;\n}\n\nexport function getStatusQueryOptions({ entityId, instanceClient }: InstanceClientIdConfig, enabled?: boolean) {\n\treturn queryOptions({\n\t\tqueryKey: [entityId, 'get_status'] as const,\n\t\tstaleTime: 9_000,\n\t\trefetchInterval: 10_000,\n\t\tretryDelay: 10_000,\n\t\tthrowOnError: false,\n\t\tenabled,\n\t\tqueryFn: async () => {\n\t\t\tconst { data } = await instanceClient.post<StatusResponse>('/', {\n\t\t\t\toperation: 'get_status',\n\t\t\t});\n\t\t\treturn data;\n\t\t},\n\t});\n}\n\nexport function getSystemStatusById(\n\tstatusResponse: StatusResponse | undefined,\n\tid: SystemStatus['id'],\n): SystemStatus['status'] | undefined {\n\tconst systemStatus = statusResponse?.systemStatus?.find(s => s.id === id);\n\treturn systemStatus?.status;\n}\n","import { InstanceClientIdConfig } from '@/config/instanceClientConfig';\nimport { SystemStatus } from '@/integrations/api/instance/status/getStatus';\nimport { ReplicatedResponse } from '@/integrations/api/replication';\nimport { queryClient } from '@/react-query/queryClient';\nimport { useMutation } from '@tanstack/react-query';\n\ninterface SetConfigurationParams extends Pick<SystemStatus, 'id' | 'status'>, InstanceClientIdConfig {\n}\n\nasync function setStatus({\n\tinstanceClient,\n\tid,\n\tstatus,\n}: SetConfigurationParams): Promise<ReplicatedResponse> {\n\tconst { data } = await instanceClient.post('/', {\n\t\toperation: 'set_status',\n\t\tid,\n\t\tstatus,\n\t});\n\treturn data;\n}\n\nexport function useSetStatus() {\n\treturn useMutation({\n\t\tmutationFn: setStatus,\n\t\tonSuccess: (_data, variables) => queryClient.invalidateQueries({ queryKey: [variables.entityId, 'get_status'] }),\n\t});\n}\n","import { Badge } from '@/components/ui/badge';\nimport { Button } from '@/components/ui/button';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { useOrganizationClusterInstancePermissions } from '@/hooks/usePermissions';\nimport { Instance } from '@/integrations/api/api.patch';\nimport { getStatusQueryOptions, getSystemStatusById } from '@/integrations/api/instance/status/getStatus';\nimport { useSetStatus } from '@/integrations/api/instance/status/setStatus';\nimport { getOperationsUrlForInstance } from '@/lib/urls/getOperationsUrlForInstance';\nimport { useQuery } from '@tanstack/react-query';\nimport { LoaderCircleIcon, ShieldCheckIcon, ShieldXIcon } from 'lucide-react';\nimport { useEffect, useMemo, useState } from 'react';\n\nexport function InstanceStatusCell(\n\t{ instance, index }: { readonly instance: Instance; index: number },\n) {\n\tconst { update: canManage } = useOrganizationClusterInstancePermissions();\n\tconst operationsUrl = useMemo(() => getOperationsUrlForInstance(instance), [instance]);\n\tconst instanceParams = useInstanceClientIdParams({\n\t\toperationsUrl,\n\t\tinstanceId: instance.id,\n\t\tforceFabricConnect: true,\n\t});\n\tconst { mutate: setStatus, isPending: isSettingStatus } = useSetStatus();\n\n\tconst [ready, setReady] = useState(false);\n\n\t// Spread the status requests out.\n\tuseEffect(() => {\n\t\tconst timer = setTimeout(() => setReady(true), index * 500);\n\t\treturn () => clearTimeout(timer);\n\t}, [index]);\n\n\tconst { data: statusResponse, isLoading, isFetching } = useQuery(\n\t\tgetStatusQueryOptions(instanceParams, ready && canManage),\n\t);\n\n\tconst systemStatus = getSystemStatusById(statusResponse, 'availability') || 'Unknown';\n\tconst isAvailable = systemStatus === 'Available';\n\tconst isUnavailable = systemStatus === 'Unavailable';\n\n\tif (!canManage) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<div className=\"flex items-center gap-2\">\n\t\t\t<Tooltip>\n\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t<div className=\"flex items-center\">\n\t\t\t\t\t\t{isLoading || !ready || (isFetching && !statusResponse)\n\t\t\t\t\t\t\t? <LoaderCircleIcon className=\"animate-spin size-5 text-muted-foreground\" />\n\t\t\t\t\t\t\t: (\n\t\t\t\t\t\t\t\t<Badge\n\t\t\t\t\t\t\t\t\tvariant={isAvailable ? 'success' : isUnavailable ? 'destructive' : 'default'}\n\t\t\t\t\t\t\t\t\tclassName=\"size-4 rounded-full p-0\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<span className=\"sr-only\">{isAvailable ? 'Online' : 'Offline'}</span>\n\t\t\t\t\t\t\t\t</Badge>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t</TooltipTrigger>\n\t\t\t\t<TooltipContent>\n\t\t\t\t\t{isFetching && statusResponse ? 'Refreshing... ' : ''}\n\t\t\t\t\t{systemStatus}\n\t\t\t\t</TooltipContent>\n\t\t\t</Tooltip>\n\n\t\t\t{canManage && (\n\t\t\t\t<div className=\"flex gap-1\">\n\t\t\t\t\t{isAvailable && (\n\t\t\t\t\t\t<Tooltip>\n\t\t\t\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tvariant=\"destructiveGhost\"\n\t\t\t\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\t\t\t\tonClick={() => setStatus({ ...instanceParams, id: 'availability', status: 'Unavailable' })}\n\t\t\t\t\t\t\t\t\tdisabled={isSettingStatus}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{isSettingStatus\n\t\t\t\t\t\t\t\t\t\t? <LoaderCircleIcon className=\"animate-spin size-4\" />\n\t\t\t\t\t\t\t\t\t\t: <ShieldXIcon className=\"size-4\" />}\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</TooltipTrigger>\n\t\t\t\t\t\t\t<TooltipContent>Bring out of rotation</TooltipContent>\n\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t)}\n\t\t\t\t\t{isUnavailable && (\n\t\t\t\t\t\t<Tooltip>\n\t\t\t\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\t\t\t\tonClick={() => setStatus({ ...instanceParams, id: 'availability', status: 'Available' })}\n\t\t\t\t\t\t\t\t\tdisabled={isSettingStatus}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{isSettingStatus\n\t\t\t\t\t\t\t\t\t\t? <LoaderCircleIcon className=\"animate-spin size-4\" />\n\t\t\t\t\t\t\t\t\t\t: <ShieldCheckIcon className=\"size-4\" />}\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</TooltipTrigger>\n\t\t\t\t\t\t\t<TooltipContent>Bring back into rotation</TooltipContent>\n\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","import { DataTable } from '@/components/DataTable';\nimport { SubNavMenu } from '@/components/SubNavMenu';\nimport { TextLoadingSkeleton } from '@/components/TextLoadingSkeleton';\nimport { Badge } from '@/components/ui/badge';\nimport { Card, CardContent } from '@/components/ui/card';\nimport { renderBadgeStatusVariant } from '@/components/ui/utils/badgeStatus';\nimport { deletedClusterStatuses } from '@/config/clusterStatuses';\nimport { calculateInstanceFQDN } from '@/features/clusters/upsert/lib/calculateInstanceFQDN';\nimport { Instance } from '@/integrations/api/api.patch';\nimport { clusterIsSelfManaged } from '@/integrations/api/clusterIsSelfManaged';\nimport { excludeFalsy } from '@/lib/arrays/excludeFalsy';\nimport { byInstanceFqdnThenPort } from '@/lib/arrays/sort/byInstanceFqdnThenPort';\nimport { capitalizeWords } from '@/lib/string/capitalizeWords';\nimport { useQuery } from '@tanstack/react-query';\nimport { useParams } from '@tanstack/react-router';\nimport { ColumnDef } from '@tanstack/react-table';\nimport { useMemo } from 'react';\nimport { EmptyCluster } from './EmptyCluster';\nimport { InstanceLogInCell } from './InstanceLogInCell';\nimport { InstanceStatusCell } from './InstanceStatusCell';\nimport { getClusterInfoQueryOptions } from './queries/getClusterInfoQuery';\n\nexport function Instances() {\n\tconst { clusterId }: { clusterId: string } = useParams({ strict: false });\n\tconst { data: cluster, isLoading: clusterIsLoading } = useQuery(\n\t\tgetClusterInfoQueryOptions(clusterId, true),\n\t);\n\tconst isSelfManaged = clusterIsSelfManaged(cluster);\n\n\tconst columns: ColumnDef<Instance>[] = useMemo(\n\t\t() =>\n\t\t\t([\n\t\t\t\t{\n\t\t\t\t\tid: 'instanceActions',\n\t\t\t\t\tsize: 1,\n\t\t\t\t\tminSize: 1,\n\t\t\t\t\tcell: (cell) => (\n\t\t\t\t\t\t<div className=\"flex justify-end gap-2 items-center\">\n\t\t\t\t\t\t\t<InstanceLogInCell isSelfManaged={isSelfManaged} instance={cell.row.original} />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t\tisSelfManaged && {\n\t\t\t\t\taccessorKey: 'instanceFqdn',\n\t\t\t\t\tsize: 90,\n\t\t\t\t\theader: 'URL',\n\t\t\t\t\tcell: (cell) => {\n\t\t\t\t\t\treturn calculateInstanceFQDN({\n\t\t\t\t\t\t\tsecure: cell.row.original.operationsApiSecure ? 'true' : 'false',\n\t\t\t\t\t\t\tport: cell.row.original.operationsApiPort,\n\t\t\t\t\t\t\tfqdn: cell.row.original.instanceFqdn,\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t!isSelfManaged && {\n\t\t\t\t\taccessorKey: 'name',\n\t\t\t\t\tsize: 90,\n\t\t\t\t\theader: 'Name',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\taccessorKey: 'status',\n\t\t\t\t\theader: 'Status',\n\t\t\t\t\tsize: 1,\n\t\t\t\t\tminSize: 1,\n\t\t\t\t\tcell: (cell) => {\n\t\t\t\t\t\tconst status = cell.getValue() as string;\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t\t<InstanceStatusCell instance={cell.row.original} index={cell.row.index} />\n\t\t\t\t\t\t\t\t{status ? <Badge variant={renderBadgeStatusVariant(status)}>{capitalizeWords(status)}</Badge> : null}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t!isSelfManaged && {\n\t\t\t\t\taccessorKey: 'version',\n\t\t\t\t\tsize: 1,\n\t\t\t\t\tminSize: 1,\n\t\t\t\t\theader: 'Version',\n\t\t\t\t},\n\t\t\t\t!isSelfManaged && {\n\t\t\t\t\taccessorKey: 'storageGb',\n\t\t\t\t\tsize: 1,\n\t\t\t\t\tminSize: 1,\n\t\t\t\t\theader: 'Storage',\n\t\t\t\t\tcell: (cell) => {\n\t\t\t\t\t\tconst value = cell.getValue() as number;\n\t\t\t\t\t\treturn `${value} GB`; // This is already in GB\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t!isSelfManaged && {\n\t\t\t\t\taccessorKey: 'usedStorageGb',\n\t\t\t\t\tsize: 1,\n\t\t\t\t\tminSize: 1,\n\t\t\t\t\theader: 'Used Storage',\n\t\t\t\t\tcell: (cell) => {\n\t\t\t\t\t\tconst value = cell.getValue();\n\t\t\t\t\t\treturn value === undefined ? '-' : `${value} GB`;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t!isSelfManaged && {\n\t\t\t\t\taccessorKey: 'cpuCores',\n\t\t\t\t\tsize: 1,\n\t\t\t\t\tminSize: 1,\n\t\t\t\t\theader: 'Cores/Threads',\n\t\t\t\t\tcell: (cell) => {\n\t\t\t\t\t\treturn <>{cell.row.original.cpuCores} / {cell.row.original.threads}</>;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t!isSelfManaged && {\n\t\t\t\t\taccessorKey: 'memoryMb',\n\t\t\t\t\tsize: 1,\n\t\t\t\t\tminSize: 1,\n\t\t\t\t\theader: 'Memory',\n\t\t\t\t\tcell: (cell) => {\n\t\t\t\t\t\tconst value = cell.getValue() as number;\n\t\t\t\t\t\treturn `${value / 1024} GB`; // The value is in MiB since that's how memory is sold, but alwayas says MB or GB instead of MiB or GiB\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t] satisfies Array<ColumnDef<Instance> | false>).filter(excludeFalsy),\n\t\t[isSelfManaged],\n\t);\n\tconst instances = useMemo(\n\t\t() => {\n\t\t\tif (!cluster?.instances) {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\treturn cluster.instances\n\t\t\t\t.filter(instance => instance.status && !deletedClusterStatuses.includes(instance.status))\n\t\t\t\t.sort(byInstanceFqdnThenPort);\n\t\t},\n\t\t[cluster],\n\t);\n\treturn (\n\t\t<>\n\t\t\t<SubNavMenu />\n\t\t\t<div className=\"mt-32 px-4 pt-4 md:px-12 min-h-[calc(100vh-(--spacing(32)))]\">\n\t\t\t\t<Card className=\"p-0 mt-4 min-h-96\">\n\t\t\t\t\t<CardContent className=\"p-0 min-h-96\">\n\t\t\t\t\t\t{clusterIsLoading\n\t\t\t\t\t\t\t? <TextLoadingSkeleton />\n\t\t\t\t\t\t\t: instances.length\n\t\t\t\t\t\t\t? <DataTable data={instances} columns={columns} />\n\t\t\t\t\t\t\t: <EmptyCluster />}\n\t\t\t\t\t</CardContent>\n\t\t\t\t</Card>\n\t\t\t</div>\n\t\t</>\n\t);\n}\n","import { NestedContentWithSubNavMenu } from '@/components/NestedContentWithSubNavMenu';\nimport { TextLoadingSkeleton } from '@/components/TextLoadingSkeleton';\nimport { activeClusterStatuses } from '@/config/clusterStatuses';\nimport { ClusterCardAction } from '@/features/clusters/components/ClusterCardAction';\nimport { ClusterProgress } from '@/features/clusters/components/ClusterProgress';\nimport { useQuery } from '@tanstack/react-query';\nimport { useParams } from '@tanstack/react-router';\nimport { useMemo } from 'react';\nimport { getClusterInfoQueryOptions } from './queries/getClusterInfoQuery';\n\nexport function Scaling() {\n\tconst { clusterId }: { organizationId: string; clusterId: string } = useParams({ strict: false });\n\tconst { data: cluster, isLoading: clusterIsLoading } = useQuery(\n\t\tgetClusterInfoQueryOptions(clusterId, 2_000),\n\t);\n\tconst status = cluster?.status;\n\tconst clusterIsActive = useMemo(() => {\n\t\treturn status && activeClusterStatuses.includes(status);\n\t}, [status]);\n\n\tif (clusterIsLoading || !cluster) {\n\t\treturn (\n\t\t\t<NestedContentWithSubNavMenu className=\"flex justify-center\">\n\t\t\t\t<TextLoadingSkeleton />\n\t\t\t</NestedContentWithSubNavMenu>\n\t\t);\n\t}\n\n\tif (clusterIsActive) {\n\t\treturn (\n\t\t\t<NestedContentWithSubNavMenu className=\"flex justify-center\">\n\t\t\t\t<div className=\"center w-2xl flex flex-col gap-4\">\n\t\t\t\t\t<h1 className=\"text-xl text-center\">All done!</h1>\n\t\t\t\t\t<ClusterProgress cluster={cluster} forceProgressBarVisible={true} />\n\t\t\t\t\t<p>Your cluster finished updating, and is ready for interaction.</p>\n\t\t\t\t\t<div className=\"text-center\">\n\t\t\t\t\t\t<ClusterCardAction cluster={cluster} />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</NestedContentWithSubNavMenu>\n\t\t);\n\t}\n\n\treturn (\n\t\t<NestedContentWithSubNavMenu className=\"flex justify-center\">\n\t\t\t<div className=\"center w-2xl flex flex-col gap-4\">\n\t\t\t\t<h1 className=\"text-xl text-center\">Here we go!</h1>\n\t\t\t\t<ClusterProgress cluster={cluster} forceProgressBarVisible={true} />\n\t\t\t\t<p>\n\t\t\t\t\tYour cluster is updating with the latest changes. This includes waiting several minutes to let traffic drain\n\t\t\t\t\tsafely.{' '}\n\t\t\t\t\t<span className=\"text-muted-foreground\">\n\t\t\t\t\t\tWe will let you know when we are ready for you to connect! In the meantime, join us on{' '}\n\t\t\t\t\t\t<a\n\t\t\t\t\t\t\thref=\"https://discord.gg/VzZuaw3Xay\"\n\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\trel=\"noreferrer\"\n\t\t\t\t\t\t\tclassName=\"underline hover:text-blue-300\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tDiscord\n\t\t\t\t\t\t</a>! Get real-time help from our engineers, see feature drops early, and connect with others building on\n\t\t\t\t\t\tFabric.\n\t\t\t\t\t</span>\n\t\t\t\t</p>\n\t\t\t</div>\n\t\t</NestedContentWithSubNavMenu>\n\t);\n}\n","import { ContactUs } from '@/components/ContactUs';\nimport { NestedContentWithSubNavMenu } from '@/components/NestedContentWithSubNavMenu';\nimport { TextLoadingSkeleton } from '@/components/TextLoadingSkeleton';\nimport { Button } from '@/components/ui/button';\nimport { isFailed } from '@/components/ui/utils/badgeStatus';\nimport { activeClusterStatuses } from '@/config/clusterStatuses';\nimport { ClusterCardAction } from '@/features/clusters/components/ClusterCardAction';\nimport { ClusterProgress } from '@/features/clusters/components/ClusterProgress';\nimport { useLocalStorage } from '@/hooks/useLocalStorage';\nimport { LocalStorageKeys } from '@/lib/storage/localStorageKeys';\nimport { useQuery } from '@tanstack/react-query';\nimport { useParams, useRouter } from '@tanstack/react-router';\nimport { CloudAlertIcon } from 'lucide-react';\nimport { useCallback, useMemo } from 'react';\nimport { getClusterInfoQueryOptions } from './queries/getClusterInfoQuery';\n\nexport function StartingUp() {\n\tconst router = useRouter();\n\tconst { clusterId }: { organizationId: string; clusterId: string } = useParams({ strict: false });\n\tconst { data: cluster, isLoading: clusterIsLoading } = useQuery(\n\t\tgetClusterInfoQueryOptions(clusterId, 2_000),\n\t);\n\n\tconst status = cluster?.status;\n\n\tconst clusterIsActive = useMemo(() => {\n\t\treturn status && activeClusterStatuses.includes(status);\n\t}, [status]);\n\tconst clusterHasFailed = isFailed(status);\n\tconst [, setSavedClusterState] = useLocalStorage<unknown | null>(LocalStorageKeys.SavedClusterState, null);\n\n\tconst onTryAgainClick = useCallback(() => {\n\t\tsetSavedClusterState(cluster);\n\t\tvoid router.navigate({ to: `/${cluster!.organizationId}/new-cluster` });\n\t}, [cluster, router, setSavedClusterState]);\n\n\tif (clusterIsLoading || !cluster) {\n\t\treturn (\n\t\t\t<NestedContentWithSubNavMenu className=\"flex justify-center\">\n\t\t\t\t<TextLoadingSkeleton />\n\t\t\t</NestedContentWithSubNavMenu>\n\t\t);\n\t}\n\n\tif (clusterHasFailed) {\n\t\treturn (\n\t\t\t<NestedContentWithSubNavMenu className=\"flex justify-center\">\n\t\t\t\t<div className=\"center max-w-2xl flex flex-col gap-4 items-center\">\n\t\t\t\t\t<CloudAlertIcon className=\"w-24 h-24\" />\n\t\t\t\t\t<span>\n\t\t\t\t\t\tYour cluster failed to successfully start. This is usually caused by temporary communication problems. Would\n\t\t\t\t\t\tyou like to try again? We also get notified about these failures. <ContactUs /> if you want more help.\n\t\t\t\t\t</span>\n\t\t\t\t\t<Button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tvariant=\"positiveOutline\"\n\t\t\t\t\t\tonClick={onTryAgainClick}\n\t\t\t\t\t>\n\t\t\t\t\t\tTry Again\n\t\t\t\t\t</Button>\n\t\t\t\t</div>\n\t\t\t</NestedContentWithSubNavMenu>\n\t\t);\n\t}\n\n\tif (clusterIsActive) {\n\t\treturn (\n\t\t\t<NestedContentWithSubNavMenu className=\"flex justify-center\">\n\t\t\t\t<div className=\"center max-w-2xl flex flex-col gap-4\">\n\t\t\t\t\t<h1 className=\"text-xl text-center\">It's ready!</h1>\n\t\t\t\t\t<ClusterProgress cluster={cluster} forceProgressBarVisible={true} />\n\t\t\t\t\t<p>\n\t\t\t\t\t\tLet's set up your secure, browser-to-cluster connection now.{' '}\n\t\t\t\t\t\t<span className=\"text-muted-foreground\">\n\t\t\t\t\t\t\tDid you know during this step, you connect straight to your cluster, providing a private secure\n\t\t\t\t\t\t\tconnection? That's <em>Direct Connect</em>! Once you create your user, you will have the option to{' '}\n\t\t\t\t\t\t\t<em>Fabric Connect</em> from your Fabric account without having to sign in again.\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</p>\n\t\t\t\t\t<div className=\"text-center\">\n\t\t\t\t\t\t<ClusterCardAction cluster={cluster} />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</NestedContentWithSubNavMenu>\n\t\t);\n\t}\n\n\treturn (\n\t\t<NestedContentWithSubNavMenu className=\"flex justify-center\">\n\t\t\t<div className=\"center max-w-2xl flex flex-col gap-4\">\n\t\t\t\t<h1 className=\"text-xl text-center\">Here we go!</h1>\n\t\t\t\t<ClusterProgress cluster={cluster} forceProgressBarVisible={true} />\n\t\t\t\t<p>\n\t\t\t\t\tYour cluster is spinning up with the latest changes, including your own DNS records and private connections.\n\t\t\t\t\tPlease wait while we get everything going.{' '}\n\t\t\t\t\t<span className=\"text-muted-foreground\">\n\t\t\t\t\t\tWe will let you know when we are ready for you to connect! In the meantime, join us on{' '}\n\t\t\t\t\t\t<a\n\t\t\t\t\t\t\thref=\"https://discord.gg/VzZuaw3Xay\"\n\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\trel=\"noreferrer\"\n\t\t\t\t\t\t\tclassName=\"underline hover:text-blue-300\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tDiscord\n\t\t\t\t\t\t</a>! Get real-time help from our engineers, see feature drops early, and connect with others building on\n\t\t\t\t\t\tFabric.\n\t\t\t\t\t</span>\n\t\t\t\t</p>\n\t\t\t</div>\n\t\t</NestedContentWithSubNavMenu>\n\t);\n}\n","import { defaultInstanceRouteUpOne } from '@/config/constants';\nimport { ClusterInstanceSignIn } from '@/features/auth/ClusterInstanceSignIn';\nimport { authStore } from '@/features/auth/store/authStore';\nimport { createRoute, redirect } from '@tanstack/react-router';\nimport { clusterLayoutRoute } from './clusterLayoutRoute';\nimport { DomainsPage } from './domains/Page';\nimport { FinishSetup } from './FinishSetup';\nimport { Instances } from './Instances';\nimport { Scaling } from './Scaling';\nimport { StartingUp } from './StartingUp';\n\nconst clusterInstancesRoute = createRoute({\n\tgetParentRoute: () => clusterLayoutRoute,\n\tpath: 'instances',\n\thead: () => ({ meta: [{ title: 'Instances — Harper Fabric' }] }),\n\tcomponent: Instances,\n});\n\nconst clusterStartingUpRoute = createRoute({\n\tgetParentRoute: () => clusterLayoutRoute,\n\tpath: 'starting-up',\n\thead: () => ({ meta: [{ title: 'Starting Up — Harper Fabric' }] }),\n\tcomponent: StartingUp,\n});\n\nconst clusterScalingRoute = createRoute({\n\tgetParentRoute: () => clusterLayoutRoute,\n\tpath: 'scaling',\n\thead: () => ({ meta: [{ title: 'Scaling — Harper Fabric' }] }),\n\tcomponent: Scaling,\n});\n\nconst clusterDomainsRoute = createRoute({\n\tgetParentRoute: () => clusterLayoutRoute,\n\tpath: 'domains',\n\thead: () => ({ meta: [{ title: 'Domains — Harper Fabric' }] }),\n\tcomponent: DomainsPage,\n});\n\nconst clusterSignInRoute = createRoute({\n\tgetParentRoute: () => clusterLayoutRoute,\n\tpath: 'sign-in',\n\thead: () => ({ meta: [{ title: 'Sign In — Harper Fabric' }] }),\n\tcomponent: ClusterInstanceSignIn,\n\tbeforeLoad: ({ context, location, params }) => {\n\t\tconst isFabricConnect = authStore.checkForFabricConnect(params.clusterId);\n\t\tif (context.authentication[params.clusterId]?.user && !isFabricConnect) {\n\t\t\tconst search: Record<string, string> = location?.search;\n\t\t\tthrow redirect({\n\t\t\t\tto: search?.redirect?.startsWith('/')\n\t\t\t\t\t? search.redirect\n\t\t\t\t\t: defaultInstanceRouteUpOne,\n\t\t\t});\n\t\t}\n\t},\n});\n\nconst instanceSignInRoute = createRoute({\n\tgetParentRoute: () => clusterLayoutRoute,\n\tpath: 'instance/$instanceId/sign-in',\n\thead: () => ({ meta: [{ title: 'Sign In — Harper Fabric' }] }),\n\tcomponent: ClusterInstanceSignIn,\n\tbeforeLoad: ({ context, location, params }) => {\n\t\tconst isFabricConnect = authStore.checkForFabricConnect(params.clusterId)\n\t\t\t|| authStore.checkForFabricConnect(params.instanceId);\n\t\tif (isFabricConnect) {\n\t\t\treturn;\n\t\t}\n\t\tif (context.authentication[params.instanceId]?.user) {\n\t\t\tconst search: Record<string, string> = location?.search;\n\t\t\tthrow redirect({\n\t\t\t\tto: search?.redirect?.startsWith('/')\n\t\t\t\t\t? search.redirect\n\t\t\t\t\t: defaultInstanceRouteUpOne,\n\t\t\t});\n\t\t}\n\t},\n});\n\nconst clusterFinishSetupRoute = createRoute({\n\tgetParentRoute: () => clusterLayoutRoute,\n\tpath: 'finish-setup',\n\thead: () => ({ meta: [{ title: 'Create Admin User — Harper Fabric' }] }),\n\tcomponent: FinishSetup,\n});\n\nexport const clusterRoutes = [\n\tclusterInstancesRoute,\n\tclusterStartingUpRoute,\n\tclusterScalingRoute,\n\tclusterDomainsRoute,\n\tclusterFinishSetupRoute,\n\tclusterSignInRoute,\n\tinstanceSignInRoute,\n];\n","import { createInstanceLayoutRoute } from '@/features/instance/instanceLayoutRoute';\nimport { createRoute } from '@tanstack/react-router';\n\nexport function createAPIsRouteTree(instanceLayoutRoute: ReturnType<typeof createInstanceLayoutRoute>) {\n\treturn createRoute({\n\t\tgetParentRoute: () => instanceLayoutRoute,\n\t\tpath: 'apis',\n\t\thead: () => ({ meta: [{ title: 'APIs — Harper Fabric' }] }),\n\t}).lazy(() => import('./index.lazy').then((d) => d.route));\n}\n","import { createInstanceLayoutRoute } from '@/features/instance/instanceLayoutRoute';\nimport { createRoute, lazyRouteComponent } from '@tanstack/react-router';\n\nexport function createApplicationsRoutes(instanceLayoutRoute: ReturnType<typeof createInstanceLayoutRoute>) {\n\tconst instanceApplicationsIndexRoute = createRoute({\n\t\tgetParentRoute: () => instanceLayoutRoute,\n\t\tpath: '/',\n\t\thead: () => ({ meta: [{ title: 'Applications — Harper Fabric' }] }),\n\t\t// Lazy: the applications editor pulls in Monaco, the AI SDK, motion and\n\t\t// react-markdown. Loading it on demand keeps all of that off first paint.\n\t\tcomponent: lazyRouteComponent(() => import('@/features/instance/applications'), 'ApplicationsEditor'),\n\t});\n\n\treturn [\n\t\tinstanceApplicationsIndexRoute,\n\t];\n}\n","import { InstanceClientIdConfig } from '@/config/instanceClientConfig';\nimport { queryOptions } from '@tanstack/react-query';\n\nexport interface CertificateDetails {\n\tissuer: string;\n\tsubject: string;\n\tserial_number: string;\n\tvalid_from: string;\n\tvalid_to: string;\n\tsubject_alt_name?: string;\n}\n\nexport interface Certificate {\n\tname: string;\n\tcertificate: string;\n\tprivate_key_name?: string;\n\tis_authority: boolean;\n\tis_self_signed: boolean;\n\tuses: string[];\n\tdetails: CertificateDetails;\n\thosts?: string[];\n}\n\nasync function listCertificates({ instanceClient }: InstanceClientIdConfig) {\n\tconst { data } = await instanceClient.post<Certificate[]>('/', {\n\t\toperation: 'list_certificates',\n\t});\n\treturn data;\n}\n\nexport function listCertificatesQueryOptions(params: InstanceClientIdConfig) {\n\treturn queryOptions({\n\t\tqueryKey: [params.entityId, 'list_certificates'] as const,\n\t\tqueryFn: () => listCertificates(params),\n\t});\n}\n","import { Certificate } from '@/integrations/api/instance/certificates/listCertificates';\nimport { ColumnDef, createColumnHelper } from '@tanstack/react-table';\n\nconst columnHelper = createColumnHelper<Certificate>();\n\nexport const dataTableColumns: Array<ColumnDef<Certificate>> = [\n\t{\n\t\theader: 'Certificate Name',\n\t\taccessorKey: 'name',\n\t\tenableSorting: true,\n\t},\n\t{\n\t\theader: 'Issuer',\n\t\taccessorKey: 'details.issuer',\n\t\tenableSorting: true,\n\t},\n\tcolumnHelper.display({\n\t\theader: 'Expires At',\n\t\tenableSorting: false,\n\t\tid: 'details.valid_to',\n\t\tcell: (props) =>\n\t\t\tprops.row.original.details.valid_to ? new Date(props.row.original.details.valid_to).toLocaleString() : 'N/A',\n\t}),\n];\n","import { cn } from '@/lib/cn';\nimport * as React from 'react';\n\nexport function Textarea({ className, ...props }: React.ComponentProps<'textarea'>) {\n\treturn (\n\t\t<textarea\n\t\t\tdata-slot=\"input\"\n\t\t\tclassName={cn(\n\t\t\t\t`border-input file:text-foreground placeholder:text-muted-foreground selection:bg-purple\n selection:text-primary-foreground\n dark:aria-invalid:outline-destructive dark:aria-invalid:ring-destructive/50 ring-ring/10\n dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 aria-invalid:outline-destructive/60\n aria-invalid:ring-destructive/20 aria-invalid:border-destructive/60 dark:aria-invalid:border-destructive\n flex w-full min-w-0 rounded-md border bg-white text-foreground dark:bg-grey-700 dark:text-white\n file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium\n focus-visible:ring-1 focus-visible:outline-none focus-visible:ring-purple disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\n aria-invalid:focus-visible:ring-[1px] aria-invalid:focus-visible:outline-none md:text-sm dark:aria-invalid:focus-visible:ring-1`,\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n","import { InstanceClientIdConfig } from '@/config/instanceClientConfig';\n\nexport interface AddCertificateParams {\n\tname: string;\n\tcertificate: string;\n\tprivate_key?: string;\n\tis_authority: boolean;\n\thosts?: string[];\n\tuses?: string[];\n}\n\nexport async function addCertificate({ instanceClient }: InstanceClientIdConfig, params: AddCertificateParams) {\n\tconst { data } = await instanceClient.post<{ message: string }>('/', {\n\t\toperation: 'add_certificate',\n\t\t...params,\n\t});\n\treturn data;\n}\n","import { InstanceClientIdConfig } from '@/config/instanceClientConfig';\nimport { useMutation } from '@tanstack/react-query';\nimport { z } from 'zod';\nimport { addCertificate, AddCertificateParams } from './addCertificate';\n\nexport const CertificateSchema = z.object({\n\tname: z.string().min(1, 'Name is required'),\n\tcertificate: z.string().min(1, 'Certificate is required'),\n\tprivate_key: z.string().optional(),\n\tis_authority: z.boolean().default(false),\n\thosts: z.string().optional(),\n\tuses: z.string().optional(),\n});\n\nexport function useAddCertificate() {\n\treturn useMutation({\n\t\tmutationFn: ({\n\t\t\tinstanceParams,\n\t\t\tcertificateParams,\n\t\t}: {\n\t\t\tinstanceParams: InstanceClientIdConfig;\n\t\t\tcertificateParams: AddCertificateParams;\n\t\t}) => addCertificate(instanceParams, certificateParams),\n\t});\n}\n","import { Button } from '@/components/ui/button';\nimport {\n\tDialog,\n\tDialogContent,\n\tDialogDescription,\n\tDialogFooter,\n\tDialogHeader,\n\tDialogTitle,\n} from '@/components/ui/dialog';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormDescription } from '@/components/ui/form/FormDescription';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { Switch } from '@/components/ui/switch';\nimport { Textarea } from '@/components/ui/textarea';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { CertificateSchema, useAddCertificate } from '@/integrations/api/instance/certificates/useAddCertificate';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { Save } from 'lucide-react';\nimport { useCallback } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\n\nexport function AddCertificateModal({\n\tisModalOpen,\n\tonChangesSaved,\n\tsetIsModalOpen,\n}: {\n\tisModalOpen: boolean;\n\tonChangesSaved: () => void;\n\tsetIsModalOpen: (open: boolean) => void;\n}) {\n\tconst form = useForm({\n\t\tresolver: zodResolver(CertificateSchema),\n\t\tdefaultValues: {\n\t\t\tname: '',\n\t\t\tcertificate: '',\n\t\t\tprivate_key: '',\n\t\t\tis_authority: false,\n\t\t\thosts: '',\n\t\t\tuses: '',\n\t\t},\n\t});\n\tconst instanceParams = useInstanceClientIdParams();\n\tconst { mutate: addCertificate, isPending } = useAddCertificate();\n\n\tconst onSubmitClick = useCallback(\n\t\tasync (formData: z.infer<typeof CertificateSchema>) => {\n\t\t\tconst { hosts, uses, private_key, ...rest } = formData;\n\t\t\tconst hostsArray = hosts\n\t\t\t\t? hosts\n\t\t\t\t\t.split(',')\n\t\t\t\t\t.map((h) => h.trim())\n\t\t\t\t\t.filter(Boolean)\n\t\t\t\t: undefined;\n\n\t\t\tconst usesArray = uses\n\t\t\t\t? uses\n\t\t\t\t\t.split(',')\n\t\t\t\t\t.map((u) => u.trim())\n\t\t\t\t\t.filter(Boolean)\n\t\t\t\t: undefined;\n\n\t\t\taddCertificate(\n\t\t\t\t{\n\t\t\t\t\tinstanceParams,\n\t\t\t\t\tcertificateParams: {\n\t\t\t\t\t\t...rest,\n\t\t\t\t\t\tprivate_key: private_key || undefined,\n\t\t\t\t\t\thosts: hostsArray && hostsArray.length > 0 ? hostsArray : undefined,\n\t\t\t\t\t\tuses: usesArray && usesArray.length > 0 ? usesArray : undefined,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tonSuccess: () => {\n\t\t\t\t\t\tform.reset();\n\t\t\t\t\t\tonChangesSaved();\n\t\t\t\t\t\ttoast.success('Certificate added successfully!');\n\t\t\t\t\t\tsetIsModalOpen(false);\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t\t[addCertificate, form, instanceParams, onChangesSaved, setIsModalOpen],\n\t);\n\n\tconst onClickCancel = useCallback(() => {\n\t\tform.reset();\n\t\tsetIsModalOpen(false);\n\t}, [form, setIsModalOpen]);\n\n\treturn (\n\t\t<Dialog onOpenChange={setIsModalOpen} open={isModalOpen}>\n\t\t\t<DialogContent aria-describedby={undefined}>\n\t\t\t\t<Form {...form}>\n\t\t\t\t\t<form\n\t\t\t\t\t\tid=\"instance-add-certificate-form\"\n\t\t\t\t\t\tname=\"instance-add-certificate-form\"\n\t\t\t\t\t\tonSubmit={form.handleSubmit(onSubmitClick)}\n\t\t\t\t\t\tclassName=\"grid gap-4 my-4\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<DialogHeader>\n\t\t\t\t\t\t\t<DialogTitle>Add New Certificate</DialogTitle>\n\t\t\t\t\t\t\t<DialogDescription>\n\t\t\t\t\t\t\t\tEnter the details of your Certificate below.\n\t\t\t\t\t\t\t</DialogDescription>\n\t\t\t\t\t\t</DialogHeader>\n\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"name\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Name</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"off\"\n\t\t\t\t\t\t\t\t\t\t\tautoFocus={true}\n\t\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"is_authority\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem className=\"flex flex-row items-center justify-between rounded-lg border border-gray-800 p-3 shadow-sm\">\n\t\t\t\t\t\t\t\t\t<div className=\"space-y-0.5\">\n\t\t\t\t\t\t\t\t\t\t<FormLabel>Is Authority</FormLabel>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Switch\n\t\t\t\t\t\t\t\t\t\t\tchecked={field.value}\n\t\t\t\t\t\t\t\t\t\t\tonCheckedChange={field.onChange}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"certificate\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Certificate</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Textarea\n\t\t\t\t\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"off\"\n\t\t\t\t\t\t\t\t\t\t\trows={5}\n\t\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"hosts\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Hosts (optional)</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormDescription>\n\t\t\t\t\t\t\t\t\t\tComma-separated list of hostnames this certificate is valid for.\n\t\t\t\t\t\t\t\t\t</FormDescription>\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"off\"\n\t\t\t\t\t\t\t\t\t\t\tplaceholder=\"e.g. example.com, *.example.com\"\n\t\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"uses\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Uses (optional)</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormDescription>\n\t\t\t\t\t\t\t\t\t\tComma-separated list of intended uses, e.g. \"https, operations, wss\".\n\t\t\t\t\t\t\t\t\t</FormDescription>\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"off\"\n\t\t\t\t\t\t\t\t\t\t\tplaceholder=\"e.g. https, operations, wss\"\n\t\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"private_key\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Private Key (optional)</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormDescription>\n\t\t\t\t\t\t\t\t\t\tPEM formatted private key string.\n\t\t\t\t\t\t\t\t\t</FormDescription>\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Textarea\n\t\t\t\t\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"off\"\n\t\t\t\t\t\t\t\t\t\t\trows={5}\n\t\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t<DialogFooter>\n\t\t\t\t\t\t\t<div className=\"flex justify-between w-full\">\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tvariant=\"destructiveOutline\"\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\t\t\tonClick={onClickCancel}\n\t\t\t\t\t\t\t\t\tdisabled={isPending}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\t\t\t\tvariant=\"submit\"\n\t\t\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\t\t\tdisabled={isPending || !form.formState.isDirty || !form.formState.isValid}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Save /> Add Certificate\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</DialogFooter>\n\t\t\t\t\t</form>\n\t\t\t\t</Form>\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n}\n","import { InstanceClientIdConfig } from '@/config/instanceClientConfig';\n\nexport async function removeCertificate({ instanceClient }: InstanceClientIdConfig, name: string) {\n\tconst { data } = await instanceClient.post<{ message: string }>('/', {\n\t\toperation: 'remove_certificate',\n\t\tname,\n\t});\n\treturn data;\n}\n","import { InstanceClientIdConfig } from '@/config/instanceClientConfig';\nimport { useMutation } from '@tanstack/react-query';\nimport { removeCertificate } from './removeCertificate';\n\nexport function useRemoveCertificate() {\n\treturn useMutation({\n\t\tmutationFn: ({ instanceParams, name }: { instanceParams: InstanceClientIdConfig; name: string }) =>\n\t\t\tremoveCertificate(instanceParams, name),\n\t});\n}\n","import { ConfirmDeletionModal } from '@/components/ConfirmDeletionModal';\nimport { Button } from '@/components/ui/button';\nimport {\n\tDialog,\n\tDialogContent,\n\tDialogDescription,\n\tDialogFooter,\n\tDialogHeader,\n\tDialogTitle,\n} from '@/components/ui/dialog';\nimport { Label } from '@/components/ui/label';\nimport { Textarea } from '@/components/ui/textarea';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { Certificate } from '@/integrations/api/instance/certificates/listCertificates';\nimport { useRemoveCertificate } from '@/integrations/api/instance/certificates/useRemoveCertificate';\nimport { Row } from '@tanstack/react-table';\nimport { useCallback, useState } from 'react';\nimport { toast } from 'sonner';\n\nexport function ViewCertificateModal({\n\tdata,\n\tisModalOpen,\n\tcloseModal,\n\tonSelectCertificate,\n\tonChangesSaved,\n}: {\n\tdata: Certificate;\n\tisModalOpen: boolean;\n\tcloseModal: () => void;\n\tonSelectCertificate: (row?: Row<Certificate>) => void;\n\tonChangesSaved: () => void;\n}) {\n\tconst { name } = data;\n\tconst instanceParams = useInstanceClientIdParams();\n\n\tconst { mutate: removeCertificate, isPending: isRemovePending } = useRemoveCertificate();\n\n\tconst [isConfirmRemoveModalOpen, setIsConfirmRemoveModalOpen] = useState(false);\n\n\tconst onCertificateRemoveClicked = useCallback(() => {\n\t\tsetIsConfirmRemoveModalOpen(true);\n\t}, []);\n\n\tconst onDeletionConfirmed = useCallback(() => {\n\t\tremoveCertificate(\n\t\t\t{\n\t\t\t\tinstanceParams,\n\t\t\t\tname,\n\t\t\t},\n\t\t\t{\n\t\t\t\tonSuccess: () => {\n\t\t\t\t\ttoast.success('Certificate removed successfully!');\n\t\t\t\t\tonSelectCertificate(undefined);\n\t\t\t\t\tonChangesSaved();\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t}, [name, removeCertificate, instanceParams, onChangesSaved, onSelectCertificate]);\n\n\treturn (\n\t\t<>\n\t\t\t<Dialog onOpenChange={closeModal} open={isModalOpen}>\n\t\t\t\t<DialogContent className=\"sm:max-w-[800px] max-h-[90vh] overflow-y-auto\" aria-describedby={undefined}>\n\t\t\t\t\t<div className=\"grid gap-4 my-4\">\n\t\t\t\t\t\t<DialogHeader>\n\t\t\t\t\t\t\t<DialogTitle>View Certificate: {name}</DialogTitle>\n\t\t\t\t\t\t\t<DialogDescription>\n\t\t\t\t\t\t\t\tDetails of the selected certificate.\n\t\t\t\t\t\t\t</DialogDescription>\n\t\t\t\t\t\t</DialogHeader>\n\n\t\t\t\t\t\t<div className=\"space-y-4\">\n\t\t\t\t\t\t\t<div className=\"grid grid-cols-2 gap-4 text-sm bg-muted p-4 rounded-lg border border-border\">\n\t\t\t\t\t\t\t\t<div className=\"col-span-2\">\n\t\t\t\t\t\t\t\t\t<p className=\"font-semibold\">Issuer</p>\n\t\t\t\t\t\t\t\t\t<p className=\"text-muted-foreground break-all\">{data.details.issuer || 'N/A'}</p>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div className=\"col-span-2\">\n\t\t\t\t\t\t\t\t\t<p className=\"font-semibold\">Subject</p>\n\t\t\t\t\t\t\t\t\t<p className=\"text-muted-foreground break-all\">{data.details.subject || 'N/A'}</p>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t{data.details.subject_alt_name && (\n\t\t\t\t\t\t\t\t\t<div className=\"col-span-2\">\n\t\t\t\t\t\t\t\t\t\t<p className=\"font-semibold\">Subject Alternative Name</p>\n\t\t\t\t\t\t\t\t\t\t<p className=\"text-muted-foreground break-all\">{data.details.subject_alt_name}</p>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t<p className=\"font-semibold\">Valid From</p>\n\t\t\t\t\t\t\t\t\t<p className=\"text-muted-foreground\">\n\t\t\t\t\t\t\t\t\t\t{data.details.valid_from ? new Date(data.details.valid_from).toLocaleString() : 'N/A'}\n\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t<p className=\"font-semibold\">Valid To (Expires At)</p>\n\t\t\t\t\t\t\t\t\t<p className=\"text-muted-foreground\">\n\t\t\t\t\t\t\t\t\t\t{data.details.valid_to ? new Date(data.details.valid_to).toLocaleString() : 'N/A'}\n\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t<p className=\"font-semibold\">Serial Number</p>\n\t\t\t\t\t\t\t\t\t<p className=\"text-muted-foreground font-mono text-xs break-all\">\n\t\t\t\t\t\t\t\t\t\t{data.details.serial_number || 'N/A'}\n\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t<p className=\"font-semibold\">Private Key Name</p>\n\t\t\t\t\t\t\t\t\t<p className=\"text-muted-foreground\">{data.private_key_name || 'N/A'}</p>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t<p className=\"font-semibold\">Is Authority</p>\n\t\t\t\t\t\t\t\t\t<p className=\"text-muted-foreground\">{data.is_authority ? 'Yes' : 'No'}</p>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t<p className=\"font-semibold\">Is Self-Signed</p>\n\t\t\t\t\t\t\t\t\t<p className=\"text-muted-foreground\">{data.is_self_signed ? 'Yes' : 'No'}</p>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t{data.hosts && data.hosts.length > 0 && (\n\t\t\t\t\t\t\t\t\t<div className=\"col-span-2\">\n\t\t\t\t\t\t\t\t\t\t<p className=\"font-semibold\">Hosts</p>\n\t\t\t\t\t\t\t\t\t\t<p className=\"text-muted-foreground\">{data.hosts.join(', ')}</p>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t<div className=\"col-span-2\">\n\t\t\t\t\t\t\t\t\t<p className=\"font-semibold\">Uses</p>\n\t\t\t\t\t\t\t\t\t<p className=\"text-muted-foreground\">{data.uses?.join(', ') || 'N/A'}</p>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t<div className=\"space-y-2\">\n\t\t\t\t\t\t\t\t<Label>Certificate Content</Label>\n\t\t\t\t\t\t\t\t<Textarea\n\t\t\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\t\t\tautoCapitalize=\"off\"\n\t\t\t\t\t\t\t\t\trows={8}\n\t\t\t\t\t\t\t\t\treadOnly={true}\n\t\t\t\t\t\t\t\t\tclassName=\"font-mono text-xs\"\n\t\t\t\t\t\t\t\t\tvalue={data.certificate}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<DialogFooter>\n\t\t\t\t\t\t\t<div className=\"flex justify-between w-full\">\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tvariant=\"destructiveOutline\"\n\t\t\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\t\t\tonClick={onCertificateRemoveClicked}\n\t\t\t\t\t\t\t\t\tdisabled={isRemovePending}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tRemove Certificate\n\t\t\t\t\t\t\t\t</Button>\n\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tvariant=\"defaultOutline\"\n\t\t\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\t\t\tonClick={() => closeModal()}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tClose\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</DialogFooter>\n\t\t\t\t\t</div>\n\t\t\t\t</DialogContent>\n\t\t\t</Dialog>\n\t\t\t<ConfirmDeletionModal\n\t\t\t\tisModalOpen={isConfirmRemoveModalOpen}\n\t\t\t\tsetIsModalOpen={setIsConfirmRemoveModalOpen}\n\t\t\t\tdeletionConfirmed={onDeletionConfirmed}\n\t\t\t\tdeletionPending={isRemovePending}\n\t\t\t\ttypeOfThingBeingDeleted=\"certificate\"\n\t\t\t\tpresentParticiple=\"Removing\"\n\t\t\t\ttransitiveVerb=\"Remove\"\n\t\t\t\tnameOfThingBeingDeleted={name}\n\t\t\t\thideDataLossWarning={true}\n\t\t\t/>\n\t\t</>\n\t);\n}\n","import { SimpleBrowseDataTable } from '@/components/SimpleBrowseDataTable';\nimport { Button } from '@/components/ui/button';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { useRefreshClick } from '@/hooks/useRefreshClick';\nimport { Certificate, listCertificatesQueryOptions } from '@/integrations/api/instance/certificates/listCertificates';\nimport { useQuery } from '@tanstack/react-query';\nimport { Link, useNavigate, useParams } from '@tanstack/react-router';\nimport { Row } from '@tanstack/react-table';\nimport { PlusIcon, RefreshCwIcon } from 'lucide-react';\nimport { useCallback, useMemo, useState } from 'react';\nimport { dataTableColumns } from './constants/tableDefinition';\nimport { AddCertificateModal } from './modals/AddCertificateModal';\nimport { ViewCertificateModal } from './modals/ViewCertificateModal';\n\nexport function ConfigCertificatesIndex() {\n\tconst navigate = useNavigate();\n\tconst { certName }: { certName?: string } = useParams({ strict: false });\n\tconst instanceParams = useInstanceClientIdParams();\n\tconst {\n\t\tdata: certificates,\n\t\trefetch,\n\t\tisFetching,\n\t\tisRefetching,\n\t} = useQuery(listCertificatesQueryOptions(instanceParams));\n\n\tconst selectedCertificate = useMemo(\n\t\t() => certificates?.find((cert) => cert.name === certName),\n\t\t[certificates, certName],\n\t);\n\n\tconst onSelectCertificate = useCallback(\n\t\t(row?: Row<Certificate>) => {\n\t\t\tconst newCertName = row?.original?.name;\n\t\t\tconst parts = [certName ? '..' : '', newCertName].filter(Boolean);\n\t\t\tvoid navigate({ to: parts.join('/') });\n\t\t},\n\t\t[certName, navigate],\n\t);\n\n\tconst isViewModalOpen = !!certName && !!selectedCertificate;\n\n\tconst [isAddModalOpen, setIsAddModalOpen] = useState(false);\n\n\tconst onAddClicked = useCallback(() => {\n\t\tsetIsAddModalOpen(true);\n\t}, [setIsAddModalOpen]);\n\n\tconst onRefreshClick = useRefreshClick(refetch);\n\n\treturn (\n\t\t<>\n\t\t\t<SimpleBrowseDataTable\n\t\t\t\tcolumns={dataTableColumns}\n\t\t\t\tdata={certificates || []}\n\t\t\t\tisFetching={isFetching}\n\t\t\t\tonRowClick={onSelectCertificate}\n\t\t\t>\n\t\t\t\t<Link\n\t\t\t\t\tclassName=\"inline-block underline text-sm text-muted-foreground hover:text-foreground\"\n\t\t\t\t\tto=\"https://docs.harperdb.io/docs/developers/operations-api/certificate-management\"\n\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t>\n\t\t\t\t\tCertificate Management Docs\n\t\t\t\t</Link>\n\t\t\t\t<Button variant=\"defaultOutline\" onClick={onRefreshClick} accessKey=\"r\" disabled={isFetching || isRefetching}>\n\t\t\t\t\t<RefreshCwIcon />\n\t\t\t\t\t<span className=\"hidden lg:inline-block\">\n\t\t\t\t\t\t<u>R</u>efresh\n\t\t\t\t\t</span>\n\t\t\t\t</Button>\n\t\t\t\t<Button variant=\"positiveOutline\" onClick={onAddClicked} accessKey=\"a\" disabled={isAddModalOpen}>\n\t\t\t\t\t<PlusIcon />\n\t\t\t\t\t<span>\n\t\t\t\t\t\t<u>A</u>dd\n\t\t\t\t\t</span>\n\t\t\t\t</Button>\n\t\t\t</SimpleBrowseDataTable>\n\t\t\t{isAddModalOpen && (\n\t\t\t\t<AddCertificateModal\n\t\t\t\t\tisModalOpen={isAddModalOpen}\n\t\t\t\t\tonChangesSaved={refetch}\n\t\t\t\t\tsetIsModalOpen={setIsAddModalOpen}\n\t\t\t\t/>\n\t\t\t)}\n\t\t\t{isViewModalOpen && (\n\t\t\t\t<ViewCertificateModal\n\t\t\t\t\tisModalOpen={isViewModalOpen}\n\t\t\t\t\tcloseModal={onSelectCertificate}\n\t\t\t\t\tdata={selectedCertificate}\n\t\t\t\t\tonSelectCertificate={onSelectCertificate}\n\t\t\t\t\tonChangesSaved={refetch}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</>\n\t);\n}\n","import { DomainsManagement } from '@/features/cluster/domains/Management';\n\nexport function ConfigDomainsIndex() {\n\treturn <DomainsManagement />;\n}\n","import { Loading } from '@/components/Loading';\nimport { isLocalStudio } from '@/config/constants';\nimport { getClusterInfoQueryOptions } from '@/features/cluster/queries/getClusterInfoQuery';\nimport { useInstanceManagePermission } from '@/hooks/usePermissions';\nimport { clusterIsSelfManaged } from '@/integrations/api/clusterIsSelfManaged';\nimport { RegistrationInfoResponse } from '@/integrations/api/instance/status/getRegistrationInfo';\nimport { wasAReleasedBeforeB } from '@/lib/string/wasAReleasedBeforeB';\nimport { buildAbsoluteLinkToPage } from '@/lib/urls/buildAbsoluteLinkToPage';\nimport { useQuery } from '@tanstack/react-query';\nimport { Link, Outlet, useLoaderData, useParams } from '@tanstack/react-router';\nimport { GlobeIcon, HandshakeIcon, KeyIcon, PieChartIcon, ShieldCheckIcon, UsersIcon } from 'lucide-react';\nimport { ReactNode, Suspense } from 'react';\n\nconst sharedClasses = 'flex items-center p-2 rounded-lg group';\nconst inactiveProps = { className: 'text-foreground hover:bg-accent dark:text-white dark:hover:bg-gray-700' };\nconst activeProps = { className: 'text-black bg-white pointer-events-none cursor-default' };\n\nexport function ConfigIndex() {\n\tconst params: {\n\t\tclusterId?: string;\n\t\tinstanceId?: string;\n\t\torganizationId?: string;\n\t} = useParams({ strict: false });\n\tconst { version }: RegistrationInfoResponse = useLoaderData({ strict: false });\n\tconst certsAvailable = wasAReleasedBeforeB('4.6.0', version);\n\n\tconst { clusterId } = params;\n\tconst canManage = useInstanceManagePermission();\n\tconst { data: cluster } = useQuery(\n\t\tgetClusterInfoQueryOptions(clusterId, false),\n\t);\n\tconst isSelfManaged = cluster === undefined || clusterIsSelfManaged(cluster);\n\n\tconst children = canManage && (\n\t\t<>\n\t\t\t<li>\n\t\t\t\t<Link\n\t\t\t\t\tto={buildAbsoluteLinkToPage(params, 'config/users')}\n\t\t\t\t\tclassName={sharedClasses}\n\t\t\t\t\tinactiveProps={inactiveProps}\n\t\t\t\t\tactiveProps={activeProps}\n\t\t\t\t>\n\t\t\t\t\t<UsersIcon className=\"hidden md:inline-block\" /> <span className=\"ms-3\">Users</span>\n\t\t\t\t</Link>\n\t\t\t</li>\n\t\t\t<li>\n\t\t\t\t<Link\n\t\t\t\t\tto={buildAbsoluteLinkToPage(params, 'config/roles')}\n\t\t\t\t\tclassName={sharedClasses}\n\t\t\t\t\tinactiveProps={inactiveProps}\n\t\t\t\t\tactiveProps={activeProps}\n\t\t\t\t>\n\t\t\t\t\t<HandshakeIcon className=\"hidden md:inline-block\" /> <span className=\"ms-3\">Roles</span>\n\t\t\t\t</Link>\n\t\t\t</li>\n\t\t\t{certsAvailable && (\n\t\t\t\t<li>\n\t\t\t\t\t<Link\n\t\t\t\t\t\tto={buildAbsoluteLinkToPage(params, 'config/certificates')}\n\t\t\t\t\t\tclassName={sharedClasses}\n\t\t\t\t\t\tinactiveProps={inactiveProps}\n\t\t\t\t\t\tactiveProps={activeProps}\n\t\t\t\t\t>\n\t\t\t\t\t\t<ShieldCheckIcon className=\"hidden md:inline-block\" /> <span className=\"ms-3\">Certificates</span>\n\t\t\t\t\t</Link>\n\t\t\t\t</li>\n\t\t\t)}\n\t\t\t{!isLocalStudio && !isSelfManaged && (\n\t\t\t\t<li>\n\t\t\t\t\t<Link\n\t\t\t\t\t\tto={buildAbsoluteLinkToPage(params, 'config/domains')}\n\t\t\t\t\t\tclassName={sharedClasses}\n\t\t\t\t\t\tinactiveProps={inactiveProps}\n\t\t\t\t\t\tactiveProps={activeProps}\n\t\t\t\t\t>\n\t\t\t\t\t\t<GlobeIcon className=\"hidden md:inline-block\" /> <span className=\"ms-3\">Domains</span>\n\t\t\t\t\t</Link>\n\t\t\t\t</li>\n\t\t\t)}\n\t\t\t{certsAvailable && (\n\t\t\t\t<li>\n\t\t\t\t\t<Link\n\t\t\t\t\t\tto={buildAbsoluteLinkToPage(params, 'config/ssh-keys')}\n\t\t\t\t\t\tclassName={sharedClasses}\n\t\t\t\t\t\tinactiveProps={inactiveProps}\n\t\t\t\t\t\tactiveProps={activeProps}\n\t\t\t\t\t>\n\t\t\t\t\t\t<KeyIcon className=\"hidden md:inline-block\" /> <span className=\"ms-3\">SSH Keys</span>\n\t\t\t\t\t</Link>\n\t\t\t\t</li>\n\t\t\t)}\n\t\t</>\n\t);\n\n\treturn (\n\t\t<div className=\"md:grid gap-4 md:grid-cols-12 min-h-[calc(100vh-(--spacing(36)))]\">\n\t\t\t<section className=\"col-span-1 text-foreground md:col-span-4 lg:col-span-3 md:border-r border-b md:border-b-0 md:pr-4 border-gray-700\">\n\t\t\t\t<DesktopConfigNavBar params={params}>{children}</DesktopConfigNavBar>\n\t\t\t\t<MobileConfigNavBar params={params}>{children}</MobileConfigNavBar>\n\t\t\t</section>\n\t\t\t<section className=\"col-span-1 text-foreground md:col-span-8 lg:col-span-9 md:pt-4\">\n\t\t\t\t<Suspense fallback={<Loading className=\"flex flex-col items-center justify-center h-full\" text=\"Loading...\" />}>\n\t\t\t\t\t<Outlet />\n\t\t\t\t</Suspense>\n\t\t\t</section>\n\t\t</div>\n\t);\n}\n\nfunction DesktopConfigNavBar({ params, children }: {\n\tparams: {\n\t\tclusterId?: string;\n\t\tinstanceId?: string;\n\t\torganizationId?: string;\n\t};\n\tchildren: ReactNode;\n}) {\n\treturn (\n\t\t<div className=\"hidden md:block pl-4 pt-4\">\n\t\t\t<Link\n\t\t\t\tto={buildAbsoluteLinkToPage(params, 'config')}\n\t\t\t\tclassName={sharedClasses}\n\t\t\t\tactiveOptions={{ exact: true }}\n\t\t\t\tinactiveProps={inactiveProps}\n\t\t\t\tactiveProps={activeProps}\n\t\t\t>\n\t\t\t\t<PieChartIcon className=\"hidden md:inline-block\" /> <span className=\"ms-3\">Overview</span>\n\t\t\t</Link>\n\n\t\t\t{children && (\n\t\t\t\t<ul className=\"border-t border-gray-700 pt-4 mt-4 space-y-2\">\n\t\t\t\t\t{children}\n\t\t\t\t</ul>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\nfunction MobileConfigNavBar({ params, children }: {\n\tparams: {\n\t\tclusterId?: string;\n\t\tinstanceId?: string;\n\t\torganizationId?: string;\n\t};\n\tchildren: ReactNode;\n}) {\n\treturn (\n\t\t<ul className=\"flex space-x-2 md:hidden py-2 px-4\">\n\t\t\t<li>\n\t\t\t\t<Link\n\t\t\t\t\tto={buildAbsoluteLinkToPage(params, 'config')}\n\t\t\t\t\tclassName={sharedClasses}\n\t\t\t\t\tactiveOptions={{ exact: true }}\n\t\t\t\t\tinactiveProps={inactiveProps}\n\t\t\t\t\tactiveProps={activeProps}\n\t\t\t\t>\n\t\t\t\t\t<PieChartIcon className=\"hidden md:inline-block\" /> <span className=\"ms-3\">Overview</span>\n\t\t\t\t</Link>\n\t\t\t</li>\n\t\t\t{children}\n\t\t</ul>\n\t);\n}\n","import { sleep } from '@/lib/sleep';\nimport { AxiosResponse } from 'axios';\n\nexport async function axiosRetry<T = unknown, R = AxiosResponse<T>>(\n\trequestPromise: () => Promise<R>,\n\tretries = 3,\n\tmsDelayBetweenAttempts = 1000,\n): Promise<R> {\n\tlet attempt = 0;\n\tif (retries <= 0) {\n\t\tthrow new Error('retries must be greater than 0');\n\t}\n\tlet lastError: unknown;\n\t// use for loop to retry 3 times at most\n\twhile (attempt < retries) {\n\t\ttry {\n\t\t\treturn await requestPromise();\n\t\t} catch (error) {\n\t\t\tattempt++;\n\t\t\tlastError = error;\n\t\t\tif (attempt === retries) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tawait sleep(msDelayBetweenAttempts);\n\t\t}\n\t}\n\tthrow lastError;\n}\n","import { InstanceClientConfig } from '@/config/instanceClientConfig';\nimport { getInstanceUserInfo } from '@/integrations/api/instance/status/getInstanceUserInfo';\nimport { ReplicatedResponse } from '@/integrations/api/replication';\nimport { axiosRetry } from '@/lib/axiosRetry';\nimport { sleep } from '@/lib/sleep';\nimport { useMutation } from '@tanstack/react-query';\n\ninterface RestartInstanceParams {\n\toperation: 'restart_service' | 'restart';\n\treplicated: boolean;\n}\n\nexport async function restartInstance(\n\t{ operation, replicated, instanceClient }: RestartInstanceParams & InstanceClientConfig,\n): Promise<ReplicatedResponse> {\n\tconst { data } = await instanceClient.post('/', {\n\t\toperation,\n\t\tservice: operation === 'restart_service' ? 'http' : undefined,\n\t\treplicated,\n\t});\n\tawait sleep(10_000);\n\tawait axiosRetry(() => getInstanceUserInfo({ instanceClient, timeout: 3_000 }), 12, 15_000);\n\treturn data;\n}\n\nexport function useRestartInstance() {\n\treturn useMutation({\n\t\tmutationFn: restartInstance,\n\t});\n}\n","import { ProgressBar } from '@/components/ProgressBar';\nimport { getInstanceClient } from '@/config/getInstanceClient';\nimport { authStore } from '@/features/auth/store/authStore';\nimport { getClusterInfo } from '@/features/cluster/queries/getClusterInfoQuery';\nimport { getInstanceUserInfo } from '@/integrations/api/instance/status/getInstanceUserInfo';\nimport { restartInstance } from '@/integrations/api/instance/status/restartInstance';\nimport { excludeFalsy } from '@/lib/arrays/excludeFalsy';\nimport { pluralize } from '@/lib/pluralize';\nimport { sleep } from '@/lib/sleep';\nimport { getOperationsUrlForInstance } from '@/lib/urls/getOperationsUrlForInstance';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { useParams } from '@tanstack/react-router';\nimport { useCallback, useState } from 'react';\nimport { toast } from 'sonner';\n\ninterface RestartClusterClickParams {\n\tonRestartedSuccessfully?: () => void;\n}\n\ninterface RestartClusterClickResponse {\n\tonRestartClick: () => void;\n\tisRestartPending: boolean;\n}\n\nexport function useRestartClusterClick(\n\t{ onRestartedSuccessfully }: RestartClusterClickParams = {},\n): RestartClusterClickResponse {\n\tconst { clusterId }: { clusterId?: string } = useParams({ strict: false });\n\tconst queryClient = useQueryClient();\n\tconst [isRestartPending, setIsRestartPending] = useState(false);\n\tconst onRestartClick = useCallback(async () => {\n\t\tif (!clusterId) {\n\t\t\tthrow new Error('clusterId must be set in the route to invoke useRestartClusterClick');\n\t\t}\n\t\tsetIsRestartPending(true);\n\n\t\tlet canceled = false;\n\t\tconst toastConfig = {\n\t\t\tduration: 60_000,\n\t\t\taction: {\n\t\t\t\tlabel: 'Cancel',\n\t\t\t\tonClick: () => {\n\t\t\t\t\tcanceled = true;\n\t\t\t\t},\n\t\t\t},\n\t\t};\n\n\t\tconst toastId = toast.loading('Restarting', {\n\t\t\t...toastConfig,\n\t\t\tdescription: (\n\t\t\t\t<ProgressBar\n\t\t\t\t\tanimated={true}\n\t\t\t\t\twidth=\"0%\"\n\t\t\t\t/>\n\t\t\t),\n\t\t});\n\n\t\tconst cluster = await getClusterInfo(clusterId);\n\t\tconst clusterUsesFabricConnect = authStore.checkForFabricConnect(cluster.id);\n\t\tconst allInstances = cluster?.instances ?? [];\n\t\tconst instanceClients = allInstances\n\t\t\t.filter(instance => instance.status === 'RUNNING')\n\t\t\t.map(instance =>\n\t\t\t\tgetInstanceClient({\n\t\t\t\t\tid: instance.id,\n\t\t\t\t\tforceFabricConnect: clusterUsesFabricConnect,\n\t\t\t\t\toperationsUrl: getOperationsUrlForInstance(instance),\n\t\t\t\t})\n\t\t\t)\n\t\t\t.reverse();\n\t\tlet instancesRestarted = 0;\n\n\t\tif (instanceClients.length) {\n\t\t\tfor (let i = 0; i < instanceClients.length; i++) {\n\t\t\t\tconst instanceClient = instanceClients[i];\n\t\t\t\tif (!canceled) {\n\t\t\t\t\ttoast.loading(`Restarting Instance ${i + 1} of ${instanceClients.length}`, {\n\t\t\t\t\t\t...toastConfig,\n\t\t\t\t\t\tid: toastId,\n\t\t\t\t\t\tdescription: (\n\t\t\t\t\t\t\t<ProgressBar\n\t\t\t\t\t\t\t\tanimated={true}\n\t\t\t\t\t\t\t\twidth={(i === 0 ? 0 : (i / instanceClients.length * 100)) + '%'}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t),\n\t\t\t\t\t});\n\t\t\t\t\ttry {\n\t\t\t\t\t\t// Make sure the instance is responding.\n\t\t\t\t\t\tawait getInstanceUserInfo({\n\t\t\t\t\t\t\tinstanceClient,\n\t\t\t\t\t\t});\n\t\t\t\t\t\t// Then restart it.\n\t\t\t\t\t\tawait restartInstance({\n\t\t\t\t\t\t\toperation: 'restart',\n\t\t\t\t\t\t\treplicated: false,\n\t\t\t\t\t\t\tinstanceClient,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tinstancesRestarted += 1;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tif (i + 1 !== instanceClients.length) {\n\t\t\t\t\t\t\t// If it fails to restart, or wasn't available, warn for a bit then move on.\n\t\t\t\t\t\t\ttoast.loading(`Failed Restarting Instance ${i + 1} of ${instanceClients.length}`, {\n\t\t\t\t\t\t\t\t...toastConfig,\n\t\t\t\t\t\t\t\tid: toastId,\n\t\t\t\t\t\t\t\tdescription: 'We will carry on momentarily.',\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tawait sleep(3000);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tsetIsRestartPending(false);\n\t\tvoid queryClient.invalidateQueries({ queryKey: [clusterId] });\n\n\t\tif (canceled) {\n\t\t\ttoast.error('Cancelled', {\n\t\t\t\tid: toastId,\n\t\t\t\tdescription: `The restart was partially cancelled.`,\n\t\t\t\tduration: 10_000,\n\t\t\t\taction: {\n\t\t\t\t\tlabel: 'Dismiss',\n\t\t\t\t\tonClick: () => toast.dismiss(),\n\t\t\t\t},\n\t\t\t});\n\t\t} else if (allInstances.length === instancesRestarted) {\n\t\t\tonRestartedSuccessfully?.();\n\t\t\ttoast.success('Success', {\n\t\t\t\tid: toastId,\n\t\t\t\tdescription: `Cluster fully restarted!`,\n\t\t\t\tduration: 10_000,\n\t\t\t\taction: {\n\t\t\t\t\tlabel: 'Dismiss',\n\t\t\t\t\tonClick: () => toast.dismiss(),\n\t\t\t\t},\n\t\t\t});\n\t\t} else {\n\t\t\tconst allTheInstances = pluralize(allInstances.length, 'instance', 'instances');\n\t\t\tconst someRunningInstancesWere = pluralize(\n\t\t\t\tinstancesRestarted,\n\t\t\t\t'\"RUNNING\" instance was',\n\t\t\t\t'\"RUNNING\" instances were',\n\t\t\t);\n\t\t\ttoast.error('Error', {\n\t\t\t\tid: toastId,\n\t\t\t\tdescription: `Failed to fully restart cluster.\\n`\n\t\t\t\t\t+ ([\n\t\t\t\t\t\tallInstances.length === 0 && 'No instances were found within the cluster to restart.',\n\t\t\t\t\t\tinstancesRestarted === 0 && `No instances were in a \"RUNNING\" state of ${allTheInstances}.`,\n\t\t\t\t\t\tallInstances.length !== instancesRestarted\n\t\t\t\t\t\t&& `Only ${someRunningInstancesWere} restarted of ${allTheInstances}.`,\n\t\t\t\t\t].filter(excludeFalsy).shift() || ''),\n\t\t\t\tduration: 10_000,\n\t\t\t\taction: {\n\t\t\t\t\tlabel: 'Dismiss',\n\t\t\t\t\tonClick: () => toast.dismiss(),\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t}, [clusterId, onRestartedSuccessfully, queryClient]);\n\n\treturn {\n\t\tonRestartClick,\n\t\tisRestartPending,\n\t};\n}\n","import { isLocalStudio } from '@/config/constants';\nimport { InstanceClientConfig } from '@/config/instanceClientConfig';\nimport { useRestartInstance } from '@/integrations/api/instance/status/restartInstance';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { useParams } from '@tanstack/react-router';\nimport { useCallback } from 'react';\nimport { toast } from 'sonner';\n\ninterface RestartInstanceClickParams extends InstanceClientConfig {\n\toperation: 'restart_service' | 'restart';\n\tonRestartedSuccessfully?: () => void;\n}\n\ninterface RestartInstanceClickResponse {\n\tonRestartClick: () => void;\n\tisRestartPending: boolean;\n}\n\nexport function useRestartInstanceClick({\n\toperation,\n\tinstanceClient,\n\tonRestartedSuccessfully,\n}: RestartInstanceClickParams): RestartInstanceClickResponse {\n\tconst { clusterId, instanceId }: { clusterId?: string; instanceId?: string } = useParams({ strict: false });\n\tconst targetNoun = (instanceId || isLocalStudio) ? 'Instance' : 'Cluster';\n\tconst { mutate: restartInstance, isPending: isRestartPending } = useRestartInstance();\n\tconst queryClient = useQueryClient();\n\tconst onRestartClick = useCallback(() => {\n\t\tconst toastId = toast.loading('Restarting', {\n\t\t\tdescription: `Restarting ${targetNoun.toLowerCase()}. This may take up to 60 seconds.`,\n\t\t\tduration: 180_000,\n\t\t\taction: {\n\t\t\t\tlabel: 'Dismiss',\n\t\t\t\tonClick: () => toast.dismiss(),\n\t\t\t},\n\t\t});\n\t\trestartInstance({\n\t\t\toperation,\n\t\t\treplicated: operation === 'restart_service' && targetNoun === 'Cluster',\n\t\t\tinstanceClient,\n\t\t}, {\n\t\t\tonSuccess: () => {\n\t\t\t\tvoid queryClient.invalidateQueries({ queryKey: [clusterId] });\n\t\t\t\tvoid queryClient.invalidateQueries({ queryKey: [instanceId] });\n\t\t\t\ttoast.dismiss(toastId);\n\t\t\t\ttoast.success('Success', {\n\t\t\t\t\tdescription: `${targetNoun} restarted!`,\n\t\t\t\t\taction: {\n\t\t\t\t\t\tlabel: 'Dismiss',\n\t\t\t\t\t\tonClick: () => toast.dismiss(),\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tonRestartedSuccessfully?.();\n\t\t\t},\n\t\t\tonError: () => {\n\t\t\t\ttoast.dismiss(toastId);\n\t\t\t\ttoast.error('Error', {\n\t\t\t\t\tdescription: `Failed to restart ${targetNoun.toLowerCase()}.`,\n\t\t\t\t\taction: {\n\t\t\t\t\t\tlabel: 'Dismiss',\n\t\t\t\t\t\tonClick: () => toast.dismiss(),\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t},\n\t\t});\n\t}, [\n\t\tclusterId,\n\t\tinstanceClient,\n\t\tinstanceId,\n\t\tonRestartedSuccessfully,\n\t\toperation,\n\t\tqueryClient,\n\t\trestartInstance,\n\t\ttargetNoun,\n\t]);\n\n\treturn {\n\t\tonRestartClick,\n\t\tisRestartPending,\n\t};\n}\n","import { Button } from '@/components/ui/button';\nimport { buttonVariants } from '@/components/ui/buttonVariants';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';\nimport { InstanceClientConfig } from '@/config/instanceClientConfig';\nimport { useRestartClusterClick } from '@/hooks/useRestartClusterClick';\nimport { useRestartInstanceClick } from '@/hooks/useRestartInstanceClick';\nimport { cx, VariantProps } from 'class-variance-authority';\nimport { RotateCcwIcon } from 'lucide-react';\n\ninterface RestartButtonParams extends InstanceClientConfig, VariantProps<typeof buttonVariants> {\n\tclassName?: string;\n\tdisabled?: boolean;\n\thideText?: boolean;\n\toperation: 'restart_service' | 'restart';\n\ttargetNoun: 'Instance' | 'Cluster';\n\ttooltip?: string;\n}\n\nexport function RestartButton({\n\tclassName,\n\tdisabled,\n\thideText,\n\tinstanceClient,\n\toperation,\n\ttargetNoun,\n\ttooltip,\n\tvariant,\n}: RestartButtonParams) {\n\tconst { onRestartClick: onRestartClusterClick, isRestartPending: isRestartClusterPending } = useRestartClusterClick();\n\tconst { onRestartClick, isRestartPending } = useRestartInstanceClick({ operation, instanceClient });\n\treturn (\n\t\t<Tooltip>\n\t\t\t<TooltipTrigger asChild>\n\t\t\t\t<Button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tvariant={variant || 'positiveOutline'}\n\t\t\t\t\tclassName={cx('mx-0 md:mx-4 rounded-full', className)}\n\t\t\t\t\tonClick={targetNoun === 'Cluster' && operation === 'restart' ? onRestartClusterClick : onRestartClick}\n\t\t\t\t\tdisabled={disabled || isRestartPending || isRestartClusterPending}\n\t\t\t\t\ttitle={`Restart ${targetNoun}`}\n\t\t\t\t>\n\t\t\t\t\t<RotateCcwIcon className=\"pointer-events-none\" />\n\t\t\t\t\t{hideText !== true && (\n\t\t\t\t\t\t<span className=\"hidden md:inline-block pointer-events-none\">\n\t\t\t\t\t\t\tRestart <span className=\"hidden 2xl:inline-block\">{targetNoun}</span>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t)}\n\t\t\t\t</Button>\n\t\t\t</TooltipTrigger>\n\t\t\t<TooltipContent side=\"bottom\">\n\t\t\t\t{tooltip\n\t\t\t\t\t? tooltip\n\t\t\t\t\t: operation === 'restart_service'\n\t\t\t\t\t? 'Restarts all service threads to apply changes. No downtime expected. Performance may be briefly slower during restart.'\n\t\t\t\t\t: 'This fully restarts the Harper service and causes downtime.'}\n\t\t\t</TooltipContent>\n\t\t</Tooltip>\n\t);\n}\n","import { cva } from 'class-variance-authority';\n\nexport const alertVariants = cva(\n\t'relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current',\n\t{\n\t\tvariants: {\n\t\t\tvariant: {\n\t\t\t\tdefault: 'bg-card text-card-foreground',\n\t\t\t\tdestructive:\n\t\t\t\t\t'text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90',\n\t\t\t\twarning:\n\t\t\t\t\t'border-amber-500/50 text-amber-600 dark:text-amber-400 bg-amber-50/50 dark:bg-amber-950/20 [&>svg]:text-amber-600 dark:[&>svg]:text-amber-400',\n\t\t\t},\n\t\t},\n\t\tdefaultVariants: {\n\t\t\tvariant: 'default',\n\t\t},\n\t},\n);\n","import { alertVariants } from '@/components/ui/alertVariants';\nimport { cn } from '@/lib/cn';\nimport { VariantProps } from 'class-variance-authority';\nimport * as React from 'react';\n\nexport function Alert({\n\tclassName,\n\tvariant,\n\t...props\n}: React.ComponentProps<'div'> & VariantProps<typeof alertVariants>) {\n\treturn (\n\t\t<div\n\t\t\tdata-slot=\"alert\"\n\t\t\trole=\"alert\"\n\t\t\tclassName={cn(alertVariants({ variant }), className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport function AlertTitle({ className, ...props }: React.ComponentProps<'div'>) {\n\treturn (\n\t\t<div\n\t\t\tdata-slot=\"alert-title\"\n\t\t\tclassName={cn(\n\t\t\t\t'col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport function AlertDescription({\n\tclassName,\n\t...props\n}: React.ComponentProps<'div'>) {\n\treturn (\n\t\t<div\n\t\t\tdata-slot=\"alert-description\"\n\t\t\tclassName={cn(\n\t\t\t\t'text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n","import { isLocalStudio } from '@/config/constants';\nimport { queryOptions } from '@tanstack/react-query';\nimport { getClusterInfo } from './getClusterInfoQuery';\n\ninterface GetInstanceInfoParams {\n\tclusterId?: string;\n\tinstanceId?: string;\n}\n\nasync function getInstanceInfo({ clusterId, instanceId }: GetInstanceInfoParams) {\n\tif (isLocalStudio) {\n\t\treturn null;\n\t}\n\tif (!clusterId) {\n\t\tthrow new Error('clusterId is required when outside of local mode and calling getInstanceInfo');\n\t}\n\tconst cluster = await getClusterInfo(clusterId);\n\tif (!cluster) {\n\t\treturn null;\n\t}\n\tconst instance = cluster.instances?.find(instance => instanceId === undefined || instance.id === instanceId);\n\tif (!instance) {\n\t\treturn null;\n\t}\n\treturn { cluster, instance };\n}\n\nexport function getInstanceInfoQueryOptions(params: GetInstanceInfoParams) {\n\treturn queryOptions({\n\t\tqueryKey: [params.clusterId, params.instanceId] as const,\n\t\tqueryFn: () => getInstanceInfo(params),\n\t\tretry: false,\n\t});\n}\n","import { TextLoadingSkeleton } from '@/components/TextLoadingSkeleton';\nimport { RegistrationInfoResponse } from '@/integrations/api/instance/status/getRegistrationInfo';\n\nexport const HarperVersion = ({\n\tloadingRegistration,\n\tregistrationInfo,\n}: {\n\tloadingRegistration?: boolean;\n\tregistrationInfo?: RegistrationInfoResponse;\n}) => {\n\tconst link = !!registrationInfo?.version\n\t\t&& parseInt(registrationInfo.version[0], 10) >= 5\n\t\t&& `https://github.com/HarperFast/harper/releases/tag/v${registrationInfo.version}`;\n\treturn (\n\t\t<>\n\t\t\t<dt className=\"font-bold text-sm/6\">Harper Version</dt>\n\t\t\t<dd className=\"text-sm/6 sm:mt-2\">\n\t\t\t\t{loadingRegistration\n\t\t\t\t\t? <TextLoadingSkeleton className=\"w-10\" />\n\t\t\t\t\t: link\n\t\t\t\t\t? (\n\t\t\t\t\t\t<a href={link} target=\"_blank\" className=\"underline hover:text-blue-300\" rel=\"noopener noreferrer\">\n\t\t\t\t\t\t\t{registrationInfo.version}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t)\n\t\t\t\t\t: registrationInfo?.version || 'Unknown'}\n\t\t\t</dd>\n\t\t</>\n\t);\n};\n","import { TextLoadingSkeleton } from '@/components/TextLoadingSkeleton';\n\nexport const LastDeployedTimestamp = ({\n\tloading,\n\ttimestamp,\n}: {\n\tloading?: boolean;\n\ttimestamp?: number | null;\n}) => {\n\tconst dateString = timestamp ? new Date(timestamp).toLocaleString() : 'Never';\n\treturn (\n\t\t<>\n\t\t\t<dt className=\"font-bold text-sm/6\">Last Deployed</dt>\n\t\t\t<dd className=\"text-sm/6 sm:mt-2\">\n\t\t\t\t{loading ? <TextLoadingSkeleton className=\"w-24\" /> : dateString}\n\t\t\t</dd>\n\t\t</>\n\t);\n};\n","import { InstanceClientConfig } from '@/config/instanceClientConfig';\nimport { ReplicatedResponse } from '@/integrations/api/replication';\n\ninterface SetConfigurationParams extends InstanceClientConfig {\n\t[key: string]: unknown;\n}\n\nexport async function setConfiguration({\n\tinstanceClient,\n\t...changes\n}: SetConfigurationParams): Promise<ReplicatedResponse> {\n\tconst { data } = await instanceClient.post('/', {\n\t\toperation: 'set_configuration',\n\t\t...changes,\n\t});\n\treturn data;\n}\n","import { ProgressBar } from '@/components/ProgressBar';\nimport { getInstanceClient } from '@/config/getInstanceClient';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { authStore } from '@/features/auth/store/authStore';\nimport { getClusterInfo } from '@/features/cluster/queries/getClusterInfoQuery';\nimport { Instance } from '@/integrations/api/api.patch';\nimport { getInstanceUserInfo } from '@/integrations/api/instance/status/getInstanceUserInfo';\nimport { restartInstance } from '@/integrations/api/instance/status/restartInstance';\nimport { setConfiguration } from '@/integrations/api/instance/status/setConfiguration';\nimport { excludeFalsy } from '@/lib/arrays/excludeFalsy';\nimport { pluralize } from '@/lib/pluralize';\nimport { sleep } from '@/lib/sleep';\nimport { getOperationsUrlForInstance } from '@/lib/urls/getOperationsUrlForInstance';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { useCallback, useState } from 'react';\nimport { toast } from 'sonner';\n\ninterface RollingConfigUpdateParams {\n\tonRestartedSuccessfully?: () => void;\n}\n\ninterface RollingConfigUpdateResponse {\n\tonConfigUpdate: (params: Record<string, unknown>) => void;\n\tisPending: boolean;\n}\n\nexport function useRollingConfigUpdate(\n\t{ onRestartedSuccessfully }: RollingConfigUpdateParams = {},\n): RollingConfigUpdateResponse {\n\tconst operationsParams = useInstanceClientIdParams();\n\tconst queryClient = useQueryClient();\n\tconst [isPending, setIsPending] = useState(false);\n\tconst onConfigUpdate = useCallback(async (params: Record<string, unknown>) => {\n\t\tsetIsPending(true);\n\n\t\tlet canceled = false;\n\t\tconst toastConfig = {\n\t\t\tduration: 60_000,\n\t\t\taction: {\n\t\t\t\tlabel: 'Cancel',\n\t\t\t\tonClick: () => {\n\t\t\t\t\tcanceled = true;\n\t\t\t\t},\n\t\t\t},\n\t\t};\n\n\t\tconst toastId = toast.loading('Restarting', {\n\t\t\t...toastConfig,\n\t\t\tdescription: (\n\t\t\t\t<ProgressBar\n\t\t\t\t\tanimated={true}\n\t\t\t\t\twidth=\"0%\"\n\t\t\t\t/>\n\t\t\t),\n\t\t});\n\n\t\tconst cluster = operationsParams.entityType === 'cluster'\n\t\t\t? await getClusterInfo(operationsParams.entityId)\n\t\t\t: null;\n\t\tconst allInstances = operationsParams.entityType === 'cluster'\n\t\t\t? cluster?.instances || []\n\t\t\t: [{ id: operationsParams.entityId, status: 'RUNNING' } as Instance];\n\t\tconst clusterUsesFabricConnect = !!cluster && authStore.checkForFabricConnect(cluster.id);\n\t\tconst instanceClients = operationsParams.entityType === 'cluster'\n\t\t\t? allInstances\n\t\t\t\t.filter(instance => instance.status === 'RUNNING')\n\t\t\t\t.map(instance =>\n\t\t\t\t\tgetInstanceClient({\n\t\t\t\t\t\tid: instance.id,\n\t\t\t\t\t\tforceFabricConnect: clusterUsesFabricConnect,\n\t\t\t\t\t\toperationsUrl: getOperationsUrlForInstance(instance),\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t\t.reverse()\n\t\t\t: [operationsParams.instanceClient];\n\t\tlet instancesRestarted = 0;\n\n\t\tif (instanceClients.length) {\n\t\t\tfor (let i = 0; i < instanceClients.length; i++) {\n\t\t\t\tconst instanceClient = instanceClients[i];\n\t\t\t\tif (!canceled) {\n\t\t\t\t\ttoast.loading(`Updating Instance ${i + 1} of ${instanceClients.length}`, {\n\t\t\t\t\t\t...toastConfig,\n\t\t\t\t\t\tid: toastId,\n\t\t\t\t\t\tdescription: (\n\t\t\t\t\t\t\t<ProgressBar\n\t\t\t\t\t\t\t\tanimated={true}\n\t\t\t\t\t\t\t\twidth={(i === 0 ? 0 : (i / instanceClients.length * 100)) + '%'}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t),\n\t\t\t\t\t});\n\t\t\t\t\ttry {\n\t\t\t\t\t\t// Make sure the instance is responding.\n\t\t\t\t\t\tawait getInstanceUserInfo({\n\t\t\t\t\t\t\tinstanceClient,\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tawait setConfiguration({\n\t\t\t\t\t\t\t...params,\n\t\t\t\t\t\t\tinstanceClient,\n\t\t\t\t\t\t});\n\t\t\t\t\t\t// Then restart it.\n\t\t\t\t\t\tawait restartInstance({\n\t\t\t\t\t\t\toperation: 'restart_service',\n\t\t\t\t\t\t\treplicated: false,\n\t\t\t\t\t\t\tinstanceClient,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tinstancesRestarted += 1;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tif (i + 1 !== instanceClients.length) {\n\t\t\t\t\t\t\t// If it fails to restart, or wasn't available, warn for a bit then move on.\n\t\t\t\t\t\t\ttoast.loading(`Failed Restarting Instance ${i + 1} of ${instanceClients.length}`, {\n\t\t\t\t\t\t\t\t...toastConfig,\n\t\t\t\t\t\t\t\tid: toastId,\n\t\t\t\t\t\t\t\tdescription: 'We will carry on momentarily.',\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tawait sleep(3000);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tsetIsPending(false);\n\t\tvoid queryClient.invalidateQueries({ queryKey: [operationsParams.entityId, 'get_configuration'] });\n\n\t\tif (canceled) {\n\t\t\ttoast.error('Cancelled', {\n\t\t\t\tid: toastId,\n\t\t\t\tdescription: `The config update was partially cancelled.`,\n\t\t\t\tduration: 10_000,\n\t\t\t\taction: {\n\t\t\t\t\tlabel: 'Dismiss',\n\t\t\t\t\tonClick: () => toast.dismiss(),\n\t\t\t\t},\n\t\t\t});\n\t\t} else if (allInstances.length === instancesRestarted) {\n\t\t\tonRestartedSuccessfully?.();\n\t\t\ttoast.success('Success', {\n\t\t\t\tid: toastId,\n\t\t\t\tdescription: `Your configuration has been updated successfully!`,\n\t\t\t\tduration: 10_000,\n\t\t\t\taction: {\n\t\t\t\t\tlabel: 'Dismiss',\n\t\t\t\t\tonClick: () => toast.dismiss(),\n\t\t\t\t},\n\t\t\t});\n\t\t} else {\n\t\t\tconst allTheInstances = pluralize(allInstances.length, 'instance', 'instances');\n\t\t\tconst someRunningInstancesWere = pluralize(\n\t\t\t\tinstancesRestarted,\n\t\t\t\t'\"RUNNING\" instance was',\n\t\t\t\t'\"RUNNING\" instances were',\n\t\t\t);\n\t\t\ttoast.error('Error', {\n\t\t\t\tid: toastId,\n\t\t\t\tdescription: `Failed to fully update cluster.\\n`\n\t\t\t\t\t+ ([\n\t\t\t\t\t\tallInstances.length === 0 && 'No instances were found within the cluster to restart.',\n\t\t\t\t\t\tinstancesRestarted === 0 && `No instances were in a \"RUNNING\" state of ${allTheInstances}.`,\n\t\t\t\t\t\tallInstances.length !== instancesRestarted\n\t\t\t\t\t\t&& `Only ${someRunningInstancesWere} restarted of ${allTheInstances}.`,\n\t\t\t\t\t].filter(excludeFalsy).shift() || ''),\n\t\t\t\tduration: 10_000,\n\t\t\t\taction: {\n\t\t\t\t\tlabel: 'Dismiss',\n\t\t\t\t\tonClick: () => toast.dismiss(),\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t}, [operationsParams, onRestartedSuccessfully, queryClient]);\n\n\treturn {\n\t\tonConfigUpdate,\n\t\tisPending,\n\t};\n}\n","import { InstanceClientIdConfig } from '@/config/instanceClientConfig';\nimport { queryOptions } from '@tanstack/react-query';\n\nexport interface APIDirectoryEntry extends APIFileEntry {\n\tentries: Array<APIDirectoryEntry | APIFileEntry>;\n\tpackage?: string;\n}\n\nexport interface APIFileEntry {\n\tname: string;\n\tmtime?: number;\n}\n\nexport async function getComponents({ instanceClient }: InstanceClientIdConfig) {\n\tconst { data }: { data: APIDirectoryEntry } = await instanceClient.post('/', {\n\t\toperation: 'get_components',\n\t});\n\treturn data;\n}\n\nexport function getComponentsQueryOptions(params: InstanceClientIdConfig & { enabled?: boolean }) {\n\treturn queryOptions({\n\t\tqueryKey: [params.entityId, 'get_components'] as const,\n\t\tqueryFn: () => getComponents(params),\n\t\tretry: false,\n\t\tenabled: params.enabled !== false,\n\t});\n}\n","import { InstanceClientIdConfig } from '@/config/instanceClientConfig';\nimport { queryOptions } from '@tanstack/react-query';\n\ninterface ConfigurationInfoResponse {\n\tlicense_expiration_date: string;\n\tram_allocation: number;\n\tregistered: boolean;\n\tversion: string;\n\thttp: {\n\t\tport: number | null;\n\t\tsecurePort: number | null;\n\t\tcors: boolean;\n\t\tcorsAccessList: string[];\n\t};\n}\n\nexport function getConfigurationQueryOptions({ entityId, instanceClient }: InstanceClientIdConfig) {\n\treturn queryOptions({\n\t\tqueryKey: [entityId, 'get_configuration'] as const,\n\t\tqueryFn: async () => {\n\t\t\tconst { data } = await instanceClient.post('/', {\n\t\t\t\toperation: 'get_configuration',\n\t\t\t});\n\t\t\treturn data as ConfigurationInfoResponse;\n\t\t},\n\t});\n}\n","import { InstanceClientIdConfig } from '@/config/instanceClientConfig';\nimport { queryOptions } from '@tanstack/react-query';\n\nexport interface RegistrationInfoResponse {\n\tversion: string;\n}\n\nexport function getRegistrationInfoQueryOptions({ entityId, instanceClient }: InstanceClientIdConfig) {\n\treturn queryOptions({\n\t\tqueryKey: [entityId, 'registration_info'] as const,\n\t\tstaleTime: 60_000,\n\t\tgcTime: 5_000,\n\t\tqueryFn: async () => {\n\t\t\tconst { data } = await instanceClient.post('/', {\n\t\t\t\toperation: 'registration_info',\n\t\t\t});\n\t\t\treturn data as RegistrationInfoResponse;\n\t\t},\n\t});\n}\n","import { InstanceClientIdConfig } from '@/config/instanceClientConfig';\nimport { queryOptions } from '@tanstack/react-query';\n\ninterface UsageLicense {\n\tid: string;\n\tlevel: string;\n\tregion: string;\n\treads: string;\n\twrites: string;\n\treadBytes: string;\n\twriteBytes: string;\n\trealTimeMessages: string;\n\trealTimeBytes: string;\n\tcpuTime: string;\n\tstorage: string;\n\tusedReads: string;\n\tusedWrites: string;\n\tusedReadBytes: string;\n\tusedWriteBytes: string;\n\tusedRealTimeMessages: string;\n\tusedRealTimeBytes: string;\n\tusedCpuTime: string;\n\tusedStorage: string;\n\texpiration: string;\n\tautoRenew: string;\n\t__createdtime__: string;\n\t__updatedtime__: string;\n}\n\nexport function getUsageLicensesQueryOptions({ entityId, instanceClient }: InstanceClientIdConfig, enabled: boolean) {\n\treturn queryOptions({\n\t\tqueryKey: [entityId, 'get_usage_licenses'] as const,\n\t\tenabled,\n\t\tqueryFn: async () => {\n\t\t\ttry {\n\t\t\t\tconst { data } = await instanceClient.post<UsageLicense[]>('/', {\n\t\t\t\t\toperation: 'get_usage_licenses',\n\t\t\t\t});\n\t\t\t\treturn data;\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(err);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t},\n\t});\n}\n","export const RESTRICTED_CONFIG: Record<string, any> = {\n\thttp: {\n\t\tport: 'blocked',\n\t\tsecurePort: 'blocked',\n\t},\n\tthreads: 'blocked',\n\tauthentication: {\n\t\tenableSessions: 'blocked',\n\t},\n\tlogging: {\n\t\tauditLog: 'blocked',\n\t\troot: 'blocked',\n\t\trotation: {\n\t\t\tpath: 'blocked',\n\t\t},\n\t},\n\tmqtt: {\n\t\tnetwork: {\n\t\t\tport: 'blocked',\n\t\t\tsecurePort: 'blocked',\n\t\t},\n\t},\n\toperationsApi: {\n\t\tnetwork: {\n\t\t\tdomainSocket: 'blocked',\n\t\t\tport: 'blocked',\n\t\t\tsecurePort: 'blocked',\n\t\t},\n\t},\n\trootPath: 'blocked',\n\treplication: 'blocked_except_databases',\n\tstorage: 'blocked',\n\ttls: 'blocked',\n\tnode: 'blocked',\n\tlicense: 'blocked',\n\tcomponentsRoot: 'blocked',\n\tanalytics: 'allowed',\n\tapplications: 'allowed',\n\tlocalStudio: 'allowed',\n};\n\nexport function isRestrictedConfigPath(path: string, value: any, originalValue: any): boolean {\n\t// If value hasn't changed, it's not \"blocked\" from staying the same\n\tif (JSON.stringify(value) === JSON.stringify(originalValue)) {\n\t\treturn false;\n\t}\n\n\tconst parts = path.split('.');\n\tlet current: any = RESTRICTED_CONFIG;\n\n\tfor (let i = 0; i < parts.length; i++) {\n\t\tconst part = parts[i];\n\t\tif (current === 'blocked') { return true; }\n\t\tif (current === 'blocked_except_databases') {\n\t\t\treturn part !== 'databases';\n\t\t}\n\t\tif (typeof current === 'object' && current !== null && part in current) {\n\t\t\tcurrent = current[part];\n\t\t} else {\n\t\t\t// Not in RESTRICTED_CONFIG, so it's allowed\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn current === 'blocked';\n}\n\nexport function omitRestrictedFields(obj: any, schema: any = RESTRICTED_CONFIG): any {\n\tif (typeof obj !== 'object' || obj === null) { return obj; }\n\n\tconst result = Array.isArray(obj) ? [] : {};\n\n\tfor (const key in obj) {\n\t\tconst value = obj[key];\n\t\tconst restriction = schema?.[key];\n\n\t\tif (restriction === 'blocked') {\n\t\t\tcontinue;\n\t\t} else if (restriction === 'blocked_except_databases') {\n\t\t\tif (value && typeof value === 'object' && 'databases' in value) {\n\t\t\t\t(result as any).replication = { databases: value.databases };\n\t\t\t}\n\t\t\tcontinue;\n\t\t} else if (typeof restriction === 'object' && restriction !== null) {\n\t\t\tconst sanitized = omitRestrictedFields(value, restriction);\n\t\t\tif (sanitized !== undefined && (typeof sanitized !== 'object' || Object.keys(sanitized).length > 0)) {\n\t\t\t\t(result as any)[key] = sanitized;\n\t\t\t}\n\t\t} else {\n\t\t\t(result as any)[key] = value;\n\t\t}\n\t}\n\n\treturn result;\n}\n\nexport function getChangedFields(original: any, edited: any): any {\n\tif (typeof original !== 'object' || original === null || typeof edited !== 'object' || edited === null) {\n\t\treturn JSON.stringify(original) !== JSON.stringify(edited) ? edited : undefined;\n\t}\n\n\tconst changes: any = {};\n\tconst allKeys = new Set([...Object.keys(original), ...Object.keys(edited)]);\n\n\tfor (const key of allKeys) {\n\t\tconst val1 = original[key];\n\t\tconst val2 = edited[key];\n\n\t\tif (\n\t\t\tval1 !== null && typeof val1 === 'object' && val2 !== null && typeof val2 === 'object' && !Array.isArray(val1)\n\t\t\t&& !Array.isArray(val2)\n\t\t) {\n\t\t\tconst nestedChanges = getChangedFields(val1, val2);\n\t\t\tif (Object.keys(nestedChanges).length > 0) {\n\t\t\t\tchanges[key] = nestedChanges;\n\t\t\t}\n\t\t} else if (JSON.stringify(val1) !== JSON.stringify(val2)) {\n\t\t\tchanges[key] = val2;\n\t\t}\n\t}\n\n\treturn changes;\n}\n\nexport function flattenConfig(obj: any, prefix = ''): Record<string, any> {\n\tconst result: Record<string, any> = {};\n\n\tfor (const key in obj) {\n\t\tconst value = obj[key];\n\t\tconst newKey = prefix ? `${prefix}_${key}` : key;\n\n\t\tif (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n\t\t\tObject.assign(result, flattenConfig(value, newKey));\n\t\t} else {\n\t\t\tresult[newKey] = value;\n\t\t}\n\t}\n\n\treturn result;\n}\n","/**\n * Harper-aware JSON support for the instance configuration editor. Registers\n * Harper's config-root JSON Schema with Monaco's JSON worker so the editor\n * gets validation, key autocomplete, and hover documentation for the instance\n * configuration — the JSON analog of the Harper-aware GraphQL support in the\n * Applications editor.\n *\n * The schema is scoped (via `fileMatch`) to the config editor's model URI only,\n * so the other JSON editors in the app (table rows, role permissions) are left\n * untouched by this global registration.\n *\n * Source of truth: node_modules/harper/config-root.schema.json, copied to\n * ./configRootSchema.json. The `harper` package only exposes `.` via its\n * exports map, so we can't import the schema file directly; refresh the copy\n * when the bundled harper version changes its config schema.\n */\nimport { OnMount } from '@monaco-editor/react';\nimport configRootSchemaRaw from './configRootSchema.json?raw';\n\ntype Monaco = Parameters<OnMount>[1];\n\nconst configRootSchema = JSON.parse(configRootSchemaRaw);\n\n/**\n * Model path (URI) for the config editor. Pass this as the `<Editor path>` prop\n * so the schema below matches it. Must stay in sync with the `fileMatch` entry.\n */\nexport const HARPER_CONFIG_MODEL_PATH = 'inmemory://harper/config-root.json';\n\nconst SCHEMA_URI = 'harper://schemas/config-root.json';\n\n/**\n * Idempotently register the Harper config schema with the (singleton) Monaco\n * JSON worker. Call this from the editor's `onMount` (not `beforeMount`):\n * Monaco's JSON language initializes lazily and resets its diagnostics options\n * the first time it loads, which clobbers a schema set too early in\n * `beforeMount`. By `onMount` the JSON language is initialized, so the\n * registration sticks. The guard keys off the already-registered schema URI,\n * so repeated mounts (and HMR) are no-ops.\n */\nexport function configureHarperConfigEditor(monaco: Monaco): void {\n\tconst jsonDefaults = monaco.languages.json.jsonDefaults;\n\tconst { schemas = [], ...rest } = jsonDefaults.diagnosticsOptions;\n\n\tif (schemas.some(schema => schema.uri === SCHEMA_URI)) {\n\t\treturn;\n\t}\n\n\tjsonDefaults.setDiagnosticsOptions({\n\t\t...rest,\n\t\tvalidate: true,\n\t\tenableSchemaRequest: false,\n\t\tschemas: [\n\t\t\t...schemas,\n\t\t\t{ uri: SCHEMA_URI, fileMatch: [HARPER_CONFIG_MODEL_PATH], schema: configRootSchema },\n\t\t],\n\t});\n}\n","import { ApplyLicensesButton } from '@/components/ApplyLicensesButton';\nimport { RestartButton } from '@/components/RestartButton';\nimport { TextLoadingSkeleton } from '@/components/TextLoadingSkeleton';\nimport { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';\nimport { Button } from '@/components/ui/button';\nimport { isLocalStudio } from '@/config/constants';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { getInstanceInfoQueryOptions } from '@/features/cluster/queries/getInstanceInfoQuery';\nimport { ApplicationURL } from '@/features/instance/config/overview/components/ApplicationURL';\nimport { ClusterDomainsList } from '@/features/instance/config/overview/components/ClusterDomainsList';\nimport { HarperVersion } from '@/features/instance/config/overview/components/HarperVersion';\nimport { InstanceNodeName } from '@/features/instance/config/overview/components/InstanceNodeName';\nimport { InstanceURL } from '@/features/instance/config/overview/components/InstanceURL';\nimport { LastDeployedTimestamp } from '@/features/instance/config/overview/components/LastDeployedTimestamp';\nimport { useMonacoTheme } from '@/hooks/useMonacoTheme';\nimport { useInstanceManagePermission } from '@/hooks/usePermissions';\nimport { useRollingConfigUpdate } from '@/hooks/useRollingConfigUpdate';\nimport {\n\tAPIDirectoryEntry,\n\tAPIFileEntry,\n\tgetComponentsQueryOptions,\n} from '@/integrations/api/instance/applications/getComponents';\nimport { getConfigurationQueryOptions } from '@/integrations/api/instance/status/getConfiguration';\nimport {\n\tgetRegistrationInfoQueryOptions,\n\tRegistrationInfoResponse,\n} from '@/integrations/api/instance/status/getRegistrationInfo';\nimport { getUsageLicensesQueryOptions } from '@/integrations/api/instance/status/getUsageLicenses';\nimport { keyBy } from '@/lib/keyBy';\nimport { Editor } from '@/lib/monaco/MonacoEditor';\nimport { wasAReleasedBeforeB } from '@/lib/string/wasAReleasedBeforeB';\nimport type { OnMount } from '@monaco-editor/react';\nimport { useQuery } from '@tanstack/react-query';\nimport { useLoaderData, useParams } from '@tanstack/react-router';\nimport { AlertCircleIcon, EditIcon, SaveIcon, XIcon } from 'lucide-react';\nimport { ReactNode, useCallback, useEffect, useMemo, useState } from 'react';\nimport { flattenConfig, getChangedFields, isRestrictedConfigPath, omitRestrictedFields } from './configRestrictions';\nimport { configureHarperConfigEditor, HARPER_CONFIG_MODEL_PATH } from './harper-config/configMonaco';\n\nconst LocalStudioOverview = ({ children }: { children: ReactNode }) => {\n\treturn <>{children}</>;\n};\n\nconst CloudStudioOverview = ({ children }: { children: ReactNode }) => {\n\treturn <>{children}</>;\n};\n\nexport function ConfigOverviewIndex() {\n\tconst { clusterId, instanceId }: { instanceId?: string; clusterId?: string } = useParams({ strict: false });\n\tconst { data: info, isLoading: loadingInstanceInfo } = useQuery(\n\t\tgetInstanceInfoQueryOptions({ clusterId, instanceId }),\n\t);\n\tconst targetNoun = (instanceId || isLocalStudio) ? 'Instance' : 'Cluster';\n\tconst instanceParams = useInstanceClientIdParams();\n\n\tconst { version }: RegistrationInfoResponse = useLoaderData({ strict: false });\n\tconst checkUsageLicenses = !isLocalStudio && wasAReleasedBeforeB('4.7.0-alpha.1', version);\n\n\tconst { data: appliedLicenses } = useQuery(\n\t\tgetUsageLicensesQueryOptions(instanceParams, checkUsageLicenses),\n\t);\n\tconst clusterInfo = info?.cluster;\n\tconst instanceInfo = info?.instance;\n\tconst { data: registrationInfo, isLoading: loadingRegistration } = useQuery(\n\t\tgetRegistrationInfoQueryOptions(instanceParams),\n\t);\n\tconst { data: configurationInfo, isLoading: loadingConfig } = useQuery(\n\t\tgetConfigurationQueryOptions(instanceParams),\n\t);\n\tconst canManage = useInstanceManagePermission();\n\tconst { data: components, isLoading: loadingComponents } = useQuery(\n\t\tgetComponentsQueryOptions({ ...instanceParams, enabled: canManage }),\n\t);\n\n\tconst lastDeployedTimestamp = useMemo(() => {\n\t\tif (!components) { return null; }\n\n\t\tlet maxMtime = 0;\n\t\tconst traverse = (entry: APIDirectoryEntry | APIFileEntry) => {\n\t\t\tif (entry.mtime) {\n\t\t\t\tmaxMtime = Math.max(maxMtime, new Date(entry.mtime).getTime());\n\t\t\t}\n\t\t\tif ('entries' in entry && entry.entries) {\n\t\t\t\tentry.entries.forEach(traverse);\n\t\t\t}\n\t\t};\n\n\t\ttraverse(components);\n\t\treturn maxMtime || null;\n\t}, [components]);\n\n\tconst sanitizedConfigInfo = useMemo(() => {\n\t\tif (!configurationInfo) { return null; }\n\t\treturn omitRestrictedFields(configurationInfo);\n\t}, [configurationInfo]);\n\n\tconst monacoTheme = useMonacoTheme();\n\tconst [isEditing, setIsEditing] = useState(false);\n\tconst [editedConfig, setEditedConfig] = useState<string>('');\n\tconst [jsonError, setJsonError] = useState<string | null>(null);\n\tconst [restrictedError, setRestrictedError] = useState<string[]>([]);\n\n\tconst { onConfigUpdate, isPending: isSaving } = useRollingConfigUpdate();\n\n\tuseEffect(() => {\n\t\tif (sanitizedConfigInfo && !isEditing) {\n\t\t\tsetEditedConfig(JSON.stringify(sanitizedConfigInfo, null, 4));\n\t\t\tsetJsonError(null);\n\t\t\tsetRestrictedError([]);\n\t\t}\n\t}, [sanitizedConfigInfo, isEditing]);\n\n\tconst handleEditorChange = useCallback((value: string | undefined) => {\n\t\tsetEditedConfig(value || '');\n\t\tif (value) {\n\t\t\ttry {\n\t\t\t\tconst parsed = JSON.parse(value);\n\t\t\t\tsetJsonError(null);\n\n\t\t\t\tconst blockedFields: string[] = [];\n\t\t\t\tconst checkBlocked = (obj: any, orig: any, path = '') => {\n\t\t\t\t\tfor (const key in obj) {\n\t\t\t\t\t\tconst currentPath = path ? `${path}.${key}` : key;\n\t\t\t\t\t\tconst val = obj[key];\n\t\t\t\t\t\tconst origVal = orig?.[key];\n\n\t\t\t\t\t\tif (isRestrictedConfigPath(currentPath, val, origVal)) {\n\t\t\t\t\t\t\tblockedFields.push(currentPath);\n\t\t\t\t\t\t} else if (typeof val === 'object' && val !== null && !Array.isArray(val)) {\n\t\t\t\t\t\t\tcheckBlocked(val, origVal, currentPath);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// Also check for deleted keys if they were blocked\n\t\t\t\t\tfor (const key in orig) {\n\t\t\t\t\t\tconst currentPath = path ? `${path}.${key}` : key;\n\t\t\t\t\t\tif (!(key in obj)) {\n\t\t\t\t\t\t\tif (isRestrictedConfigPath(currentPath, undefined, orig[key])) {\n\t\t\t\t\t\t\t\tblockedFields.push(currentPath);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tif (sanitizedConfigInfo) {\n\t\t\t\t\tcheckBlocked(parsed, sanitizedConfigInfo);\n\t\t\t\t}\n\t\t\t\tsetRestrictedError(blockedFields);\n\t\t\t} catch (e: any) {\n\t\t\t\tsetJsonError(e.message);\n\t\t\t\tsetRestrictedError([]);\n\t\t\t}\n\t\t}\n\t}, [configurationInfo]);\n\n\tconst handleEditorDidMount = useCallback<OnMount>((_editor, monaco) => {\n\t\tconfigureHarperConfigEditor(monaco);\n\t}, []);\n\n\tconst handleSave = useCallback(() => {\n\t\tif (jsonError || restrictedError.length > 0) { return; }\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(editedConfig);\n\t\t\tconst changedFields = getChangedFields(sanitizedConfigInfo, parsed);\n\t\t\tconst flattened = flattenConfig(changedFields);\n\n\t\t\tonConfigUpdate(flattened);\n\t\t\tsetIsEditing(false);\n\t\t} catch (e: any) {\n\t\t\tsetJsonError(e.message);\n\t\t}\n\t}, [editedConfig, jsonError, onConfigUpdate, sanitizedConfigInfo, restrictedError.length]);\n\n\tconst newLicenses = useMemo(() => {\n\t\tif (isLocalStudio) {\n\t\t\treturn [];\n\t\t}\n\t\tconst cloudLicenses = instanceInfo?.licenses;\n\t\tif (appliedLicenses && cloudLicenses) {\n\t\t\tconst appliedLicensesById = keyBy(appliedLicenses, 'id');\n\t\t\treturn cloudLicenses.filter(cloudLicense => !appliedLicensesById[cloudLicense.id]);\n\t\t}\n\t\treturn [];\n\t}, [appliedLicenses, instanceInfo]);\n\n\treturn (\n\t\t<div className=\"h-full flex flex-col\">\n\t\t\t{isLocalStudio\n\t\t\t\t? (\n\t\t\t\t\t<LocalStudioOverview>\n\t\t\t\t\t\t<dl className=\"grid grid-cols-1 sm:grid-cols-3\">\n\t\t\t\t\t\t\t<div className=\"px-4 pb-4 sm:col-span-1 sm:px-0\">\n\t\t\t\t\t\t\t\t<HarperVersion loadingRegistration={loadingRegistration} registrationInfo={registrationInfo} />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div className=\"px-4 pb-4 sm:col-span-1 sm:px-0\">\n\t\t\t\t\t\t\t\t<LastDeployedTimestamp loading={loadingComponents} timestamp={lastDeployedTimestamp} />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div className=\"px-4 pb-4 text-right sm:col-span-1 sm:px-0\">\n\t\t\t\t\t\t\t\t<RestartButton\n\t\t\t\t\t\t\t\t\ttargetNoun={targetNoun}\n\t\t\t\t\t\t\t\t\tinstanceClient={instanceParams.instanceClient}\n\t\t\t\t\t\t\t\t\toperation=\"restart\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</dl>\n\t\t\t\t\t</LocalStudioOverview>\n\t\t\t\t)\n\t\t\t\t: (\n\t\t\t\t\t<CloudStudioOverview>\n\t\t\t\t\t\t<dl className=\"flex-none grid grid-cols-1 sm:grid-cols-4\">\n\t\t\t\t\t\t\t<div className=\"px-4 pb-4 sm:col-span-1 sm:px-0\">\n\t\t\t\t\t\t\t\t<InstanceNodeName loadingInstanceInfo={loadingInstanceInfo} instanceInfo={instanceInfo} />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div className=\"px-4 pb-4 sm:col-span-1 sm:px-0\">\n\t\t\t\t\t\t\t\t<HarperVersion loadingRegistration={loadingRegistration} registrationInfo={registrationInfo} />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div className=\"px-4 pb-4 sm:col-span-1 sm:px-0\">\n\t\t\t\t\t\t\t\t<LastDeployedTimestamp loading={loadingComponents} timestamp={lastDeployedTimestamp} />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div className=\"px-4 pb-4 text-right sm:col-span-1 sm:px-0 grid gap-1\">\n\t\t\t\t\t\t\t\t{newLicenses?.length > 0 && <ApplyLicensesButton newLicenses={newLicenses} />}\n\t\t\t\t\t\t\t\t<RestartButton\n\t\t\t\t\t\t\t\t\ttargetNoun={targetNoun}\n\t\t\t\t\t\t\t\t\tinstanceClient={instanceParams.instanceClient}\n\t\t\t\t\t\t\t\t\toperation=\"restart\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div className=\"px-4 pb-4 sm:col-span-3 sm:px-0\">\n\t\t\t\t\t\t\t\t<InstanceURL loadingInstanceInfo={loadingInstanceInfo} instanceInfo={instanceInfo} />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div className=\"px-4 pb-4 sm:col-span-3 sm:px-0\">\n\t\t\t\t\t\t\t\t<ApplicationURL loadingInstanceInfo={loadingInstanceInfo} clusterInfo={clusterInfo} />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t{clusterInfo?.domains?.length && (\n\t\t\t\t\t\t\t\t<div className=\"px-4 pb-4 sm:col-span-3 sm:px-0\">\n\t\t\t\t\t\t\t\t\t<ClusterDomainsList loadingInstanceInfo={loadingInstanceInfo} clusterInfo={clusterInfo} />\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</dl>\n\t\t\t\t\t</CloudStudioOverview>\n\t\t\t\t)}\n\n\t\t\t<div className=\"flex-none flex items-center justify-between mb-2\">\n\t\t\t\t<div>\n\t\t\t\t\t<h3 className=\"font-bold text-sm/6\">Instance Config {isEditing ? '(editing)' : '(read only)'}</h3>\n\t\t\t\t\t{!instanceId && !isLocalStudio && (\n\t\t\t\t\t\t<p className=\"text-muted-foreground italic text-sm\">\n\t\t\t\t\t\t\tYou are viewing the config for one instance in your cluster, based on what the load balancer selected for\n\t\t\t\t\t\t\tyou.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t<div className=\"flex items-center gap-2 pr-4\">\n\t\t\t\t\t{!isEditing\n\t\t\t\t\t\t? (\n\t\t\t\t\t\t\t<Button size=\"sm\" onClick={() => setIsEditing(true)}>\n\t\t\t\t\t\t\t\t<EditIcon className=\"w-4 h-4 mr-1\" /> Edit\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t)\n\t\t\t\t\t\t: (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<Button type=\"button\" size=\"sm\" variant=\"ghost\" onClick={() => setIsEditing(false)}>\n\t\t\t\t\t\t\t\t\t<XIcon className=\"w-4 h-4 mr-1\" /> Cancel\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\tdisabled={!!jsonError || restrictedError.length > 0 || isSaving}\n\t\t\t\t\t\t\t\t\tonClick={handleSave}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<SaveIcon className=\"w-4 h-4 mr-1\" /> {isSaving ? 'Saving...' : 'Save & Restart'}\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t{jsonError && (\n\t\t\t\t<Alert variant=\"destructive\" className=\"mb-4\">\n\t\t\t\t\t<AlertCircleIcon className=\"h-4 w-4\" />\n\t\t\t\t\t<AlertTitle>Invalid JSON</AlertTitle>\n\t\t\t\t\t<AlertDescription>{jsonError}</AlertDescription>\n\t\t\t\t</Alert>\n\t\t\t)}\n\n\t\t\t{restrictedError.length > 0 && (\n\t\t\t\t<Alert variant=\"destructive\" className=\"mb-4\">\n\t\t\t\t\t<AlertCircleIcon className=\"h-4 w-4\" />\n\t\t\t\t\t<AlertTitle>Restricted Configuration</AlertTitle>\n\t\t\t\t\t<AlertDescription>\n\t\t\t\t\t\tThe following fields cannot be modified via Studio:\n\t\t\t\t\t\t<ul className=\"list-disc ml-4 mt-2\">\n\t\t\t\t\t\t\t{restrictedError.map(field => (\n\t\t\t\t\t\t\t\t<li key={field}>\n\t\t\t\t\t\t\t\t\t<code>{field}</code>\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</AlertDescription>\n\t\t\t\t</Alert>\n\t\t\t)}\n\n\t\t\t<div className=\"grow\">\n\t\t\t\t{!loadingConfig\n\t\t\t\t\t? (\n\t\t\t\t\t\t<Editor\n\t\t\t\t\t\t\tclassName=\"w-full min-h-full h-96\"\n\t\t\t\t\t\t\tpath={HARPER_CONFIG_MODEL_PATH}\n\t\t\t\t\t\t\tlanguage=\"json\"\n\t\t\t\t\t\t\ttheme={monacoTheme}\n\t\t\t\t\t\t\tonMount={handleEditorDidMount}\n\t\t\t\t\t\t\toptions={{ readOnly: !isEditing, scrollBeyondLastLine: false }}\n\t\t\t\t\t\t\tvalue={isEditing ? editedConfig : JSON.stringify(sanitizedConfigInfo, null, 4)}\n\t\t\t\t\t\t\tonChange={handleEditorChange}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)\n\t\t\t\t\t: (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t<TextLoadingSkeleton className=\"w-full\" />\n\t\t\t\t\t\t\t<TextLoadingSkeleton className=\"w-full\" />\n\t\t\t\t\t\t\t<TextLoadingSkeleton className=\"w-1/2\" />\n\t\t\t\t\t\t</>\n\t\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n","import { LocalRole } from '@/integrations/api/api.patch';\nimport { translateSecondsToAgo } from '@/lib/translateSecondsToAgo';\nimport { ColumnDef, createColumnHelper } from '@tanstack/react-table';\n\nconst columnHelper = createColumnHelper<LocalRole>();\n\nexport const dataTableColumns: Array<ColumnDef<LocalRole>> = [\n\t{\n\t\theader: 'Role',\n\t\taccessorKey: 'role',\n\t\tenableSorting: false,\n\t},\n\tcolumnHelper.display({\n\t\theader: 'Created',\n\t\tenableSorting: false,\n\t\tid: '__createdtime__',\n\t\tcell: (props) =>\n\t\t\ttranslateSecondsToAgo(\n\t\t\t\t(Date.now() - props.row.original.__createdtime__) / 1000,\n\t\t\t\tprops.row.original.__createdtime__,\n\t\t\t),\n\t}),\n\tcolumnHelper.display({\n\t\theader: 'Updated',\n\t\tid: '__updatedtime__',\n\t\tenableSorting: false,\n\t\tcell: (props) =>\n\t\t\ttranslateSecondsToAgo(\n\t\t\t\t(Date.now() - props.row.original.__updatedtime__) / 1000,\n\t\t\t\tprops.row.original.__updatedtime__,\n\t\t\t),\n\t}),\n\tcolumnHelper.display({\n\t\theader: 'Super User',\n\t\tid: 'super_user',\n\t\tenableSorting: false,\n\t\tcell: (props) => (props.row.original.permission.super_user ? 'Yes' : 'No'),\n\t}),\n\tcolumnHelper.display({\n\t\theader: 'Structure User',\n\t\tid: 'structure_user',\n\t\tenableSorting: false,\n\t\tcell: (props) => (props.row.original.permission.structure_user ? 'Yes' : 'No'),\n\t}),\n];\n","import { InstanceClientConfig } from '@/config/instanceClientConfig';\nimport { useMutation } from '@tanstack/react-query';\n\nexport interface AddRoleFormData {\n\trole: string;\n\tsuper_user?: boolean;\n\tstructure_user?: boolean;\n}\n\nexport async function onAddRoleSubmit(formData: AddRoleFormData & InstanceClientConfig) {\n\tconst { role, super_user, structure_user, instanceClient } = formData;\n\tconst { data } = await instanceClient.post(\n\t\t'/',\n\t\t{\n\t\t\toperation: 'add_role',\n\t\t\trole,\n\t\t\tpermission: {\n\t\t\t\tsuper_user,\n\t\t\t\tstructure_user,\n\t\t\t},\n\t\t},\n\t);\n\treturn data;\n}\n\nexport function useAddRoleMutation() {\n\treturn useMutation({\n\t\tmutationFn: onAddRoleSubmit,\n\t});\n}\n","import { z } from 'zod';\n\nexport const AddRoleFormSchema = z.object({\n\trole: z\n\t\t.string()\n\t\t.nonempty({ error: 'Please enter a role.' })\n\t\t.regex(/^[a-zA-Z_]*$/, {\n\t\t\terror: 'Role must contain only letters and underscores.',\n\t\t})\n\t\t.max(30, {\n\t\t\terror: 'Role cannot be longer than 30 characters.',\n\t\t}),\n\tsuper_user: z.boolean(),\n\tstructure_user: z.boolean(),\n});\n","import { Button } from '@/components/ui/button';\nimport {\n\tDialog,\n\tDialogContent,\n\tDialogDescription,\n\tDialogFooter,\n\tDialogHeader,\n\tDialogTitle,\n} from '@/components/ui/dialog';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { AddRoleFormData, useAddRoleMutation } from '@/integrations/api/instance/auth/addRole';\nimport { AddRoleFormSchema } from '@/integrations/api/instance/auth/addRoleFormSchema';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { Save } from 'lucide-react';\nimport { useCallback } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\n\nexport function AddRoleModal({\n\tisModalOpen,\n\tonChangesSaved,\n\tsetIsModalOpen,\n}: {\n\tisModalOpen: boolean;\n\tonChangesSaved: (roleName: string) => void;\n\tsetIsModalOpen: (open: boolean) => void;\n}) {\n\tconst form = useForm({\n\t\tresolver: zodResolver(AddRoleFormSchema),\n\t\tdefaultValues: {\n\t\t\trole: '',\n\t\t\tsuper_user: false,\n\t\t\tstructure_user: false,\n\t\t},\n\t});\n\tconst instanceParams = useInstanceClientIdParams();\n\tconst { mutate: addRole, isPending: isAddPending } = useAddRoleMutation();\n\n\tconst onSubmitClick = useCallback(\n\t\tasync (formData: AddRoleFormData) => {\n\t\t\tif (formData) {\n\t\t\t\taddRole(\n\t\t\t\t\t{\n\t\t\t\t\t\trole: formData.role,\n\t\t\t\t\t\tsuper_user: formData.super_user,\n\t\t\t\t\t\tstructure_user: formData.structure_user,\n\t\t\t\t\t\t...instanceParams,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tonSuccess: () => {\n\t\t\t\t\t\t\tform.reset();\n\t\t\t\t\t\t\tonChangesSaved(formData.role);\n\t\t\t\t\t\t\ttoast.success('Role added successfully!');\n\t\t\t\t\t\t\tsetIsModalOpen(false);\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\t[addRole, form, instanceParams, onChangesSaved, setIsModalOpen],\n\t);\n\n\tconst onClickCancel = useCallback(() => {\n\t\tform.reset();\n\t\tsetIsModalOpen(false);\n\t}, [form, setIsModalOpen]);\n\n\treturn (\n\t\t<Dialog onOpenChange={setIsModalOpen} open={isModalOpen}>\n\t\t\t{/* NOTE - Is this okay to do for the aria describedby? */}\n\t\t\t<DialogContent aria-describedby={undefined}>\n\t\t\t\t<Form {...form}>\n\t\t\t\t\t<form\n\t\t\t\t\t\tid=\"instance-add-role-form\"\n\t\t\t\t\t\tname=\"instance-add-role-form\"\n\t\t\t\t\t\tonSubmit={form.handleSubmit(onSubmitClick)}\n\t\t\t\t\t\tclassName=\"grid gap-4 my-4 md:grid-cols-2\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<DialogHeader className=\"md:col-span-2\">\n\t\t\t\t\t\t\t<DialogTitle>Add New Role</DialogTitle>\n\t\t\t\t\t\t\t<DialogDescription>\n\t\t\t\t\t\t\t\tAfter adding the role, you will be able to edit the per-table permissions.\n\t\t\t\t\t\t\t</DialogDescription>\n\t\t\t\t\t\t</DialogHeader>\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"role\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem className=\"md:col-span-2\">\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Name</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Input type=\"text\" {...field} />\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"super_user\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem className=\"flex\">\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"w-6\"\n\t\t\t\t\t\t\t\t\t\t\tchecked={field.value}\n\t\t\t\t\t\t\t\t\t\t\tonChange={(e) => field.onChange(e.target.checked)}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pl-4 pr-8 flex-1 py-2.5\">Super User</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"structure_user\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem className=\"flex\">\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"w-6\"\n\t\t\t\t\t\t\t\t\t\t\tchecked={field.value}\n\t\t\t\t\t\t\t\t\t\t\tonChange={(e) => field.onChange(e.target.checked)}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pl-4 pr-8 flex-1 py-2.5\">Structure User</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t<DialogFooter className=\"md:col-span-2\">\n\t\t\t\t\t\t\t<div className=\"flex justify-between w-full\">\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tvariant=\"destructiveOutline\"\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\t\t\tonClick={onClickCancel}\n\t\t\t\t\t\t\t\t\tdisabled={isAddPending}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t<Button type=\"submit\" variant=\"submit\" className=\"rounded-full\" disabled={isAddPending}>\n\t\t\t\t\t\t\t\t\t<Save /> Add Role\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</DialogFooter>\n\t\t\t\t\t</form>\n\t\t\t\t</Form>\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n}\n","import { InstanceClientConfig, InstanceClientIdConfig } from '@/config/instanceClientConfig';\nimport { LocalRole } from '@/integrations/api/api.patch';\nimport { queryOptions } from '@tanstack/react-query';\n\nexport function getListRolesQueryOptions({ entityId, instanceClient }: InstanceClientIdConfig) {\n\treturn queryOptions({\n\t\tqueryKey: [entityId, 'list_roles'] as const,\n\t\tqueryFn: () => getListRoles({ instanceClient }),\n\t\trefetchInterval: 10_000,\n\t});\n}\n\nasync function getListRoles({ instanceClient }: InstanceClientConfig) {\n\tconst { data } = await instanceClient.post('/', {\n\t\toperation: 'list_roles',\n\t});\n\treturn data as LocalRole[];\n}\n","import {\n\tInstanceDatabaseMap,\n\tLocalLegacyRolePermissionTable,\n\tLocalRolePermission,\n\tLocalRolePermissionTable,\n} from '@/integrations/api/api.patch';\nimport { keyBy } from '@/lib/keyBy';\n\nexport function calculateDefaultPermissions({\n\tinstanceDatabaseMap,\n\tcurrentRolePermissions,\n\tversion,\n\tshowAttributes,\n}: {\n\tinstanceDatabaseMap: InstanceDatabaseMap;\n\tcurrentRolePermissions: LocalRolePermission;\n\tversion: string;\n\tshowAttributes: boolean;\n}): LocalRolePermission {\n\tconst permissionStructure: LocalRolePermission = {\n\t\t...currentRolePermissions,\n\t};\n\tif (\n\t\tcurrentRolePermissions.super_user || currentRolePermissions.structure_user || currentRolePermissions.cluster_user\n\t) {\n\t\treturn currentRolePermissions;\n\t}\n\tconst [major, minor, patch] = version.split('.').map(number => parseInt(number, 10));\n\tconst legacy = version !== '2.0.000' && major <= 2 && minor <= 1 && patch <= 2;\n\n\tfor (const databaseName in instanceDatabaseMap) {\n\t\tpermissionStructure[databaseName] = {\n\t\t\ttables: {},\n\t\t};\n\t\tfor (const tableName in instanceDatabaseMap[databaseName]) {\n\t\t\tconst thisTable = instanceDatabaseMap[databaseName][tableName];\n\t\t\tconst attributes = thisTable.attributes.map((a) => a.attribute).sort();\n\t\t\tif (legacy) {\n\t\t\t\tconst extantTablePermissions = currentRolePermissions && currentRolePermissions[databaseName]\n\t\t\t\t\t&& currentRolePermissions[databaseName].tables[tableName];\n\t\t\t\tpermissionStructure[databaseName].tables[tableName] = buildLegacy(\n\t\t\t\t\textantTablePermissions as LocalLegacyRolePermissionTable,\n\t\t\t\t\tattributes,\n\t\t\t\t\tshowAttributes,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tconst extantTablePermissions = currentRolePermissions && currentRolePermissions[databaseName]\n\t\t\t\t\t&& currentRolePermissions[databaseName].tables[tableName];\n\t\t\t\tpermissionStructure[databaseName].tables[tableName] = buildCurrent(\n\t\t\t\t\textantTablePermissions as LocalRolePermissionTable,\n\t\t\t\t\tattributes,\n\t\t\t\t\tshowAttributes,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn permissionStructure;\n}\n\nfunction buildLegacy(\n\textantTablePermissions: LocalLegacyRolePermissionTable | undefined,\n\tattributes: string[],\n\tshowAttributes: boolean,\n): LocalLegacyRolePermissionTable {\n\tconst attributeRestrictionsMap = extantTablePermissions\n\t\t&& keyBy(extantTablePermissions.attribute_restrictions, 'attribute_name');\n\treturn {\n\t\tread: extantTablePermissions ? extantTablePermissions.read : true,\n\t\tinsert: extantTablePermissions ? extantTablePermissions.insert : true,\n\t\tupdate: extantTablePermissions ? extantTablePermissions.update : true,\n\t\tdelete: extantTablePermissions ? extantTablePermissions.delete : true,\n\t\tattribute_restrictions: attributes\n\t\t\t.filter(() => showAttributes)\n\t\t\t.map((a) => {\n\t\t\t\tconst extantAttributePermissions = attributeRestrictionsMap?.[a];\n\n\t\t\t\treturn {\n\t\t\t\t\tattribute_name: a,\n\t\t\t\t\tread: extantAttributePermissions\n\t\t\t\t\t\t? extantAttributePermissions.read\n\t\t\t\t\t\t: extantTablePermissions\n\t\t\t\t\t\t? extantTablePermissions.read\n\t\t\t\t\t\t: true,\n\t\t\t\t\tinsert: extantAttributePermissions\n\t\t\t\t\t\t? extantAttributePermissions.insert\n\t\t\t\t\t\t: extantTablePermissions\n\t\t\t\t\t\t? extantTablePermissions.insert\n\t\t\t\t\t\t: true,\n\t\t\t\t\tupdate: extantAttributePermissions\n\t\t\t\t\t\t? extantAttributePermissions.update\n\t\t\t\t\t\t: extantTablePermissions\n\t\t\t\t\t\t? extantTablePermissions.update\n\t\t\t\t\t\t: true,\n\t\t\t\t\tdelete: extantAttributePermissions\n\t\t\t\t\t\t? extantAttributePermissions.delete\n\t\t\t\t\t\t: extantTablePermissions\n\t\t\t\t\t\t? extantTablePermissions.delete\n\t\t\t\t\t\t: true,\n\t\t\t\t};\n\t\t\t}),\n\t};\n}\n\nfunction buildCurrent(\n\textantTablePermissions: LocalRolePermissionTable | undefined,\n\tattributes: string[],\n\tshowAttributes: boolean,\n): LocalRolePermissionTable {\n\tconst attributePermissionsMap = extantTablePermissions\n\t\t&& keyBy(extantTablePermissions.attribute_permissions || [], 'attribute_name');\n\treturn {\n\t\tread: extantTablePermissions ? extantTablePermissions.read : false,\n\t\tinsert: extantTablePermissions ? extantTablePermissions.insert : false,\n\t\tupdate: extantTablePermissions ? extantTablePermissions.update : false,\n\t\tdelete: extantTablePermissions ? extantTablePermissions.delete : false,\n\t\tattribute_permissions: showAttributes\n\t\t\t? attributes\n\t\t\t\t.map((a: string) => {\n\t\t\t\t\tconst extantAttributePermissions = attributePermissionsMap?.[a];\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\tattribute_name: a,\n\t\t\t\t\t\tread: extantAttributePermissions\n\t\t\t\t\t\t\t? extantAttributePermissions.read\n\t\t\t\t\t\t\t: extantTablePermissions?.attribute_permissions?.length\n\t\t\t\t\t\t\t? false\n\t\t\t\t\t\t\t: extantTablePermissions?.read || false,\n\t\t\t\t\t\tinsert: extantAttributePermissions\n\t\t\t\t\t\t\t? extantAttributePermissions.insert\n\t\t\t\t\t\t\t: extantTablePermissions?.attribute_permissions?.length\n\t\t\t\t\t\t\t? false\n\t\t\t\t\t\t\t: extantTablePermissions?.insert || false,\n\t\t\t\t\t\tupdate: extantAttributePermissions\n\t\t\t\t\t\t\t? extantAttributePermissions.update\n\t\t\t\t\t\t\t: extantTablePermissions?.attribute_permissions?.length\n\t\t\t\t\t\t\t? false\n\t\t\t\t\t\t\t: extantTablePermissions?.update || false,\n\t\t\t\t\t};\n\t\t\t\t})\n\t\t\t: null,\n\t};\n}\n","import { InstanceClientConfig } from '@/config/instanceClientConfig';\nimport { LocalRolePermission } from '@/integrations/api/api.patch';\nimport { useMutation } from '@tanstack/react-query';\n\ninterface AlterRoleRequestBody extends InstanceClientConfig {\n\tid: string;\n\tpermission: LocalRolePermission;\n}\n\ninterface AlterRoleResponse {\n\tid: string;\n\tpermission: object;\n\trole: string;\n\t__createdtime__: number;\n\t__updatedtime__: number;\n}\n\nasync function onAlterRole({\n\tid,\n\tpermission,\n\tinstanceClient,\n}: AlterRoleRequestBody): Promise<AlterRoleResponse> {\n\tconst { data } = await instanceClient.post(\n\t\t'/',\n\t\t{\n\t\t\toperation: 'alter_role',\n\t\t\tid,\n\t\t\tpermission,\n\t\t},\n\t);\n\treturn data as AlterRoleResponse;\n}\n\nexport function useAlterRole() {\n\treturn useMutation({\n\t\tmutationFn: onAlterRole,\n\t});\n}\n","import { InstanceClientConfig } from '@/config/instanceClientConfig';\nimport { useMutation } from '@tanstack/react-query';\n\ninterface DeleteRoleData extends InstanceClientConfig {\n\tid: string;\n}\n\ninterface DeleteRoleResponse {\n\tmessage: string;\n}\n\nasync function onDeleteRole({ id, instanceClient }: DeleteRoleData) {\n\tconst { data } = await instanceClient.post<DeleteRoleResponse>('/', {\n\t\toperation: 'drop_role',\n\t\tid,\n\t});\n\treturn data;\n}\n\nexport function useDeleteRoleMutation() {\n\treturn useMutation({\n\t\tmutationFn: onDeleteRole,\n\t});\n}\n","import { InstanceClientIdConfig } from '@/config/instanceClientConfig';\nimport { InstanceDatabaseMap } from '@/integrations/api/api.patch';\nimport { queryOptions } from '@tanstack/react-query';\n\nexport async function getDescribeAll({ instanceClient }: InstanceClientIdConfig) {\n\tconst { data } = await instanceClient.post<InstanceDatabaseMap>('/', {\n\t\toperation: 'describe_all',\n\t});\n\treturn data;\n}\n\nexport function getDescribeAllQueryOptions(params: InstanceClientIdConfig) {\n\treturn queryOptions({\n\t\tqueryKey: [params.entityId, 'describe_all'] as const,\n\t\tqueryFn: () => getDescribeAll(params),\n\t\tstaleTime: 60_000,\n\t\tgcTime: 5_000,\n\t\tretry: false,\n\t});\n}\n","import { TextLoadingSkeleton } from '@/components/TextLoadingSkeleton';\nimport { Button } from '@/components/ui/button';\nimport { Dialog, DialogContent, DialogDescription, DialogFooter, DialogTitle } from '@/components/ui/dialog';\nimport { Input } from '@/components/ui/input';\nimport { Label } from '@/components/ui/label';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { calculateDefaultPermissions } from '@/features/instance/config/roles/defaultCalculator';\nimport { useInstanceAuth } from '@/hooks/useAuth';\nimport { useCheckboxCallback } from '@/hooks/useCheckboxCallback';\nimport { useMonacoTheme } from '@/hooks/useMonacoTheme';\nimport { LocalRole, LocalRolePermission } from '@/integrations/api/api.patch';\nimport { useAlterRole } from '@/integrations/api/instance/auth/alterRole';\nimport { useDeleteRoleMutation } from '@/integrations/api/instance/auth/deleteRole';\nimport { getDescribeAllQueryOptions } from '@/integrations/api/instance/database/getDescribeAll';\nimport { getRegistrationInfoQueryOptions } from '@/integrations/api/instance/status/getRegistrationInfo';\nimport { Editor } from '@/lib/monaco/MonacoEditor';\nimport { safeParse } from '@/lib/string/safeParse';\nimport { useQuery } from '@tanstack/react-query';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { toast } from 'sonner';\n\nexport function EditRoleModal({\n\tdata,\n\tinstanceId,\n\tclusterId,\n\tisModalOpen,\n\tcloseModal,\n\tonSelectRole,\n\tonChangesSaved,\n}: {\n\tdata: LocalRole;\n\tinstanceId?: string;\n\tclusterId?: string;\n\tisModalOpen: boolean;\n\tcloseModal: () => void;\n\tonSelectRole: (role?: string) => void;\n\tonChangesSaved: () => void;\n}) {\n\tconst monacoTheme = useMonacoTheme();\n\tconst { role, permission: initialPermissions } = data;\n\tconst [updatedPermissions, setUpdatedPermissions] = useState<string | undefined>(\n\t\tJSON.stringify(initialPermissions, null, 2),\n\t);\n\n\tconst instanceParams = useInstanceClientIdParams();\n\tconst [isValidJSON, setIsValidJSON] = useState(true);\n\tconst { data: instanceDatabaseMap } = useQuery(getDescribeAllQueryOptions(instanceParams));\n\tconst { data: registrationInfo } = useQuery(\n\t\tgetRegistrationInfoQueryOptions(instanceParams),\n\t);\n\tconst auth = useInstanceAuth(instanceId ?? clusterId);\n\tconst isSelf = auth.user?.role?.role === data.role;\n\n\tconst [showAttributes, onShowAttributesChanged] = useCheckboxCallback(updatedPermissions?.includes('attribute_name'));\n\n\tconst { mutate: alterRole, isPending } = useAlterRole();\n\tconst { mutate: dropRole } = useDeleteRoleMutation();\n\n\tconst onValidate = useCallback(\n\t\t(markers: unknown[]) => {\n\t\t\tsetIsValidJSON(markers.length === 0);\n\t\t},\n\t\t[setIsValidJSON],\n\t);\n\n\tconst defaultValue = useMemo(() => {\n\t\treturn JSON.stringify(\n\t\t\tinstanceDatabaseMap && registrationInfo && calculateDefaultPermissions({\n\t\t\t\tinstanceDatabaseMap,\n\t\t\t\tcurrentRolePermissions: updatedPermissions && safeParse(updatedPermissions) || initialPermissions,\n\t\t\t\tversion: registrationInfo.version,\n\t\t\t\tshowAttributes: showAttributes,\n\t\t\t}),\n\t\t\tnull,\n\t\t\t2,\n\t\t);\n\t\t// We exclude updatedPermissions on purpose from the deps: defaultValue must only recompute on\n\t\t// load and when showAttributes toggles, otherwise the useEffect below overwrites the editor's\n\t\t// value on every keystroke and Monaco jumps the cursor to the end of the input.\n\t\t// eslint-disable-next-line react/exhaustive-deps\n\t}, [initialPermissions, instanceDatabaseMap, registrationInfo, showAttributes]);\n\n\tuseEffect(() => {\n\t\tsetUpdatedPermissions(defaultValue);\n\t}, [defaultValue]);\n\n\tconst onRoleUpdated = useCallback(\n\t\t(updatedPermissions: string) => {\n\t\t\tif (updatedPermissions) {\n\t\t\t\tconst parsedPermissions = JSON.parse(updatedPermissions) as LocalRolePermission;\n\t\t\t\tif (parsedPermissions.super_user || parsedPermissions.structure_user || parsedPermissions.cluster_user) {\n\t\t\t\t\tfor (const parsedPermissionsKey in parsedPermissions) {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tparsedPermissionsKey !== 'super_user' && parsedPermissionsKey !== 'structure_user'\n\t\t\t\t\t\t\t&& parsedPermissionsKey !== 'cluster_user'\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// If you're a super, structure or cluster user, you don't need more specific permissions.\n\t\t\t\t\t\t\tdelete parsedPermissions[parsedPermissionsKey];\n\t\t\t\t\t\t} else if (parsedPermissions[parsedPermissionsKey] === false) {\n\t\t\t\t\t\t\t// If you've set one of the top-level properties, clear out any others set to false.\n\t\t\t\t\t\t\tdelete parsedPermissions[parsedPermissionsKey];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\talterRole(\n\t\t\t\t\t{\n\t\t\t\t\t\tid: data.id,\n\t\t\t\t\t\tpermission: parsedPermissions,\n\t\t\t\t\t\t...instanceParams,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tonSuccess: () => {\n\t\t\t\t\t\t\ttoast.success('Role updated successfully!');\n\t\t\t\t\t\t\tonSelectRole(undefined);\n\t\t\t\t\t\t\tonChangesSaved();\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\t[alterRole, data.id, instanceParams, onChangesSaved, onSelectRole],\n\t);\n\n\tconst onRoleDeleted = useCallback(() => {\n\t\tdropRole(\n\t\t\t{\n\t\t\t\tid: data.id,\n\t\t\t\t...instanceParams,\n\t\t\t},\n\t\t\t{\n\t\t\t\tonSuccess: () => {\n\t\t\t\t\ttoast.success('Role deleted successfully!');\n\t\t\t\t\tonSelectRole(undefined);\n\t\t\t\t\tonChangesSaved();\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t}, [data.id, dropRole, instanceParams, onChangesSaved, onSelectRole]);\n\n\tconst onSubmitClick = useCallback(() => {\n\t\tif (updatedPermissions && isValidJSON) {\n\t\t\tonRoleUpdated(updatedPermissions);\n\t\t}\n\t}, [updatedPermissions, onRoleUpdated, isValidJSON]);\n\n\tconst onRoleDeleteClick = useCallback(() => {\n\t\tonRoleDeleted();\n\t}, [onRoleDeleted]);\n\n\treturn (\n\t\t<Dialog onOpenChange={closeModal} open={isModalOpen}>\n\t\t\t<DialogContent className=\"sm:max-w-[750px]\">\n\t\t\t\t<DialogTitle>{isSelf ? 'View' : 'Edit'} Role \"{role}\"</DialogTitle>\n\t\t\t\t<DialogDescription>\n\t\t\t\t\t{isSelf\n\t\t\t\t\t\t? 'You can view your own role, but you cannot edit it. Please assign yourself a different'\n\t\t\t\t\t\t\t+ ' role to edit this role.'\n\t\t\t\t\t\t: \"Edit the role's permissions in JSON format or remove the role entirely.\"}\n\t\t\t\t</DialogDescription>\n\t\t\t\t{defaultValue\n\t\t\t\t\t? (\n\t\t\t\t\t\t<Editor\n\t\t\t\t\t\t\ttheme={monacoTheme}\n\t\t\t\t\t\t\theight=\"400px\"\n\t\t\t\t\t\t\tdefaultLanguage=\"json\"\n\t\t\t\t\t\t\tvalue={updatedPermissions}\n\t\t\t\t\t\t\toptions={isSelf ? { readOnly: true } : undefined}\n\t\t\t\t\t\t\tonValidate={onValidate}\n\t\t\t\t\t\t\tonChange={setUpdatedPermissions}\n\t\t\t\t\t\t\tdefaultValue={defaultValue}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)\n\t\t\t\t\t: <TextLoadingSkeleton />}\n\t\t\t\t<DialogFooter>\n\t\t\t\t\t{!isSelf && (\n\t\t\t\t\t\t<div className=\"flex justify-between w-full\">\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tvariant=\"destructiveOutline\"\n\t\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\t\tonClick={onRoleDeleteClick}\n\t\t\t\t\t\t\t\tdisabled={isPending}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tDelete Role\n\t\t\t\t\t\t\t</Button>\n\n\t\t\t\t\t\t\t<div className=\"grow\" />\n\n\t\t\t\t\t\t\t<Label className=\"flex\">\n\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\t\tclassName=\"w-6\"\n\t\t\t\t\t\t\t\t\tchecked={showAttributes}\n\t\t\t\t\t\t\t\t\tonChange={onShowAttributesChanged}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<span className=\"pl-4 pr-8 flex-1 py-2.5\">Pick Attributes</span>\n\t\t\t\t\t\t\t</Label>\n\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\tvariant=\"submit\"\n\t\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\t\tonClick={onSubmitClick}\n\t\t\t\t\t\t\t\tdisabled={isPending || !isValidJSON}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tSave Changes\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t</DialogFooter>\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n}\n","import { Loading } from '@/components/Loading';\nimport { SimpleBrowseDataTable } from '@/components/SimpleBrowseDataTable';\nimport { Button } from '@/components/ui/button';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { dataTableColumns } from '@/features/instance/config/roles/constants/tableDefinition';\nimport { AddRoleModal } from '@/features/instance/config/roles/modals/AddRoleModal';\nimport { useRefreshClick } from '@/hooks/useRefreshClick';\nimport { LocalRole } from '@/integrations/api/api.patch';\nimport { getListRolesQueryOptions } from '@/integrations/api/instance/auth/getListRoles';\nimport { useSuspenseQuery } from '@tanstack/react-query';\nimport { useNavigate, useParams } from '@tanstack/react-router';\nimport { Row } from '@tanstack/react-table';\nimport { PlusIcon, RefreshCwIcon } from 'lucide-react';\nimport { Suspense, useCallback, useMemo, useState } from 'react';\nimport { EditRoleModal } from './modals/EditRoleModal';\n\nexport function ConfigRolesIndex() {\n\tconst navigate = useNavigate();\n\tconst { clusterId, instanceId, roleId }: {\n\t\tinstanceId?: string;\n\t\tclusterId?: string;\n\t\troleId?: string;\n\t} = useParams({ strict: false });\n\tconst instanceParams = useInstanceClientIdParams();\n\tconst {\n\t\tdata: localRoles,\n\t\trefetch,\n\t\tisFetching,\n\t\tisRefetching,\n\t} = useSuspenseQuery(getListRolesQueryOptions(instanceParams));\n\n\tconst selectedRole = useMemo(() => localRoles?.find((role) => role.id === roleId), [localRoles, roleId]);\n\n\tconst onSelectRole = useCallback(\n\t\t(newRole: string | undefined) => {\n\t\t\tconst parts = [roleId ? '..' : '', newRole].filter(Boolean);\n\t\t\tvoid navigate({ to: parts.join('/') });\n\t\t},\n\t\t[roleId, navigate],\n\t);\n\n\tconst isEditModalOpen = !!roleId && !!selectedRole;\n\n\tconst [isAddModalOpen, setIsAddModalOpen] = useState(false);\n\n\tconst onAddClicked = useCallback(() => {\n\t\tsetIsAddModalOpen(true);\n\t}, [setIsAddModalOpen]);\n\tconst onRoleAdded = useCallback((roleName: string) => {\n\t\tvoid refetch();\n\t\tsetIsAddModalOpen(false);\n\t\tonSelectRole(roleName);\n\t}, [onSelectRole, refetch]);\n\n\tconst onRowClick = useCallback(\n\t\t(rowData: Row<LocalRole>) => {\n\t\t\tonSelectRole(rowData.original.role);\n\t\t},\n\t\t[onSelectRole],\n\t);\n\tconst closeEditModal = useCallback(() => {\n\t\tonSelectRole(undefined);\n\t}, [onSelectRole]);\n\n\tconst onRefreshClick = useRefreshClick(refetch);\n\n\treturn (\n\t\t<Suspense fallback={<Loading className=\"flex flex-col items-center justify-center h-full\" text=\"Loading...\" />}>\n\t\t\t<SimpleBrowseDataTable\n\t\t\t\tcolumns={dataTableColumns}\n\t\t\t\tdata={localRoles}\n\t\t\t\tisFetching={isFetching}\n\t\t\t\tonRowClick={onRowClick}\n\t\t\t>\n\t\t\t\t<Button variant=\"defaultOutline\" onClick={onRefreshClick} accessKey=\"r\" disabled={isFetching || isRefetching}>\n\t\t\t\t\t<RefreshCwIcon />\n\t\t\t\t\t<span className=\"hidden lg:inline-block\">\n\t\t\t\t\t\t<u>R</u>efresh\n\t\t\t\t\t</span>\n\t\t\t\t</Button>\n\t\t\t\t<Button variant=\"positiveOutline\" onClick={onAddClicked} accessKey=\"a\" disabled={isAddModalOpen}>\n\t\t\t\t\t<PlusIcon />\n\t\t\t\t\t<span>\n\t\t\t\t\t\t<u>A</u>dd\n\t\t\t\t\t</span>\n\t\t\t\t</Button>\n\t\t\t</SimpleBrowseDataTable>\n\t\t\t<AddRoleModal isModalOpen={isAddModalOpen} onChangesSaved={onRoleAdded} setIsModalOpen={setIsAddModalOpen} />\n\t\t\t{isEditModalOpen && (\n\t\t\t\t<EditRoleModal\n\t\t\t\t\tinstanceId={instanceId}\n\t\t\t\t\tclusterId={clusterId}\n\t\t\t\t\tisModalOpen={isEditModalOpen}\n\t\t\t\t\tcloseModal={closeEditModal}\n\t\t\t\t\tdata={selectedRole}\n\t\t\t\t\tonSelectRole={onSelectRole}\n\t\t\t\t\tonChangesSaved={() => refetch()}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</Suspense>\n\t);\n}\n","import { InstanceClientIdConfig } from '@/config/instanceClientConfig';\nimport { queryOptions } from '@tanstack/react-query';\n\nexport interface SSHKeyName {\n\tname: string;\n}\n\nasync function listSSHKeys({ instanceClient }: InstanceClientIdConfig) {\n\tconst { data } = await instanceClient.post<SSHKeyName[]>('/', {\n\t\toperation: 'list_ssh_keys',\n\t});\n\treturn data;\n}\n\nexport function listSSHKeysQueryOptions(params: InstanceClientIdConfig) {\n\treturn queryOptions({\n\t\tqueryKey: [params.entityId, 'list_ssh_keys'] as const,\n\t\tqueryFn: () => listSSHKeys(params),\n\t});\n}\n","import { SSHKeyName } from '@/integrations/api/instance/ssh/listSSHKeys';\nimport { ColumnDef } from '@tanstack/react-table';\n\nexport const dataTableColumns: Array<ColumnDef<SSHKeyName>> = [\n\t{\n\t\theader: 'SSH Key Name',\n\t\taccessorKey: 'name',\n\t\tenableSorting: false,\n\t},\n];\n","import { InstanceClientIdConfig } from '@/config/instanceClientConfig';\nimport { queryOptions } from '@tanstack/react-query';\n\ninterface SSHKeyKnownHosts {\n\tknown_hosts: string | null;\n}\n\nasync function getSSHKnownHosts({ instanceClient }: InstanceClientIdConfig) {\n\tconst { data } = await instanceClient.post<SSHKeyKnownHosts>('/', {\n\t\toperation: 'get_ssh_known_hosts',\n\t});\n\treturn data;\n}\n\nexport function getSSHKnownHostsQueryOptions(params: InstanceClientIdConfig) {\n\treturn queryOptions({\n\t\tqueryKey: [params.entityId, 'get_ssh_known_hosts'] as const,\n\t\tqueryFn: () => getSSHKnownHosts(params),\n\t});\n}\n","import { InstanceClientConfig, InstanceTypeConfig } from '@/config/instanceClientConfig';\nimport { ReplicatedResponse } from '@/integrations/api/replication';\nimport { useMutation } from '@tanstack/react-query';\nimport { z } from 'zod';\n\nexport const SSHKnownHostsSchema = z.object({\n\tknown_hosts: z.string().trim(),\n});\n\ntype SetSSHKnownHostsFormData = z.infer<typeof SSHKnownHostsSchema> & InstanceClientConfig & InstanceTypeConfig;\n\nasync function setSSHKnownHosts(formData: SetSSHKnownHostsFormData) {\n\tconst { instanceClient, entityType, ...sshKey } = formData;\n\tconst { data } = await instanceClient.post<ReplicatedResponse>('/', {\n\t\toperation: 'set_ssh_known_hosts',\n\t\treplicated: entityType === 'cluster',\n\t\t...sshKey,\n\t});\n\treturn data;\n}\n\nexport function useSetSSHKnownHosts() {\n\treturn useMutation({\n\t\tmutationFn: setSSHKnownHosts,\n\t});\n}\n","import { Button } from '@/components/ui/button';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormDescription } from '@/components/ui/form/FormDescription';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Textarea } from '@/components/ui/textarea';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { getSSHKnownHostsQueryOptions } from '@/integrations/api/instance/ssh/getSSHKnownHosts';\nimport { SSHKnownHostsSchema, useSetSSHKnownHosts } from '@/integrations/api/instance/ssh/setSSHKnownHosts';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useSuspenseQuery } from '@tanstack/react-query';\nimport { Save } from 'lucide-react';\nimport { useCallback } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\n\nexport function KnownHosts() {\n\tconst instanceParams = useInstanceClientIdParams();\n\tconst { data } = useSuspenseQuery(getSSHKnownHostsQueryOptions(instanceParams));\n\tconst form = useForm({\n\t\tresolver: zodResolver(SSHKnownHostsSchema),\n\t\tdefaultValues: {\n\t\t\tknown_hosts: data?.known_hosts || '',\n\t\t},\n\t});\n\tconst { mutate: setSSHKnownHosts, isPending } = useSetSSHKnownHosts();\n\n\tconst onSubmitClick = useCallback(\n\t\tasync (formData: z.infer<typeof SSHKnownHostsSchema>) => {\n\t\t\tconst { known_hosts } = formData;\n\t\t\tif (known_hosts) {\n\t\t\t\tsetSSHKnownHosts(\n\t\t\t\t\t{\n\t\t\t\t\t\tknown_hosts: known_hosts.trim() + '\\n',\n\t\t\t\t\t\t...instanceParams,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tonSuccess: () => {\n\t\t\t\t\t\t\tform.reset(formData);\n\t\t\t\t\t\t\ttoast.success('Known hosts saved!');\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\t[setSSHKnownHosts, form, instanceParams],\n\t);\n\n\treturn (\n\t\t<Form {...form}>\n\t\t\t<form\n\t\t\t\tid=\"instance-edit-known-hosts-form\"\n\t\t\t\tname=\"instance-edit-known-hosts-form\"\n\t\t\t\tonSubmit={form.handleSubmit(onSubmitClick)}\n\t\t\t\tclassName=\"grid my-4 md:grid-cols-2 overflow-x-auto rounded-md\"\n\t\t\t>\n\t\t\t\t<FormField\n\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\tname=\"known_hosts\"\n\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t<FormItem className=\"md:col-span-2 gap-0\">\n\t\t\t\t\t\t\t<FormLabel className=\"bg-muted dark:bg-black-dark py-3 px-2 m-0 text-left font-medium whitespace-nowrap\">\n\t\t\t\t\t\t\t\tKnown Hosts\n\t\t\t\t\t\t\t</FormLabel>\n\t\t\t\t\t\t\t<div className=\"border border-grey-700 p-2 pb-3\">\n\t\t\t\t\t\t\t\t<FormDescription className=\"pb-2\">\n\t\t\t\t\t\t\t\t\tManage your known hosts here. When you add a SSH Key with a hostname of \"github.com\", we'll\n\t\t\t\t\t\t\t\t\tautomatically attempt to resolve GitHub's known hosts for you.\n\t\t\t\t\t\t\t\t</FormDescription>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Textarea\n\t\t\t\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"off\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"whitespace-nowrap\"\n\t\t\t\t\t\t\t\t\t\trows={10}\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\t\t\t\tvariant=\"submit\"\n\t\t\t\t\t\t\t\t\tclassName=\"rounded-full mt-2\"\n\t\t\t\t\t\t\t\t\tdisabled={isPending || !form.formState.isDirty || !form.formState.isValid}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Save /> {isPending ? 'Saving' : 'Save'} Known Hosts{isPending ? '...' : ''}\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t)}\n\t\t\t\t/>\n\t\t\t</form>\n\t\t</Form>\n\t);\n}\n","import { InstanceClientIdConfig, InstanceTypeConfig } from '@/config/instanceClientConfig';\nimport { ReplicatedResponse } from '@/integrations/api/replication';\nimport { useMutation } from '@tanstack/react-query';\nimport { z } from 'zod';\n\nexport const SSHKeySchema = z.object({\n\tname: z\n\t\t.string()\n\t\t.trim()\n\t\t.min(1)\n\t\t.regex(/^[a-zA-Z0-9-_]*$/, { error: 'Can only contain letters, numbers, dashes and underscores.' }),\n\tkey: z.string().min(1).trim(),\n\thost: z.string().min(1).trim(),\n\thostname: z.string().min(1).trim(),\n\tknown_hosts: z.string().trim().optional(),\n});\n\ntype AddSSHKeyFormData = z.infer<typeof SSHKeySchema> & InstanceClientIdConfig & InstanceTypeConfig;\n\nasync function addSSHKey(formData: AddSSHKeyFormData) {\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\tconst { instanceClient, entityType, entityId, ...sshKey } = formData;\n\tconst { data } = await instanceClient.post<ReplicatedResponse>('/', {\n\t\toperation: 'add_ssh_key',\n\t\treplicated: entityType === 'cluster',\n\t\t...sshKey,\n\t});\n\treturn data;\n}\n\nexport function useAddSSHKey() {\n\treturn useMutation({\n\t\tmutationFn: addSSHKey,\n\t});\n}\n","import { Button } from '@/components/ui/button';\nimport {\n\tDialog,\n\tDialogContent,\n\tDialogDescription,\n\tDialogFooter,\n\tDialogHeader,\n\tDialogTitle,\n} from '@/components/ui/dialog';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormDescription } from '@/components/ui/form/FormDescription';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { Textarea } from '@/components/ui/textarea';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { SSHKeySchema, useAddSSHKey } from '@/integrations/api/instance/ssh/addSSHKey';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { Save } from 'lucide-react';\nimport { useCallback } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\n\nexport function AddSSHKeyModal({\n\tisModalOpen,\n\tonChangesSaved,\n\tsetIsModalOpen,\n}: {\n\tisModalOpen: boolean;\n\tonChangesSaved: () => void;\n\tsetIsModalOpen: (open: boolean) => void;\n}) {\n\tconst form = useForm({\n\t\tresolver: zodResolver(SSHKeySchema),\n\t\tdefaultValues: {\n\t\t\tname: '',\n\t\t\tkey: '',\n\t\t\thost: '',\n\t\t\thostname: '',\n\t\t\tknown_hosts: '',\n\t\t},\n\t});\n\tconst instanceParams = useInstanceClientIdParams();\n\tconst { mutate: addSSHKey, isPending } = useAddSSHKey();\n\n\tconst onSubmitClick = useCallback(\n\t\tasync (formData: z.infer<typeof SSHKeySchema>) => {\n\t\t\tif (formData) {\n\t\t\t\tconst { name, key, host, hostname, known_hosts } = formData;\n\t\t\t\taddSSHKey(\n\t\t\t\t\t{\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tkey: key.trim() + '\\n',\n\t\t\t\t\t\thost,\n\t\t\t\t\t\thostname,\n\t\t\t\t\t\tknown_hosts: known_hosts || undefined,\n\t\t\t\t\t\t...instanceParams,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tonSuccess: () => {\n\t\t\t\t\t\t\tform.reset();\n\t\t\t\t\t\t\tonChangesSaved();\n\t\t\t\t\t\t\ttoast.success('SSH Key added successfully!');\n\t\t\t\t\t\t\tsetIsModalOpen(false);\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\t[addSSHKey, form, instanceParams, onChangesSaved, setIsModalOpen],\n\t);\n\n\tconst onClickCancel = useCallback(() => {\n\t\tform.reset();\n\t\tsetIsModalOpen(false);\n\t}, [form, setIsModalOpen]);\n\n\treturn (\n\t\t<Dialog onOpenChange={setIsModalOpen} open={isModalOpen}>\n\t\t\t<DialogContent aria-describedby={undefined}>\n\t\t\t\t<Form {...form}>\n\t\t\t\t\t<form\n\t\t\t\t\t\tid=\"instance-add-ssh-key-form\"\n\t\t\t\t\t\tname=\"instance-add-ssh-key-form\"\n\t\t\t\t\t\tonSubmit={form.handleSubmit(onSubmitClick)}\n\t\t\t\t\t\tclassName=\"grid gap-4 my-4 md:grid-cols-2\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<DialogHeader className=\"md:col-span-2\">\n\t\t\t\t\t\t\t<DialogTitle>Add New SSH Key</DialogTitle>\n\t\t\t\t\t\t\t<DialogDescription>\n\t\t\t\t\t\t\t\tEnter the details of your SSH Key below.\n\t\t\t\t\t\t\t</DialogDescription>\n\t\t\t\t\t\t</DialogHeader>\n\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"name\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem className=\"md:col-span-2\">\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Name</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"off\"\n\t\t\t\t\t\t\t\t\t\t\tautoFocus={true}\n\t\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"key\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem className=\"md:col-span-2\">\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Key</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormDescription>\n\t\t\t\t\t\t\t\t\t\tYour private key. Don't have one? Try out \"ssh-keygen\"! You'll want to add your public key to your\n\t\t\t\t\t\t\t\t\t\tregistry, i.e. GitHub.\n\t\t\t\t\t\t\t\t\t</FormDescription>\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Textarea\n\t\t\t\t\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"off\"\n\t\t\t\t\t\t\t\t\t\t\trows={3}\n\t\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"host\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem className=\"md:col-span-2\">\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Host</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormDescription>\n\t\t\t\t\t\t\t\t\t\tA unique identifying name for the combination of this key and your hostname, i.e.\n\t\t\t\t\t\t\t\t\t\t\"your-repo.github.com\". You will use this instead of the direct hostname to pick your key when\n\t\t\t\t\t\t\t\t\t\timporting applications.\n\t\t\t\t\t\t\t\t\t</FormDescription>\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"off\"\n\t\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"hostname\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem className=\"md:col-span-2\">\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Hostname</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormDescription>\n\t\t\t\t\t\t\t\t\t\tWhen making the request, the actual hostname to use, i.e. \"github.com\".\n\t\t\t\t\t\t\t\t\t</FormDescription>\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"off\"\n\t\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"known_hosts\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem className=\"md:col-span-2\">\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Known Hosts</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormDescription>\n\t\t\t\t\t\t\t\t\t\tOptionally, append known hosts, one per line. GitHub known hosts should resolve automatically.\n\t\t\t\t\t\t\t\t\t</FormDescription>\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Textarea\n\t\t\t\t\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"off\"\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"whitespace-nowrap\"\n\t\t\t\t\t\t\t\t\t\t\trows={3}\n\t\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t<DialogFooter className=\"md:col-span-2\">\n\t\t\t\t\t\t\t<div className=\"flex justify-between w-full\">\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tvariant=\"destructiveOutline\"\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\t\t\tonClick={onClickCancel}\n\t\t\t\t\t\t\t\t\tdisabled={isPending}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\t\t\t\tvariant=\"submit\"\n\t\t\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\t\t\tdisabled={isPending || !form.formState.isDirty || !form.formState.isValid}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Save /> Add SSH Key\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</DialogFooter>\n\t\t\t\t\t</form>\n\t\t\t\t</Form>\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n}\n","import { InstanceClientConfig, InstanceTypeConfig } from '@/config/instanceClientConfig';\nimport { ReplicatedResponse } from '@/integrations/api/replication';\nimport { useMutation } from '@tanstack/react-query';\n\ninterface DeleteSSHKeyFormData extends InstanceClientConfig, InstanceTypeConfig {\n\tname: string;\n}\n\nasync function deleteSSHKey(formData: DeleteSSHKeyFormData) {\n\tconst { instanceClient, entityType, name } = formData;\n\tconst { data } = await instanceClient.post<ReplicatedResponse>('/', {\n\t\toperation: 'delete_ssh_key',\n\t\treplicated: entityType === 'cluster',\n\t\tname,\n\t});\n\treturn data;\n}\n\nexport function useDeleteSSHKey() {\n\treturn useMutation({\n\t\tmutationFn: deleteSSHKey,\n\t});\n}\n","import { InstanceClientIdConfig } from '@/config/instanceClientConfig';\nimport { queryOptions } from '@tanstack/react-query';\n\ninterface GetSSHKeyFormData extends InstanceClientIdConfig {\n\tname: string;\n}\n\ninterface SSHKey {\n\tname: string;\n\tkey: unknown;\n\thost?: string;\n\thostname?: string;\n}\n\nasync function getSSHKey({ name, instanceClient }: GetSSHKeyFormData) {\n\tconst { data } = await instanceClient.post<SSHKey>('/', {\n\t\toperation: 'get_ssh_key',\n\t\tname,\n\t});\n\treturn data;\n}\n\nexport function getSSHKeyQueryOptions(params: GetSSHKeyFormData) {\n\treturn queryOptions({\n\t\tqueryKey: [params.entityId, 'get_ssh_key'] as const,\n\t\tqueryFn: () => getSSHKey(params),\n\t\trefetchInterval: 10_000,\n\t});\n}\n","import { InstanceClientConfig, InstanceTypeConfig } from '@/config/instanceClientConfig';\nimport { ReplicatedResponse } from '@/integrations/api/replication';\nimport { useMutation } from '@tanstack/react-query';\nimport { z } from 'zod';\n\nexport const UpdateSSHKeySchema = z.object({\n\tname: z.string().trim(),\n\tkey: z.string().min(1).trim(),\n});\n\ntype UpdateSSHKeyFormData = z.infer<typeof UpdateSSHKeySchema> & InstanceClientConfig & InstanceTypeConfig;\n\nasync function updateSSHKey(formData: UpdateSSHKeyFormData) {\n\tconst { instanceClient, entityType, name, key } = formData;\n\tconst { data } = await instanceClient.post<ReplicatedResponse>('/', {\n\t\toperation: 'update_ssh_key',\n\t\treplicated: entityType === 'cluster',\n\t\tname,\n\t\tkey,\n\t});\n\treturn data;\n}\n\nexport function useUpdateSSHKey() {\n\treturn useMutation({\n\t\tmutationFn: updateSSHKey,\n\t});\n}\n","import { Button } from '@/components/ui/button';\nimport { Dialog, DialogContent, DialogFooter, DialogTitle } from '@/components/ui/dialog';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormDescription } from '@/components/ui/form/FormDescription';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { Textarea } from '@/components/ui/textarea';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { useDeleteSSHKey } from '@/integrations/api/instance/ssh/deleteSSHKey';\nimport { getSSHKeyQueryOptions } from '@/integrations/api/instance/ssh/getSSHKey';\nimport { SSHKeyName } from '@/integrations/api/instance/ssh/listSSHKeys';\nimport { UpdateSSHKeySchema, useUpdateSSHKey } from '@/integrations/api/instance/ssh/updateSSHKey';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useQuery } from '@tanstack/react-query';\nimport { Row } from '@tanstack/react-table';\nimport { useCallback } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\n\nexport function EditSSHKeyModal({\n\tdata,\n\tisModalOpen,\n\tcloseModal,\n\tonSelectSSHKey,\n\tonChangesSaved,\n}: {\n\tdata: SSHKeyName;\n\tisModalOpen: boolean;\n\tcloseModal: () => void;\n\tonSelectSSHKey: (row?: Row<SSHKeyName>) => void;\n\tonChangesSaved: () => void;\n}) {\n\tconst { name } = data;\n\n\tconst form = useForm({\n\t\tresolver: zodResolver(UpdateSSHKeySchema),\n\t\tdefaultValues: {\n\t\t\tname,\n\t\t\tkey: '',\n\t\t},\n\t});\n\n\tconst instanceParams = useInstanceClientIdParams();\n\n\tconst { data: fullData } = useQuery(getSSHKeyQueryOptions({\n\t\t...instanceParams,\n\t\tname,\n\t}));\n\n\tconst { mutate: updateSSHKey, isPending } = useUpdateSSHKey();\n\tconst { mutate: deleteSSHKey } = useDeleteSSHKey();\n\n\tconst onSubmitClick = useCallback(\n\t\tasync ({ key }: z.infer<typeof UpdateSSHKeySchema>) => {\n\t\t\tif (key) {\n\t\t\t\tupdateSSHKey(\n\t\t\t\t\t{\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tkey: key.trim() + '\\n',\n\t\t\t\t\t\t...instanceParams,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tonSuccess: () => {\n\t\t\t\t\t\t\ttoast.success('SSH Key updated successfully!');\n\t\t\t\t\t\t\tonSelectSSHKey(undefined);\n\t\t\t\t\t\t\tonChangesSaved();\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\t[updateSSHKey, name, instanceParams, onSelectSSHKey, onChangesSaved],\n\t);\n\n\tconst onSSHKeyDeleteClicked = useCallback(() => {\n\t\tdeleteSSHKey(\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\t...instanceParams,\n\t\t\t},\n\t\t\t{\n\t\t\t\tonSuccess: () => {\n\t\t\t\t\ttoast.success('SSH Key deleted successfully!');\n\t\t\t\t\tonSelectSSHKey(undefined);\n\t\t\t\t\tonChangesSaved();\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t}, [name, deleteSSHKey, instanceParams, onChangesSaved, onSelectSSHKey]);\n\n\treturn (\n\t\t<Dialog onOpenChange={closeModal} open={isModalOpen}>\n\t\t\t<DialogContent className=\"sm:max-w-[750px]\" aria-describedby={undefined}>\n\t\t\t\t<Form {...form}>\n\t\t\t\t\t<form\n\t\t\t\t\t\tid=\"instance-edit-ssh-key-form\"\n\t\t\t\t\t\tname=\"instance-edit-ssh-key-form\"\n\t\t\t\t\t\tonSubmit={form.handleSubmit(onSubmitClick)}\n\t\t\t\t\t\tclassName=\"grid gap-4 my-4 md:grid-cols-2\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<DialogTitle>Edit SSH Key</DialogTitle>\n\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"name\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem className=\"md:col-span-2\">\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Name</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"off\"\n\t\t\t\t\t\t\t\t\t\t\treadOnly={true}\n\t\t\t\t\t\t\t\t\t\t\tdisabled={true}\n\t\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"key\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem className=\"md:col-span-2\">\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Key</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormDescription>\n\t\t\t\t\t\t\t\t\t\tReplace your existing private key. Lost it? Try out \"ssh-keygen\"! You'll want to add your public key\n\t\t\t\t\t\t\t\t\t\tto your registry, i.e. GitHub.\n\t\t\t\t\t\t\t\t\t</FormDescription>\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Textarea\n\t\t\t\t\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"off\"\n\t\t\t\t\t\t\t\t\t\t\tautoFocus={true}\n\t\t\t\t\t\t\t\t\t\t\trows={3}\n\t\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t<FormItem className=\"md:col-span-2\">\n\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Host</FormLabel>\n\t\t\t\t\t\t\t<FormDescription>\n\t\t\t\t\t\t\t\tA unique identifying name for the combination of this key and your hostname, i.e.\n\t\t\t\t\t\t\t\t\"your-repo.github.com\". You will use this instead of the direct hostname to pick your key when importing\n\t\t\t\t\t\t\t\tapplications.\n\t\t\t\t\t\t\t</FormDescription>\n\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\t\t\tautoCapitalize=\"off\"\n\t\t\t\t\t\t\t\t\tvalue={fullData?.host || ''}\n\t\t\t\t\t\t\t\t\tdisabled={true}\n\t\t\t\t\t\t\t\t\treadOnly={true}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t</FormItem>\n\n\t\t\t\t\t\t<FormItem className=\"md:col-span-2\">\n\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Hostname</FormLabel>\n\t\t\t\t\t\t\t<FormDescription>\n\t\t\t\t\t\t\t\tWhen making the request, the actual hostname to use, i.e. \"github.com\".\n\t\t\t\t\t\t\t</FormDescription>\n\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\t\t\tautoCapitalize=\"off\"\n\t\t\t\t\t\t\t\t\tvalue={fullData?.hostname || ''}\n\t\t\t\t\t\t\t\t\tdisabled={true}\n\t\t\t\t\t\t\t\t\treadOnly={true}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t</FormItem>\n\n\t\t\t\t\t\t<DialogFooter>\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tvariant=\"destructiveOutline\"\n\t\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\t\tonClick={onSSHKeyDeleteClicked}\n\t\t\t\t\t\t\t\tdisabled={isPending}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tDelete SSH Key\n\t\t\t\t\t\t\t</Button>\n\n\t\t\t\t\t\t\t<div className=\"grow\" />\n\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\t\t\tvariant=\"submit\"\n\t\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\t\tdisabled={isPending || !form.formState.isValid}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tUpdate SSH Key\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t</DialogFooter>\n\t\t\t\t\t</form>\n\t\t\t\t</Form>\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n}\n","import { Loading } from '@/components/Loading';\nimport { SimpleBrowseDataTable } from '@/components/SimpleBrowseDataTable';\nimport { Button } from '@/components/ui/button';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { useRefreshClick } from '@/hooks/useRefreshClick';\nimport { listSSHKeysQueryOptions, SSHKeyName } from '@/integrations/api/instance/ssh/listSSHKeys';\nimport { useQuery } from '@tanstack/react-query';\nimport { Link, useNavigate, useParams } from '@tanstack/react-router';\nimport { Row } from '@tanstack/react-table';\nimport { PlusIcon, RefreshCwIcon } from 'lucide-react';\nimport { Suspense, useCallback, useMemo, useState } from 'react';\nimport { dataTableColumns } from './constants/tableDefinition';\nimport { KnownHosts } from './KnownHosts';\nimport { AddSSHKeyModal } from './modals/AddSSHKeyModal';\nimport { EditSSHKeyModal } from './modals/EditSSHKeyModal';\n\nexport function ConfigSSHKeysIndex() {\n\tconst navigate = useNavigate();\n\tconst { keyName }: { keyName?: string } = useParams({ strict: false });\n\tconst instanceParams = useInstanceClientIdParams();\n\tconst {\n\t\tdata: localSSHKeys,\n\t\trefetch,\n\t\tisFetching,\n\t\tisRefetching,\n\t} = useQuery(listSSHKeysQueryOptions(instanceParams));\n\n\tconst selectedSSHKey = useMemo(() => localSSHKeys?.find((role) => role.name === keyName), [localSSHKeys, keyName]);\n\n\tconst onSelectSSHKey = useCallback(\n\t\t(row?: Row<SSHKeyName>) => {\n\t\t\tconst newKeyName = row?.original?.name;\n\t\t\tconst parts = [keyName ? '..' : '', newKeyName].filter(Boolean);\n\t\t\tvoid navigate({ to: parts.join('/') });\n\t\t},\n\t\t[keyName, navigate],\n\t);\n\n\tconst isEditModalOpen = !!keyName && !!selectedSSHKey;\n\n\tconst [isAddModalOpen, setIsAddModalOpen] = useState(false);\n\n\tconst onAddClicked = useCallback(() => {\n\t\tsetIsAddModalOpen(true);\n\t}, [setIsAddModalOpen]);\n\n\tconst onRefreshClick = useRefreshClick(refetch);\n\n\treturn (\n\t\t<>\n\t\t\t<SimpleBrowseDataTable\n\t\t\t\tcolumns={dataTableColumns}\n\t\t\t\tdata={localSSHKeys || []}\n\t\t\t\tisFetching={isFetching}\n\t\t\t\tonRowClick={onSelectSSHKey}\n\t\t\t>\n\t\t\t\t<Link\n\t\t\t\t\tclassName=\"inline-block underline text-sm text-muted-foreground hover:text-foreground\"\n\t\t\t\t\tto=\"https://docs.harperdb.io/docs/developers/security/certificate-management\"\n\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t>\n\t\t\t\t\tCertificate Management Docs\n\t\t\t\t</Link>\n\t\t\t\t<Button variant=\"defaultOutline\" onClick={onRefreshClick} accessKey=\"r\" disabled={isFetching || isRefetching}>\n\t\t\t\t\t<RefreshCwIcon />\n\t\t\t\t\t<span className=\"hidden lg:inline-block\">\n\t\t\t\t\t\t<u>R</u>efresh\n\t\t\t\t\t</span>\n\t\t\t\t</Button>\n\t\t\t\t<Button variant=\"positiveOutline\" onClick={onAddClicked} accessKey=\"a\" disabled={isAddModalOpen}>\n\t\t\t\t\t<PlusIcon />\n\t\t\t\t\t<span>\n\t\t\t\t\t\t<u>A</u>dd\n\t\t\t\t\t</span>\n\t\t\t\t</Button>\n\t\t\t</SimpleBrowseDataTable>\n\t\t\t{isAddModalOpen && (\n\t\t\t\t<AddSSHKeyModal isModalOpen={isAddModalOpen} onChangesSaved={refetch} setIsModalOpen={setIsAddModalOpen} />\n\t\t\t)}\n\t\t\t{isEditModalOpen && (\n\t\t\t\t<EditSSHKeyModal\n\t\t\t\t\tisModalOpen={isEditModalOpen}\n\t\t\t\t\tcloseModal={onSelectSSHKey}\n\t\t\t\t\tdata={selectedSSHKey}\n\t\t\t\t\tonSelectSSHKey={onSelectSSHKey}\n\t\t\t\t\tonChangesSaved={refetch}\n\t\t\t\t/>\n\t\t\t)}\n\t\t\t<Suspense fallback={<Loading text=\"Loading...\" />}>\n\t\t\t\t<KnownHosts />\n\t\t\t</Suspense>\n\t\t</>\n\t);\n}\n","import { LocalUser } from '@/integrations/api/api.patch';\nimport { translateSecondsToAgo } from '@/lib/translateSecondsToAgo';\nimport { ColumnDef, createColumnHelper } from '@tanstack/react-table';\n\nconst columnHelper = createColumnHelper<LocalUser>();\n\nexport const dataTableColumns: Array<ColumnDef<LocalUser>> = [\n\t{\n\t\theader: 'Username',\n\t\taccessorKey: 'username',\n\t\tenableSorting: false,\n\t},\n\tcolumnHelper.display({\n\t\theader: 'Role',\n\t\tenableSorting: false,\n\t\tid: 'role',\n\t\tcell: (props) => props.row.original.role.role,\n\t}),\n\t{\n\t\theader: 'Active',\n\t\taccessorKey: 'active',\n\t\tenableSorting: false,\n\t},\n\tcolumnHelper.display({\n\t\theader: 'Created',\n\t\tenableSorting: false,\n\t\tid: '__createdtime__',\n\t\tcell: (props) =>\n\t\t\ttranslateSecondsToAgo(\n\t\t\t\t(Date.now() - props.row.original.__createdtime__) / 1000,\n\t\t\t\tprops.row.original.__createdtime__,\n\t\t\t),\n\t}),\n\t{\n\t\theader: 'Updated',\n\t\taccessorKey: '__updatedtime__',\n\t\tenableSorting: false,\n\t\tcell: (props) =>\n\t\t\ttranslateSecondsToAgo(\n\t\t\t\t(Date.now() - props.row.original.__updatedtime__) / 1000,\n\t\t\t\tprops.row.original.__updatedtime__,\n\t\t\t),\n\t},\n];\n","import { TextLoadingSkeleton } from '@/components/TextLoadingSkeleton';\nimport { Button } from '@/components/ui/button';\nimport { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport {\n\tSelect,\n\tSelectContent,\n\tSelectGroup,\n\tSelectItem,\n\tSelectLabel,\n\tSelectTrigger,\n\tSelectValue,\n} from '@/components/ui/select';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { useAddUserMutation } from '@/integrations/api/instance/auth/addUser';\nimport { AddUserFormSchema } from '@/integrations/api/instance/auth/addUserFormSchema';\nimport { getListRolesQueryOptions } from '@/integrations/api/instance/auth/getListRoles';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useSuspenseQuery } from '@tanstack/react-query';\nimport { Save } from 'lucide-react';\nimport { Suspense, useCallback } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\n\nexport function AddUserModal({\n\tisModalOpen,\n\tonChangesSaved,\n\tsetIsModalOpen,\n}: {\n\tisModalOpen: boolean;\n\tonChangesSaved: () => void;\n\tsetIsModalOpen: (open: boolean) => void;\n}) {\n\tconst instanceParams = useInstanceClientIdParams();\n\tconst { data: roles } = useSuspenseQuery(getListRolesQueryOptions(instanceParams));\n\tconst form = useForm({\n\t\tresolver: zodResolver(AddUserFormSchema),\n\t\tdefaultValues: {\n\t\t\tusername: '',\n\t\t\trole: '',\n\t\t\tpassword: '',\n\t\t\tconfirmPassword: '',\n\t\t},\n\t});\n\tconst { mutate: addUser, isPending: isAddPending } = useAddUserMutation();\n\n\tconst onSubmitClick = useCallback(async (formData: z.infer<typeof AddUserFormSchema>) => {\n\t\tif (formData) {\n\t\t\taddUser(\n\t\t\t\t{\n\t\t\t\t\tactive: true,\n\t\t\t\t\tpassword: formData.password,\n\t\t\t\t\trole: formData.role,\n\t\t\t\t\tusername: formData.username,\n\t\t\t\t\t...instanceParams,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tonSuccess: () => {\n\t\t\t\t\t\tconst lastRole = formData.role;\n\t\t\t\t\t\tform.reset();\n\t\t\t\t\t\t// Persist the selected role if they open the form again.\n\t\t\t\t\t\tform.setValue('role', lastRole);\n\t\t\t\t\t\tonChangesSaved();\n\t\t\t\t\t\ttoast.success('User added successfully!');\n\t\t\t\t\t\tsetIsModalOpen(false);\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}, [addUser, form, instanceParams, onChangesSaved, setIsModalOpen]);\n\n\treturn (\n\t\t<Dialog onOpenChange={setIsModalOpen} open={isModalOpen}>\n\t\t\t{/* NOTE - Is this okay to do for the aria describedby? */}\n\t\t\t<DialogContent aria-describedby={undefined}>\n\t\t\t\t<Form {...form}>\n\t\t\t\t\t<form\n\t\t\t\t\t\tid=\"instance-add-user-form\"\n\t\t\t\t\t\tname=\"instance-add-user-form\"\n\t\t\t\t\t\tonSubmit={form.handleSubmit(onSubmitClick)}\n\t\t\t\t\t\tclassName=\"grid gap-4 my-4\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<DialogHeader>\n\t\t\t\t\t\t\t<DialogTitle>Add New User</DialogTitle>\n\t\t\t\t\t\t</DialogHeader>\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"username\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Username</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\t\tenterKeyHint=\"next\"\n\t\t\t\t\t\t\t\t\t\t\tautoComplete=\"username\"\n\t\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"password\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Password</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\t\t\t\t\t\tenterKeyHint=\"next\"\n\t\t\t\t\t\t\t\t\t\t\tautoComplete=\"new-password\"\n\t\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"confirmPassword\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Confirm Password</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\t\t\t\t\t\tenterKeyHint=\"next\"\n\t\t\t\t\t\t\t\t\t\t\tautoComplete=\"new-password\"\n\t\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"role\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Role</FormLabel>\n\n\t\t\t\t\t\t\t\t\t<Suspense fallback={<TextLoadingSkeleton />}>\n\t\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t\t<Select {...field} onValueChange={(role) => field.onChange(role)}>\n\t\t\t\t\t\t\t\t\t\t\t\t<SelectTrigger className=\"w-full\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<SelectValue placeholder=\"Choose Role\" />\n\t\t\t\t\t\t\t\t\t\t\t\t</SelectTrigger>\n\t\t\t\t\t\t\t\t\t\t\t\t<SelectContent>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<SelectGroup>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<SelectLabel>Role</SelectLabel>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{roles?.map((role) => (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<SelectItem\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tkey={role.id}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tvalue={role.id}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{role.role}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</SelectItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</SelectGroup>\n\t\t\t\t\t\t\t\t\t\t\t\t</SelectContent>\n\t\t\t\t\t\t\t\t\t\t\t</Select>\n\t\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t</Suspense>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t<DialogFooter>\n\t\t\t\t\t\t\t<div className=\"flex justify-between w-full\">\n\t\t\t\t\t\t\t\t<Button type=\"submit\" variant=\"submit\" className=\"rounded-full\" disabled={isAddPending}>\n\t\t\t\t\t\t\t\t\t<Save /> Add User\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</DialogFooter>\n\t\t\t\t\t</form>\n\t\t\t\t</Form>\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n}\n","import { AddUserFormSchema } from '@/integrations/api/instance/auth/addUserFormSchema';\nimport { z } from 'zod';\n\nexport const AlterUserFormSchema = z.object({\n\tusername: AddUserFormSchema.shape.username,\n\trole: AddUserFormSchema.shape.role,\n\tnewPassword: AddUserFormSchema.shape.password.or(z.literal('')).optional(),\n\tconfirmPassword: AddUserFormSchema.shape.confirmPassword,\n})\n\t.refine((data) => !data.newPassword || data.newPassword.length >= 8, {\n\t\terror: 'Password must be at least 8 characters long.',\n\t\tpath: ['password'],\n\t})\n\t.refine((data) => !data.newPassword || data.newPassword === data.confirmPassword, {\n\t\terror: 'Passwords do not match.',\n\t\tpath: ['confirmPassword'],\n\t});\n","import { TextLoadingSkeleton } from '@/components/TextLoadingSkeleton';\nimport { Button } from '@/components/ui/button';\nimport { DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport {\n\tSelect,\n\tSelectContent,\n\tSelectGroup,\n\tSelectItem,\n\tSelectLabel,\n\tSelectTrigger,\n\tSelectValue,\n} from '@/components/ui/select';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { LocalUser } from '@/integrations/api/api.patch';\nimport { AlterUserRequestBody, useAlterUser } from '@/integrations/api/instance/auth/alterUser';\nimport { AlterUserFormSchema } from '@/integrations/api/instance/auth/alterUserFormSchema';\nimport { getListRolesQueryOptions } from '@/integrations/api/instance/auth/getListRoles';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useSuspenseQuery } from '@tanstack/react-query';\nimport { Save } from 'lucide-react';\nimport { Suspense, useCallback } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\n\nexport function AlterUserForm({\n\tdata,\n\tonUserUpdated,\n}: {\n\tdata: LocalUser;\n\tonUserUpdated: () => void;\n}) {\n\tconst instanceParams = useInstanceClientIdParams();\n\tconst { data: roles } = useSuspenseQuery(getListRolesQueryOptions(instanceParams));\n\tconst { mutate: alterUser, isPending: isUpdateUserPending } = useAlterUser();\n\tconst alterForm = useForm({\n\t\tresolver: zodResolver(AlterUserFormSchema),\n\t\tdefaultValues: {\n\t\t\tusername: data.username,\n\t\t\trole: data.role.role,\n\t\t\tnewPassword: '',\n\t\t\tconfirmPassword: '',\n\t\t},\n\t});\n\n\tconst onSubmitClick = useCallback((formData: z.infer<typeof AlterUserFormSchema>) => {\n\t\tconst alterBody: AlterUserRequestBody = {\n\t\t\tusername: data.username,\n\t\t\trole: formData.role,\n\t\t\t...instanceParams,\n\t\t};\n\t\tif (formData.newPassword) {\n\t\t\talterBody.password = formData.newPassword;\n\t\t}\n\t\talterUser(\n\t\t\talterBody,\n\t\t\t{\n\t\t\t\tonSuccess: () => {\n\t\t\t\t\talterForm.reset();\n\t\t\t\t\ttoast.success('User edited successfully!');\n\t\t\t\t\tonUserUpdated();\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t}, [alterForm, alterUser, data.username, instanceParams, onUserUpdated]);\n\n\treturn (\n\t\t<Form {...alterForm}>\n\t\t\t<form\n\t\t\t\tid=\"instance-edit-user-form\"\n\t\t\t\tname=\"instance-edit-user-form\"\n\t\t\t\tonSubmit={alterForm.handleSubmit(onSubmitClick)}\n\t\t\t\tclassName=\"grid gap-4 my-4\"\n\t\t\t>\n\t\t\t\t<DialogHeader>\n\t\t\t\t\t<DialogTitle>Edit User</DialogTitle>\n\t\t\t\t</DialogHeader>\n\n\t\t\t\t<FormField\n\t\t\t\t\tcontrol={alterForm.control}\n\t\t\t\t\tname=\"username\"\n\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Username</FormLabel>\n\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\tenterKeyHint=\"next\"\n\t\t\t\t\t\t\t\t\tautoComplete=\"username\"\n\t\t\t\t\t\t\t\t\tdisabled={true}\n\t\t\t\t\t\t\t\t\treadOnly={true}\n\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t)}\n\t\t\t\t/>\n\n\t\t\t\t<FormField\n\t\t\t\t\tcontrol={alterForm.control}\n\t\t\t\t\tname=\"newPassword\"\n\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Change Password</FormLabel>\n\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\t\t\t\tenterKeyHint=\"next\"\n\t\t\t\t\t\t\t\t\tautoComplete=\"new-password\"\n\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t)}\n\t\t\t\t/>\n\t\t\t\t<FormField\n\t\t\t\t\tcontrol={alterForm.control}\n\t\t\t\t\tname=\"confirmPassword\"\n\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Confirm Password</FormLabel>\n\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\t\t\t\tenterKeyHint=\"next\"\n\t\t\t\t\t\t\t\t\tautoComplete=\"new-password\"\n\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t)}\n\t\t\t\t/>\n\n\t\t\t\t<FormField\n\t\t\t\t\tcontrol={alterForm.control}\n\t\t\t\t\tname=\"role\"\n\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Role</FormLabel>\n\n\t\t\t\t\t\t\t<Suspense fallback={<TextLoadingSkeleton />}>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Select {...field} onValueChange={(role) => field.onChange(role)}>\n\t\t\t\t\t\t\t\t\t\t<SelectTrigger className=\"w-full\">\n\t\t\t\t\t\t\t\t\t\t\t<SelectValue placeholder=\"Choose Role\" />\n\t\t\t\t\t\t\t\t\t\t</SelectTrigger>\n\t\t\t\t\t\t\t\t\t\t<SelectContent>\n\t\t\t\t\t\t\t\t\t\t\t<SelectGroup>\n\t\t\t\t\t\t\t\t\t\t\t\t<SelectLabel>Role</SelectLabel>\n\t\t\t\t\t\t\t\t\t\t\t\t{roles?.map((role) => (\n\t\t\t\t\t\t\t\t\t\t\t\t\t<SelectItem\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tkey={role.id}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tvalue={role.id}\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{role.role}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</SelectItem>\n\t\t\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t\t\t</SelectGroup>\n\t\t\t\t\t\t\t\t\t\t</SelectContent>\n\t\t\t\t\t\t\t\t\t</Select>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t</Suspense>\n\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t)}\n\t\t\t\t/>\n\n\t\t\t\t<DialogFooter>\n\t\t\t\t\t<div className=\"flex justify-between w-full\">\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tvariant=\"submit\"\n\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\tdisabled={isUpdateUserPending}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Save /> Save Changes\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</div>\n\t\t\t\t</DialogFooter>\n\t\t\t</form>\n\t\t</Form>\n\t);\n}\n","import { zodRequireUsername } from '@/lib/zod/username';\nimport { z } from 'zod';\n\nexport const DeleteUserFormSchema = z.object({\n\tusername: zodRequireUsername,\n\tconfirmUsernameForDeletion: z\n\t\t.string()\n\t\t.nonempty({\n\t\t\terror: 'Please type the username again to confirm deletion.',\n\t\t})\n\t\t.toLowerCase(),\n})\n\t.refine((data) => data.username === data.confirmUsernameForDeletion, {\n\t\terror: 'Username does not match.',\n\t\tpath: ['confirmUsernameForDeletion'], // This specifies where the error message should be attached\n\t});\n","import { Button } from '@/components/ui/button';\nimport { DialogFooter } from '@/components/ui/dialog';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { useInstanceClientParams } from '@/config/useInstanceClient';\nimport { LocalUser } from '@/integrations/api/api.patch';\nimport { useDeleteUserMutation } from '@/integrations/api/instance/auth/deleteUser';\nimport { DeleteUserFormSchema } from '@/integrations/api/instance/auth/deleteUserFormSchema';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { Trash } from 'lucide-react';\nimport { useCallback } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\n\nexport function DeleteUserForm({\n\tdata,\n\tonUserDeleted,\n}: {\n\tdata: LocalUser;\n\tonUserDeleted: () => void;\n}) {\n\tconst { mutate: deleteUser, isPending: isDeleteUserPending } = useDeleteUserMutation();\n\tconst deleteForm = useForm({\n\t\tresolver: zodResolver(DeleteUserFormSchema),\n\t\tdefaultValues: {\n\t\t\tusername: data.username,\n\t\t\tconfirmUsernameForDeletion: '',\n\t\t},\n\t});\n\n\tconst instanceParams = useInstanceClientParams();\n\tconst onDeleteClicked = useCallback(() => {\n\t\tdeleteUser(\n\t\t\t{\n\t\t\t\tusername: data.username,\n\t\t\t\t...instanceParams,\n\t\t\t},\n\t\t\t{\n\t\t\t\tonSuccess: () => {\n\t\t\t\t\tdeleteForm.reset();\n\t\t\t\t\ttoast.success('User deleted successfully!');\n\t\t\t\t\tonUserDeleted();\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t}, [data.username, deleteForm, deleteUser, instanceParams, onUserDeleted]);\n\n\treturn (\n\t\t<Form {...deleteForm}>\n\t\t\t<form\n\t\t\t\tid=\"instance-delete-user-form\"\n\t\t\t\tname=\"instance-delete-user-form\"\n\t\t\t\tonSubmit={deleteForm.handleSubmit(onDeleteClicked)}\n\t\t\t\tclassName=\"grid gap-4 my-4\"\n\t\t\t>\n\t\t\t\t<FormField\n\t\t\t\t\tcontrol={deleteForm.control}\n\t\t\t\t\tname=\"confirmUsernameForDeletion\"\n\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Confirm Username</FormLabel>\n\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\tenterKeyHint=\"next\"\n\t\t\t\t\t\t\t\t\tautoComplete=\"username\"\n\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t)}\n\t\t\t\t/>\n\n\t\t\t\t<DialogFooter>\n\t\t\t\t\t<div className=\"flex justify-between w-full\">\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tvariant=\"destructive\"\n\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\tdisabled={isDeleteUserPending || !deleteForm.formState.isValid}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Trash /> Delete User\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</div>\n\t\t\t\t</DialogFooter>\n\t\t\t</form>\n\t\t</Form>\n\t);\n}\n","import { Dialog, DialogContent } from '@/components/ui/dialog';\nimport { authStore } from '@/features/auth/store/authStore';\nimport { AlterUserForm } from '@/features/instance/config/users/components/AlterUserForm';\nimport { DeleteUserForm } from '@/features/instance/config/users/components/DeleteUserForm';\nimport { useInstanceAuth } from '@/hooks/useAuth';\nimport { LocalUser } from '@/integrations/api/api.patch';\n\nexport function EditUserModal({\n\tcloseModal,\n\tclusterId,\n\tinstanceId,\n\tdata,\n\tisModalOpen,\n\tonUserDeleted,\n\tonUserUpdated,\n}: {\n\tclusterId?: string;\n\tinstanceId?: string;\n\tisModalOpen: boolean;\n\tcloseModal: () => void;\n\tdata: LocalUser;\n\tonUserDeleted: () => void;\n\tonUserUpdated: () => void;\n}) {\n\tconst isFabricConnect = authStore.checkForFabricConnect(instanceId ?? clusterId);\n\tconst auth = useInstanceAuth(instanceId ?? clusterId);\n\tconst isSelf = !isFabricConnect && auth.user?.username === data.username;\n\tconst canDelete = !isSelf;\n\n\treturn (\n\t\t<Dialog onOpenChange={closeModal} open={isModalOpen}>\n\t\t\t<DialogContent className=\"sm:max-w-[750px]\">\n\t\t\t\t<AlterUserForm data={data} onUserUpdated={onUserUpdated} />\n\t\t\t\t{canDelete && <DeleteUserForm data={data} onUserDeleted={onUserDeleted} />}\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n}\n","import { InstanceClientConfig, InstanceClientIdConfig } from '@/config/instanceClientConfig';\nimport { LocalUser } from '@/integrations/api/api.patch';\nimport { queryOptions } from '@tanstack/react-query';\n\nexport function getListUsersQueryOptions({ entityId, instanceClient }: InstanceClientIdConfig) {\n\treturn queryOptions({\n\t\tqueryKey: [entityId, 'list_users'] as const,\n\t\tqueryFn: () => getListUsers({ instanceClient }),\n\t\trefetchInterval: 10_000,\n\t});\n}\n\nasync function getListUsers({ instanceClient }: InstanceClientConfig) {\n\tconst { data } = await instanceClient.post('/', {\n\t\toperation: 'list_users',\n\t});\n\treturn data as LocalUser[];\n}\n","import { Loading } from '@/components/Loading';\nimport { SimpleBrowseDataTable } from '@/components/SimpleBrowseDataTable';\nimport { Button } from '@/components/ui/button';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { dataTableColumns } from '@/features/instance/config/users/constants/tableDefinition';\nimport { AddUserModal } from '@/features/instance/config/users/modals/AddUserModal';\nimport { EditUserModal } from '@/features/instance/config/users/modals/EditUserModal';\nimport { useRefreshClick } from '@/hooks/useRefreshClick';\nimport { LocalUser } from '@/integrations/api/api.patch';\nimport { getListUsersQueryOptions } from '@/integrations/api/instance/auth/getListUsers';\nimport { useSuspenseQuery } from '@tanstack/react-query';\nimport { useNavigate, useParams } from '@tanstack/react-router';\nimport { Row } from '@tanstack/react-table';\nimport { PlusIcon, RefreshCwIcon } from 'lucide-react';\nimport { Suspense, useCallback, useMemo, useState } from 'react';\n\nexport function ConfigUsersIndex() {\n\tconst navigate = useNavigate();\n\tconst { instanceId, clusterId, username }: {\n\t\tinstanceId?: string;\n\t\tclusterId?: string;\n\t\tusername?: string;\n\t} = useParams({ strict: false });\n\tconst instanceParams = useInstanceClientIdParams();\n\tconst {\n\t\tdata: localUsers,\n\t\trefetch,\n\t\tisFetching,\n\t\tisRefetching,\n\t} = useSuspenseQuery(getListUsersQueryOptions(instanceParams));\n\tconst selectedUser = useMemo(\n\t\t() => localUsers?.find(user => user.username === username),\n\t\t[localUsers, username],\n\t);\n\n\tconst onSelectUser = useCallback((newUsername: string | undefined) => {\n\t\tconst parts = [username ? '..' : '', newUsername].filter(Boolean);\n\t\tvoid navigate({ to: parts.join('/') });\n\t}, [username, navigate]);\n\n\tconst isEditModalOpen = !!username && !!selectedUser;\n\n\tconst [isAddModalOpen, setIsAddModalOpen] = useState(false);\n\tconst [sortTableDataParams] = useState({\n\t\tattribute: 'username',\n\t\tdescending: false,\n\t});\n\tconst sortingState = useMemo(() => [{\n\t\tdesc: sortTableDataParams.descending,\n\t\tid: sortTableDataParams.attribute,\n\t}], [sortTableDataParams]);\n\n\tconst onAddClicked = useCallback(() => {\n\t\tsetIsAddModalOpen(true);\n\t}, [setIsAddModalOpen]);\n\tconst onUsedAdded = useCallback(() => {\n\t\tvoid refetch();\n\t\tsetIsAddModalOpen(false);\n\t}, [refetch, setIsAddModalOpen]);\n\n\tconst onRowClick = useCallback((rowData: Row<LocalUser>) => {\n\t\tonSelectUser(rowData.original.username);\n\t}, [onSelectUser]);\n\tconst closeEditModal = useCallback(() => {\n\t\tonSelectUser(undefined);\n\t}, [onSelectUser]);\n\n\tconst onUserUpdated = useCallback(() => {\n\t\tvoid refetch();\n\t\tonSelectUser(undefined);\n\t}, [onSelectUser, refetch]);\n\tconst onUserDeleted = useCallback(() => {\n\t\tvoid refetch();\n\t\tonSelectUser(undefined);\n\t}, [onSelectUser, refetch]);\n\n\tconst onRefreshClick = useRefreshClick(refetch);\n\n\treturn (\n\t\t<Suspense\n\t\t\tfallback={<Loading className=\"flex flex-col items-center justify-center h-full\" text=\"Loading...\" />}\n\t\t>\n\t\t\t<SimpleBrowseDataTable<LocalUser, unknown>\n\t\t\t\tdata={localUsers}\n\t\t\t\tisFetching={isFetching || isRefetching}\n\t\t\t\tcolumns={dataTableColumns}\n\t\t\t\tonRowClick={onRowClick}\n\t\t\t\tsortingState={sortingState}\n\t\t\t>\n\t\t\t\t{/*<UploadCSVModal />*/}\n\t\t\t\t{/*disabled={tableDataFetching}*/}\n\t\t\t\t<Button variant=\"defaultOutline\" onClick={onRefreshClick} accessKey=\"r\" disabled={isFetching || isRefetching}>\n\t\t\t\t\t<RefreshCwIcon />{' '}\n\t\t\t\t\t<span className=\"hidden lg:inline-block\">\n\t\t\t\t\t\t<u>R</u>efresh\n\t\t\t\t\t</span>\n\t\t\t\t</Button>\n\t\t\t\t{/*<Button variant=\"defaultOutline\" onClick={notYetImplemented}><SearchIcon /> <span*/}\n\t\t\t\t{/*\tclassName=\"hidden lg:inline-block\">Search</span></Button>*/}\n\t\t\t\t<Button variant=\"positiveOutline\" onClick={onAddClicked} accessKey=\"a\" disabled={isAddModalOpen}>\n\t\t\t\t\t<PlusIcon />{' '}\n\t\t\t\t\t<span>\n\t\t\t\t\t\t<u>A</u>dd\n\t\t\t\t\t</span>\n\t\t\t\t</Button>\n\t\t\t</SimpleBrowseDataTable>\n\t\t\t<AddUserModal\n\t\t\t\tisModalOpen={isAddModalOpen}\n\t\t\t\tonChangesSaved={onUsedAdded}\n\t\t\t\tsetIsModalOpen={setIsAddModalOpen}\n\t\t\t/>\n\t\t\t{isEditModalOpen && (\n\t\t\t\t<EditUserModal\n\t\t\t\t\tinstanceId={instanceId}\n\t\t\t\t\tclusterId={clusterId}\n\t\t\t\t\tcloseModal={closeEditModal}\n\t\t\t\t\tdata={selectedUser}\n\t\t\t\t\tisModalOpen={isEditModalOpen}\n\t\t\t\t\tonUserDeleted={onUserDeleted}\n\t\t\t\t\tonUserUpdated={onUserUpdated}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</Suspense>\n\t);\n}\n","import { getInstanceClientIdFromParams } from '@/config/useInstanceClient';\nimport { getRegistrationInfoQueryOptions } from '@/integrations/api/instance/status/getRegistrationInfo';\nimport { QueryClient } from '@tanstack/react-query';\n\nexport function registrationInfoLoader({\n\tcontext,\n\tparams,\n}: {\n\tcontext: { queryClient: QueryClient };\n\tparams: { organizationId?: string; clusterId?: string; instanceId?: string };\n}) {\n\tconst operationsParams = getInstanceClientIdFromParams(params);\n\treturn context.queryClient.ensureQueryData(getRegistrationInfoQueryOptions(operationsParams));\n}\n","import { ConfigCertificatesIndex } from '@/features/instance/config/certificates';\nimport { ConfigDomainsIndex } from '@/features/instance/config/domains';\nimport { ConfigIndex } from '@/features/instance/config/index';\nimport { ConfigOverviewIndex } from '@/features/instance/config/overview';\nimport { ConfigRolesIndex } from '@/features/instance/config/roles';\nimport { ConfigSSHKeysIndex } from '@/features/instance/config/sshKeys';\nimport { ConfigUsersIndex } from '@/features/instance/config/users';\nimport { createInstanceLayoutRoute } from '@/features/instance/instanceLayoutRoute';\nimport { registrationInfoLoader } from '@/features/instance/registrationInfoLoader';\nimport { createRoute } from '@tanstack/react-router';\n\nexport function createConfigRouteTree(instanceLayoutRoute: ReturnType<typeof createInstanceLayoutRoute>) {\n\tconst instanceConfigRoute = createRoute({\n\t\tgetParentRoute: () => instanceLayoutRoute,\n\t\tpath: 'config',\n\t\thead: () => ({ meta: [{ title: 'Config — Harper Fabric' }] }),\n\t\tcomponent: ConfigIndex,\n\t\tloader: registrationInfoLoader,\n\t});\n\tconst instanceOverviewRoute = createRoute({\n\t\tgetParentRoute: () => instanceConfigRoute,\n\t\tpath: '/',\n\t\thead: () => ({ meta: [{ title: 'Overview — Harper Fabric' }] }),\n\t\tcomponent: ConfigOverviewIndex,\n\t\tloader: registrationInfoLoader,\n\t});\n\n\tconst instanceConfigRolesRoute = createRoute({\n\t\tgetParentRoute: () => instanceConfigRoute,\n\t\tpath: 'roles',\n\t\thead: () => ({ meta: [{ title: 'Instance Roles — Harper Fabric' }] }),\n\t\tcomponent: ConfigRolesIndex,\n\t});\n\tconst instanceConfigRoleRoute = createRoute({\n\t\tgetParentRoute: () => instanceConfigRoute,\n\t\tpath: 'roles/$roleId',\n\t\thead: () => ({ meta: [{ title: 'Instance Roles — Harper Fabric' }] }),\n\t\tcomponent: ConfigRolesIndex,\n\t});\n\n\tconst instanceConfigUsersRoute = createRoute({\n\t\tgetParentRoute: () => instanceConfigRoute,\n\t\tpath: 'users',\n\t\thead: () => ({ meta: [{ title: 'Instance Users — Harper Fabric' }] }),\n\t\tcomponent: ConfigUsersIndex,\n\t});\n\tconst instanceConfigUserRoute = createRoute({\n\t\tgetParentRoute: () => instanceConfigRoute,\n\t\tpath: 'users/$username',\n\t\thead: () => ({ meta: [{ title: 'Instance Users — Harper Fabric' }] }),\n\t\tcomponent: ConfigUsersIndex,\n\t});\n\n\tconst instanceConfigDomainsRoute = createRoute({\n\t\tgetParentRoute: () => instanceConfigRoute,\n\t\tpath: 'domains',\n\t\thead: () => ({ meta: [{ title: 'Instance Domains — Harper Fabric' }] }),\n\t\tcomponent: ConfigDomainsIndex,\n\t});\n\n\tconst instanceConfigSSHKeysRoute = createRoute({\n\t\tgetParentRoute: () => instanceConfigRoute,\n\t\tpath: 'ssh-keys',\n\t\thead: () => ({ meta: [{ title: 'SSH Keys — Harper Fabric' }] }),\n\t\tcomponent: ConfigSSHKeysIndex,\n\t});\n\tconst instanceConfigSSHKeyRoute = createRoute({\n\t\tgetParentRoute: () => instanceConfigRoute,\n\t\tpath: 'ssh-keys/$keyName',\n\t\thead: () => ({ meta: [{ title: 'SSH Keys — Harper Fabric' }] }),\n\t\tcomponent: ConfigSSHKeysIndex,\n\t});\n\n\tconst instanceConfigCertificatesRoute = createRoute({\n\t\tgetParentRoute: () => instanceConfigRoute,\n\t\tpath: 'certificates',\n\t\thead: () => ({ meta: [{ title: 'Certificates — Harper Fabric' }] }),\n\t\tcomponent: ConfigCertificatesIndex,\n\t});\n\tconst instanceConfigCertificateRoute = createRoute({\n\t\tgetParentRoute: () => instanceConfigRoute,\n\t\tpath: 'certificates/$certName',\n\t\thead: () => ({ meta: [{ title: 'Certificates — Harper Fabric' }] }),\n\t\tcomponent: ConfigCertificatesIndex,\n\t});\n\n\treturn instanceConfigRoute.addChildren([\n\t\tinstanceOverviewRoute,\n\n\t\tinstanceConfigRolesRoute,\n\t\tinstanceConfigRoleRoute,\n\n\t\tinstanceConfigUsersRoute,\n\t\tinstanceConfigUserRoute,\n\n\t\tinstanceConfigDomainsRoute,\n\n\t\tinstanceConfigSSHKeysRoute,\n\t\tinstanceConfigSSHKeyRoute,\n\n\t\tinstanceConfigCertificatesRoute,\n\t\tinstanceConfigCertificateRoute,\n\t]);\n}\n","import { excludeFalsy } from '@/lib/arrays/excludeFalsy';\nimport { buildAbsoluteLinkToPage } from '@/lib/urls/buildAbsoluteLinkToPage';\n\nexport function buildAbsoluteLinkToDatabasePage({\n\tclusterId,\n\tdatabaseName,\n\tinstanceId,\n\torganizationId,\n\ttableName,\n}: {\n\tclusterId?: string;\n\tdatabaseName?: string;\n\tinstanceId?: string;\n\torganizationId?: string;\n\ttableName?: string;\n}): string {\n\tconst databases = [`databases`, databaseName, tableName].filter(excludeFalsy).join('/');\n\treturn buildAbsoluteLinkToPage({\n\t\torganizationId,\n\t\tinstanceId,\n\t\tclusterId,\n\t}, databases);\n}\n","import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';\nimport * as React from 'react';\n\nimport { cn } from '@/lib/cn';\n\nfunction ScrollArea({\n\tclassName,\n\tchildren,\n\t...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {\n\treturn (\n\t\t<ScrollAreaPrimitive.Root\n\t\t\tdata-slot=\"scroll-area\"\n\t\t\tclassName={cn('relative', className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<ScrollAreaPrimitive.Viewport\n\t\t\t\tdata-slot=\"scroll-area-viewport\"\n\t\t\t\tclassName=\"focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1\"\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</ScrollAreaPrimitive.Viewport>\n\t\t\t<ScrollBar />\n\t\t\t<ScrollAreaPrimitive.Corner />\n\t\t</ScrollAreaPrimitive.Root>\n\t);\n}\n\nfunction ScrollBar({\n\tclassName,\n\torientation = 'vertical',\n\t...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {\n\treturn (\n\t\t<ScrollAreaPrimitive.ScrollAreaScrollbar\n\t\t\tdata-slot=\"scroll-area-scrollbar\"\n\t\t\torientation={orientation}\n\t\t\tclassName={cn(\n\t\t\t\t'flex touch-none p-px transition-colors select-none',\n\t\t\t\torientation === 'vertical'\n\t\t\t\t\t&& 'h-full w-2.5 border-l border-l-transparent',\n\t\t\t\torientation === 'horizontal'\n\t\t\t\t\t&& 'h-2.5 flex-col border-t border-t-transparent',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<ScrollAreaPrimitive.ScrollAreaThumb\n\t\t\t\tdata-slot=\"scroll-area-thumb\"\n\t\t\t\tclassName=\"bg-border relative flex-1 rounded-full\"\n\t\t\t/>\n\t\t</ScrollAreaPrimitive.ScrollAreaScrollbar>\n\t);\n}\n\nexport { ScrollArea, ScrollBar };\n","import { InstanceClientConfig } from '@/config/instanceClientConfig';\nimport { ReplicatedResponse } from '@/integrations/api/replication';\nimport { useMutation } from '@tanstack/react-query';\n\ninterface CreateTableFormData extends InstanceClientConfig {\n\tdatabaseName: string;\n\ttableName: string;\n\tprimaryKey: string;\n\treplicated: boolean;\n}\n\nasync function onCreateTableSubmit({\n\tdatabaseName,\n\ttableName,\n\tprimaryKey,\n\treplicated,\n\tinstanceClient,\n}: CreateTableFormData): Promise<ReplicatedResponse> {\n\tconst { data } = await instanceClient.post('/', {\n\t\toperation: 'create_table',\n\t\tdatabase: databaseName,\n\t\ttable: tableName,\n\t\tprimary_key: primaryKey,\n\t\treplicated,\n\t});\n\treturn data;\n}\n\nexport function useCreateTableMutation() {\n\treturn useMutation({\n\t\tmutationFn: onCreateTableSubmit,\n\t});\n}\n","export const schemaRegex = /^[\\x20-\\x2E|\\x30-\\x5F|\\x61-\\x7E]*$/;\n","import { z } from 'zod';\nimport { schemaRegex } from './schemaRegex';\n\nexport const databaseNameSchema = z\n\t.string()\n\t.regex(schemaRegex, {\n\t\terror: 'Database name cannot include backticks or forward slashes.',\n\t})\n\t.max(75, { error: 'Database name cannot be longer than 75 characters.' });\n","import { z } from 'zod';\nimport { schemaRegex } from './schemaRegex';\n\nexport const tableNameSchema = z\n\t.string()\n\t.nonempty({\n\t\terror: 'Table name is required.',\n\t})\n\t.regex(schemaRegex, {\n\t\terror: 'Table name cannot include backticks or forward slashes.',\n\t})\n\t.max(250, {\n\t\terror: 'Table name cannot be longer than 250 characters.',\n\t});\n","import { Button } from '@/components/ui/button';\nimport {\n\tDialog,\n\tDialogContent,\n\tDialogDescription,\n\tDialogFooter,\n\tDialogHeader,\n\tDialogTitle,\n\tDialogTrigger,\n} from '@/components/ui/dialog';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { useCreateTableMutation } from '@/integrations/api/instance/database/createTable';\nimport { databaseNameSchema } from '@/integrations/api/instance/database/databaseNameSchema';\nimport { schemaRegex } from '@/integrations/api/instance/database/schemaRegex';\nimport { tableNameSchema } from '@/integrations/api/instance/database/tableNameSchema';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { useRouter } from '@tanstack/react-router';\nimport { Plus, Table } from 'lucide-react';\nimport { useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\n\nconst CreateTableSchema = z.object({\n\tdatabaseName: databaseNameSchema,\n\ttableName: tableNameSchema,\n\tprimaryKey: z\n\t\t.string()\n\t\t.regex(schemaRegex, {\n\t\t\terror: 'Primary key cannot include backticks or forward slashes.',\n\t\t})\n\t\t.max(250, {\n\t\t\terror: 'Primary key cannot be longer than 250 characters.',\n\t\t}),\n});\n\nexport function CreateNewTableModal({ databaseName, onSelectTable }: {\n\treadonly databaseName: string | undefined;\n\treadonly onSelectTable: (databaseName: string | undefined, tableName: string | undefined) => void;\n}) {\n\tconst queryClient = useQueryClient();\n\tconst instanceParams = useInstanceClientIdParams();\n\tconst router = useRouter();\n\tconst [isModalOpen, setIsModalOpen] = useState(false);\n\tconst form = useForm({\n\t\tresolver: zodResolver(CreateTableSchema),\n\t\tdefaultValues: {\n\t\t\tdatabaseName: databaseName || '',\n\t\t\ttableName: '',\n\t\t\tprimaryKey: '',\n\t\t},\n\t});\n\n\tconst { mutate: submitNewTableData } = useCreateTableMutation();\n\n\tconst submitForm = async (formData: z.infer<typeof CreateTableSchema>) => {\n\t\tconst databaseName = formData.databaseName || 'data';\n\t\tconst tableName = formData.tableName;\n\t\tsubmitNewTableData({\n\t\t\tdatabaseName,\n\t\t\ttableName,\n\t\t\tprimaryKey: formData.primaryKey || 'id',\n\t\t\t...instanceParams,\n\t\t\treplicated: instanceParams.entityType === 'cluster',\n\t\t}, {\n\t\t\tonSuccess: async () => {\n\t\t\t\tawait queryClient.invalidateQueries({\n\t\t\t\t\tqueryKey: [instanceParams.entityId, 'describe_all'],\n\t\t\t\t\trefetchType: 'all',\n\t\t\t\t});\n\t\t\t\ttoast.success(`Table ${tableName} created successfully`);\n\t\t\t\tsetIsModalOpen(false);\n\t\t\t\tform.reset();\n\t\t\t\tonSelectTable(databaseName, tableName);\n\t\t\t\tawait router.invalidate();\n\t\t\t},\n\t\t});\n\t};\n\n\treturn (\n\t\t<Dialog open={isModalOpen} onOpenChange={setIsModalOpen}>\n\t\t\t<DialogTrigger asChild>\n\t\t\t\t<div className=\"sticky bottom-0 py-4 bg-background/80 backdrop-blur-xs dark:bg-black/70\">\n\t\t\t\t\t<Button variant=\"positiveOutline\" className=\"w-full rounded-full\" size=\"lg\" accessKey=\"t\">\n\t\t\t\t\t\t<Plus />\n\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\tCreate a <u>T</u>able\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</Button>\n\t\t\t\t</div>\n\t\t\t</DialogTrigger>\n\t\t\t<DialogContent className=\"sm:max-w-[425px]\">\n\t\t\t\t<DialogHeader>\n\t\t\t\t\t<DialogTitle>Create a New Table</DialogTitle>\n\t\t\t\t\t<DialogDescription>\n\t\t\t\t\t\tWhat would you like to create?\n\t\t\t\t\t</DialogDescription>\n\t\t\t\t</DialogHeader>\n\t\t\t\t<Form {...form}>\n\t\t\t\t\t<form\n\t\t\t\t\t\tid=\"instance-new-table-form\"\n\t\t\t\t\t\tname=\"instance-new-table-form\"\n\t\t\t\t\t\tonSubmit={form.handleSubmit(submitForm)}\n\t\t\t\t\t\tclassName=\"grid gap-6 text-popover-foreground\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"tableName\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem className=\"\">\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Table Name</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\t\tmaxLength={CreateTableSchema.shape.tableName.maxLength!}\n\t\t\t\t\t\t\t\t\t\t\tautoFocus={true}\n\t\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"off\"\n\t\t\t\t\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\t\t\t\t\tautoCorrect=\"off\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"primaryKey\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem className=\"\">\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Primary Key</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t\t\tplaceholder=\"id\"\n\t\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\t\tmaxLength={CreateTableSchema.shape.primaryKey.maxLength!}\n\t\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"off\"\n\t\t\t\t\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\t\t\t\t\tautoCorrect=\"off\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"databaseName\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem className=\"\">\n\t\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Database Name</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\t\tplaceholder=\"data\"\n\t\t\t\t\t\t\t\t\t\t\tmaxLength={CreateTableSchema.shape.databaseName.maxLength!}\n\t\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"off\"\n\t\t\t\t\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\t\t\t\t\tautoCorrect=\"off\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<DialogFooter>\n\t\t\t\t\t\t\t<Button type=\"submit\" variant=\"submit\" className=\"rounded-full\">\n\t\t\t\t\t\t\t\t<Table />\n\t\t\t\t\t\t\t\tCreate New Table\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t</DialogFooter>\n\t\t\t\t\t</form>\n\t\t\t\t</Form>\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n}\n","import { TextLoadingSkeleton } from '@/components/TextLoadingSkeleton';\nimport { Button } from '@/components/ui/button';\nimport { ScrollArea } from '@/components/ui/scrollArea';\nimport { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';\nimport { CreateNewTableModal } from '@/features/instance/databases/modals/CreateNewTableModal';\nimport { useInstanceBrowseManagePermission } from '@/hooks/usePermissions';\nimport { InstanceDatabaseMap } from '@/integrations/api/api.patch';\nimport { buildAbsoluteLinkToDatabasePage } from '@/lib/urls/buildAbsoluteLinkToDatabasePage';\nimport { useNavigate, useParams, useRouter } from '@tanstack/react-router';\nimport { ArrowRight } from 'lucide-react';\nimport { useCallback, useMemo } from 'react';\n\nexport function DatabasesSidebar({ instanceDatabaseMap }: { instanceDatabaseMap?: InstanceDatabaseMap }) {\n\tconst router = useRouter();\n\n\tconst loading = !instanceDatabaseMap;\n\n\tconst params: { databaseName?: string; tableName?: string } = useParams({ strict: false });\n\tconst navigate = useNavigate();\n\tconst canManageBrowseInstance = useInstanceBrowseManagePermission();\n\n\tconst { databaseNames, tableNames } = useMemo(() => {\n\t\tconst databaseNames = Object.keys(instanceDatabaseMap || {}).sort();\n\t\tconst tableNames = params.databaseName ? Object.keys(instanceDatabaseMap?.[params.databaseName] || []).sort() : [];\n\t\treturn {\n\t\t\tdatabaseNames,\n\t\t\ttableNames,\n\t\t};\n\t}, [instanceDatabaseMap, params.databaseName]);\n\n\tconst onSelectDatabase = useCallback((newDatabaseName: string | undefined) => {\n\t\tconst tableNames = newDatabaseName ? Object.keys(instanceDatabaseMap?.[newDatabaseName] || []).sort() : [];\n\t\tif (!params.databaseName) {\n\t\t\tvoid router.invalidate();\n\t\t} else {\n\t\t\tvoid navigate({\n\t\t\t\tto: buildAbsoluteLinkToDatabasePage({\n\t\t\t\t\t...params,\n\t\t\t\t\tdatabaseName: newDatabaseName,\n\t\t\t\t\ttableName: tableNames[0],\n\t\t\t\t}),\n\t\t\t});\n\t\t}\n\t}, [instanceDatabaseMap, params, router, navigate]);\n\n\tconst onSelectTable = useCallback((newDatabaseName: string | undefined, newTableName: string | undefined) => {\n\t\tvoid navigate({\n\t\t\tto: buildAbsoluteLinkToDatabasePage({\n\t\t\t\t...params,\n\t\t\t\tdatabaseName: newDatabaseName,\n\t\t\t\ttableName: newTableName,\n\t\t\t}),\n\t\t});\n\t}, [navigate, params]);\n\n\treturn (\n\t\t<div className=\"pl-3\">\n\t\t\t<h1 className=\"pt-3 pb-3 text-3xl\">Databases</h1>\n\t\t\t{loading\n\t\t\t\t? <TextLoadingSkeleton className=\"w-full h-9 m-0 rounded-md\" />\n\t\t\t\t: (\n\t\t\t\t\t<div className=\"flex space-x-2\">\n\t\t\t\t\t\t<Select\n\t\t\t\t\t\t\tname=\"databaseSelect\"\n\t\t\t\t\t\t\tvalue={params.databaseName || ''}\n\t\t\t\t\t\t\tdisabled={databaseNames.length === 0}\n\t\t\t\t\t\t\tonValueChange={onSelectDatabase}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<SelectTrigger className=\"w-full\">\n\t\t\t\t\t\t\t\t<SelectValue placeholder=\"Select a Database\" />\n\t\t\t\t\t\t\t</SelectTrigger>\n\t\t\t\t\t\t\t<SelectContent>\n\t\t\t\t\t\t\t\t<SelectGroup>\n\t\t\t\t\t\t\t\t\t{databaseNames.map((databaseName) => (\n\t\t\t\t\t\t\t\t\t\t<SelectItem key={databaseName} value={databaseName}>\n\t\t\t\t\t\t\t\t\t\t\t{databaseName}\n\t\t\t\t\t\t\t\t\t\t</SelectItem>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</SelectGroup>\n\t\t\t\t\t\t\t</SelectContent>\n\t\t\t\t\t\t</Select>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t{loading\n\t\t\t\t? <TextLoadingSkeleton className=\"w-full min-h-80 rounded-md mb-0\" />\n\t\t\t\t: (\n\t\t\t\t\t<ScrollArea className=\"border rounded-md min-h-80 border-grey-700 mt-4\">\n\t\t\t\t\t\t{tableNames.length === 0 && params.databaseName?.length\n\t\t\t\t\t\t\t? (\n\t\t\t\t\t\t\t\t<div className=\"w-full h-full text-center\">\n\t\t\t\t\t\t\t\t\t<p className=\"py-6\">No tables found in this database.</p>\n\t\t\t\t\t\t\t\t\t{canManageBrowseInstance && (\n\t\t\t\t\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\t\t\t\t\tTap \"Create a Table\" below!\n\t\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t: tableNames.length === 0 && !params.databaseName?.length\n\t\t\t\t\t\t\t? canManageBrowseInstance\n\t\t\t\t\t\t\t\t? (\n\t\t\t\t\t\t\t\t\t<p className=\"pt-2 text-sm text-center\">\n\t\t\t\t\t\t\t\t\t\tPlease {databaseNames.length === 0 ? 'create' : 'select'} a table.\n\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t: (\n\t\t\t\t\t\t\t\t\t<p className=\"pt-2 text-sm text-center\">\n\t\t\t\t\t\t\t\t\t\tPlease {databaseNames.length === 0 ? 'ask your admin to create' : 'select'} a table.\n\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t: (\n\t\t\t\t\t\t\t\t''\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t<ul>\n\t\t\t\t\t\t\t{tableNames.map((tableName) => (\n\t\t\t\t\t\t\t\t<li\n\t\t\t\t\t\t\t\t\tkey={tableName}\n\t\t\t\t\t\t\t\t\tclassName=\"flex items-center p-2 border-b hover:bg-accent border-border dark:hover:bg-grey-700/80 dark:border-grey-700\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\tonClick={() => onSelectTable(params.databaseName, tableName)}\n\t\t\t\t\t\t\t\t\t\tsize=\"lg\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"items-center justify-between w-full bg-transparent border-none shadow-none hover:bg-transparent text-foreground\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{tableName}\n\t\t\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t\t\t{params.tableName === tableName && <ArrowRight />}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</ScrollArea>\n\t\t\t\t)}\n\t\t\t{canManageBrowseInstance && (\n\t\t\t\t<CreateNewTableModal\n\t\t\t\t\tdatabaseName={params.databaseName}\n\t\t\t\t\tonSelectTable={onSelectTable}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","import { InstanceAttribute, InstanceTable } from '@/integrations/api/api.patch';\nimport { ColumnDef } from '@tanstack/react-table';\n\nexport function formatBrowseDataTableHeader(instanceTable?: InstanceTable): {\n\tdataTableColumns: Array<ColumnDef<Record<string, unknown>>>;\n\tprimaryKey: string;\n} {\n\tif (!instanceTable) {\n\t\treturn {\n\t\t\tdataTableColumns: [],\n\t\t\tprimaryKey: '',\n\t\t};\n\t}\n\tconst primaryKey = instanceTable.primary_key ?? instanceTable.hash_attribute ?? '';\n\tconst { attributes } = instanceTable;\n\tconst primaryKeyColumns: ColumnDef<Record<string, unknown>>[] = [];\n\tconst sortableColumns: ColumnDef<Record<string, unknown>>[] = [];\n\tconst normalColumns: ColumnDef<Record<string, unknown>>[] = [];\n\tconst timeColumns: ColumnDef<Record<string, unknown>>[] = [];\n\tfor (let i = attributes.length - 1; i >= 0; i--) {\n\t\tconst { attribute, type, is_primary_key, indexed } = attributes[i];\n\n\t\tconst dataTableColumn: ColumnDef<Record<string, unknown>> = {\n\t\t\theader: attribute,\n\t\t\taccessorKey: attribute,\n\t\t\tenableSorting: Boolean(is_primary_key || indexed),\n\t\t\tenableColumnFilter: Boolean(is_primary_key || indexed),\n\t\t\t// enableResizing: true,\n\t\t\tsize: sizeByAttributeType(type),\n\t\t};\n\t\tif (is_primary_key) {\n\t\t\tprimaryKeyColumns.push(dataTableColumn);\n\t\t} else if (attribute === '__createdtime__' || attribute === '__updatedtime__') {\n\t\t\ttimeColumns.push(dataTableColumn);\n\t\t} else if (dataTableColumn.enableSorting) {\n\t\t\tsortableColumns.push(dataTableColumn);\n\t\t} else {\n\t\t\tnormalColumns.push(dataTableColumn);\n\t\t}\n\t}\n\treturn {\n\t\tdataTableColumns: [...primaryKeyColumns, ...sortableColumns, ...normalColumns, ...timeColumns],\n\t\tprimaryKey,\n\t};\n}\n\nfunction sizeByAttributeType(type: InstanceAttribute['type']) {\n\tswitch (type) {\n\t\tcase 'Id':\n\t\tcase 'ID':\n\t\t\treturn 1;\n\t\tcase 'Boolean':\n\t\t\treturn 1;\n\t\tcase 'Int':\n\t\tcase 'Long':\n\t\tcase 'Float':\n\t\tcase 'BigInt':\n\t\t\treturn 1;\n\t\tcase 'Date':\n\t\tcase 'String':\n\t\tdefault:\n\t\t\treturn Math.round(window.innerWidth * 0.1);\n\t}\n}\n","import { InstanceClientConfig } from '@/config/instanceClientConfig';\nimport { useMutation } from '@tanstack/react-query';\n\ninterface InsertTableRecordsData extends InstanceClientConfig {\n\tdatabaseName: string;\n\ttableName: string;\n\trecords: object[];\n}\n\nexport interface InsertTableRecordsResponse {\n\tmessage: string;\n\tinserted_hashes: string[];\n\tskipped_hashes: string[];\n}\n\nexport async function insertTableRecords({ databaseName, tableName, records, instanceClient }: InsertTableRecordsData) {\n\tconst { data } = await instanceClient.post<InsertTableRecordsResponse>('/', {\n\t\toperation: 'insert',\n\t\tdatabase: databaseName,\n\t\ttable: tableName,\n\t\trecords: records,\n\t});\n\treturn data;\n}\n\nexport function useInsertTableRecords() {\n\treturn useMutation({\n\t\tmutationFn: insertTableRecords,\n\t});\n}\n","import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';\nimport { Button } from '@/components/ui/button';\nimport { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { useMonacoTheme } from '@/hooks/useMonacoTheme';\nimport { InstanceAttribute, InstanceTable } from '@/integrations/api/api.patch';\nimport { useInsertTableRecords } from '@/integrations/api/instance/database/insertTableRecords';\nimport { Editor } from '@/lib/monaco/MonacoEditor';\nimport { pluralize } from '@/lib/pluralize';\nimport type { EditorProps, OnMount } from '@monaco-editor/react';\nimport { Save, TerminalIcon } from 'lucide-react';\nimport { useCallback, useMemo, useState } from 'react';\nimport { toast } from 'sonner';\n\nexport function AddTableRowModal({\n\tisModalOpen,\n\tinstanceTable,\n\tsetIsModalOpen,\n\trefreshTable,\n}: {\n\tinstanceTable: InstanceTable;\n\tisModalOpen: boolean;\n\tsetIsModalOpen: (open: boolean) => void;\n\trefreshTable: () => void;\n}) {\n\tconst monacoTheme = useMonacoTheme();\n\tconst { mutate: addTableRecords, isPending: isAddTableRecordsPending } = useInsertTableRecords();\n\tconst instanceParams = useInstanceClientIdParams();\n\n\tconst [isValidJSON, setIsValidJSON] = useState(true);\n\tconst [addTableRecordData, setAddTableRecordData] = useState<string>();\n\tconst [madeChanges, setMadeChanges] = useState(false);\n\tconst [skippedHashes, setSkippedHashes] = useState<string[]>([]);\n\n\tconst sampleJSON = useMemo(() => {\n\t\tconst sample: Record<string, unknown> = {};\n\t\tfor (const attribute of instanceTable.attributes) {\n\t\t\tif (\n\t\t\t\tattribute.is_primary_key || attribute.attribute === '__createdtime__'\n\t\t\t\t|| attribute.attribute === '__updatedtime__'\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tsample[attribute.attribute] = defaultByAttributeType(attribute.type);\n\t\t}\n\t\treturn JSON.stringify(sample, null, 4);\n\t}, [instanceTable]);\n\n\tconst onValidate = useCallback((markers: unknown[]) => {\n\t\tsetMadeChanges(true);\n\t\tsetIsValidJSON(markers.length === 0);\n\t}, [setIsValidJSON]);\n\n\tconst onSubmitClick = useCallback(() => {\n\t\tif (addTableRecordData && isValidJSON) {\n\t\t\tconst data = JSON.parse(addTableRecordData);\n\t\t\tconst records = Array.isArray(data) ? data : [data];\n\t\t\tconst toastId = toast.loading(`Adding ${records.length} records...`);\n\t\t\taddTableRecords(\n\t\t\t\t{\n\t\t\t\t\t...instanceParams,\n\t\t\t\t\tdatabaseName: instanceTable.schema,\n\t\t\t\t\ttableName: instanceTable.name,\n\t\t\t\t\trecords,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tonSuccess: (response) => {\n\t\t\t\t\t\tvoid refreshTable();\n\t\t\t\t\t\tif (!response.skipped_hashes?.length) {\n\t\t\t\t\t\t\tsetIsModalOpen(false);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsetSkippedHashes(response.skipped_hashes);\n\t\t\t\t\t\t(response.skipped_hashes?.length > 0 ? toast.warning : toast.success)(\n\t\t\t\t\t\t\tresponse.skipped_hashes?.length > 0 ? 'Warning!' : 'Success!',\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tid: toastId,\n\t\t\t\t\t\t\t\tdescription: (\n\t\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t\t{response.inserted_hashes.length > 0\n\t\t\t\t\t\t\t\t\t\t\t&& <p>Added {pluralize(response.inserted_hashes.length, 'record', 'records')}</p>}\n\t\t\t\t\t\t\t\t\t\t{response.skipped_hashes.length > 0\n\t\t\t\t\t\t\t\t\t\t\t&& <p>Skipped {pluralize(response.skipped_hashes.length, 'record', 'records')}</p>}\n\t\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}, [\n\t\taddTableRecordData,\n\t\taddTableRecords,\n\t\tinstanceParams,\n\t\tinstanceTable.name,\n\t\tinstanceTable.schema,\n\t\tisValidJSON,\n\t\trefreshTable,\n\t\tsetIsModalOpen,\n\t]);\n\n\tconst handleEditorDidMount: EditorProps['onMount'] = useCallback<OnMount>((editor) => {\n\t\teditor?.focus();\n\t}, []);\n\n\treturn (\n\t\t<Dialog onOpenChange={setIsModalOpen} open={isModalOpen}>\n\t\t\t{/* NOTE - Is this okay to do for the aria describedby? */}\n\t\t\t<DialogContent\n\t\t\t\taria-describedby={undefined}\n\t\t\t\tonEscapeKeyDown={(event) => {\n\t\t\t\t\tif (madeChanges) {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<DialogHeader>\n\t\t\t\t\t<DialogTitle>Add New {instanceTable.name}</DialogTitle>\n\t\t\t\t</DialogHeader>\n\t\t\t\t{(instanceTable?.primary_key ?? instanceTable?.hash_attribute)\n\t\t\t\t\t&& (\n\t\t\t\t\t\t<div className=\"text-sm text-gray-500\">\n\t\t\t\t\t\t\tThe primary key for this table is{' '}\n\t\t\t\t\t\t\t<strong>&ldquo;{instanceTable.primary_key ?? instanceTable.hash_attribute}&rdquo;</strong>, and will\n\t\t\t\t\t\t\tauto-generate. You may manually add it if you want to specify its value.\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t<Editor\n\t\t\t\t\tclassName=\"w-full h-96\"\n\t\t\t\t\tlanguage=\"json\"\n\t\t\t\t\ttheme={monacoTheme}\n\t\t\t\t\tvalue={sampleJSON}\n\t\t\t\t\tonValidate={onValidate}\n\t\t\t\t\tonChange={setAddTableRecordData}\n\t\t\t\t\toptions={{ minimap: { enabled: false } }}\n\t\t\t\t\tonMount={handleEditorDidMount}\n\t\t\t\t/>\n\t\t\t\t<div className=\"text-sm text-gray-500\">\n\t\t\t\t\t<strong>Provide an [array]</strong> if you want to add more than one record at a time.\n\t\t\t\t</div>\n\n\t\t\t\t{skippedHashes.length > 0 && (\n\t\t\t\t\t<Alert className=\"mt-2\">\n\t\t\t\t\t\t<TerminalIcon className=\"w-4 h-4\" />\n\t\t\t\t\t\t<AlertTitle>\n\t\t\t\t\t\t\tSkipped {skippedHashes.length === 1 ? 'Hash' : 'Hashes'} Detected\n\t\t\t\t\t\t</AlertTitle>\n\t\t\t\t\t\t<AlertDescription className=\"max-h-36 overflow-auto\">\n\t\t\t\t\t\t\t<ol>\n\t\t\t\t\t\t\t\t{skippedHashes.map(hash => <li key={hash}>{hash}</li>)}\n\t\t\t\t\t\t\t</ol>\n\t\t\t\t\t\t</AlertDescription>\n\t\t\t\t\t</Alert>\n\t\t\t\t)}\n\n\t\t\t\t<DialogFooter>\n\t\t\t\t\t<div className=\"flex justify-between w-full\">\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tvariant=\"submit\"\n\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\tonClick={onSubmitClick}\n\t\t\t\t\t\t\taccessKey=\"s\"\n\t\t\t\t\t\t\tdisabled={!addTableRecordData || !isValidJSON || isAddTableRecordsPending}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Save />{' '}\n\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t<u>S</u>ave Changes\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</div>\n\t\t\t\t</DialogFooter>\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n}\n\nfunction defaultByAttributeType(type: InstanceAttribute['type']) {\n\tswitch (type) {\n\t\tcase 'Date':\n\t\t\treturn new Date().toISOString();\n\t\tcase 'Id':\n\t\tcase 'ID':\n\t\tcase 'String':\n\t\t\treturn '';\n\t\tcase 'Boolean':\n\t\t\treturn false;\n\t\tcase 'Int':\n\t\tcase 'Long':\n\t\tcase 'Float':\n\t\tcase 'BigInt':\n\t\t\treturn 0;\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n","import { InstanceClientConfig } from '@/config/instanceClientConfig';\nimport { ReplicatedResponse } from '@/integrations/api/replication';\nimport { useMutation } from '@tanstack/react-query';\n\ninterface DeleteDatabaseParams extends InstanceClientConfig {\n\tdatabaseName: string;\n\treplicated: boolean;\n}\n\nasync function onDeleteDatabase(\n\t{ databaseName, replicated, instanceClient }: DeleteDatabaseParams,\n): Promise<ReplicatedResponse> {\n\tconst { data } = await instanceClient.post('/', {\n\t\toperation: 'drop_database',\n\t\tdatabase: databaseName,\n\t\treplicated,\n\t});\n\treturn data;\n}\n\nexport function useDeleteDatabaseMutation() {\n\treturn useMutation({\n\t\tmutationFn: onDeleteDatabase,\n\t});\n}\n","import { sleep } from '@/lib/sleep';\n\ninterface IFocusable {\n\tfocus?: () => void;\n}\n\ninterface ITargetFocusable {\n\ttarget?: IFocusable;\n}\n\nexport function attemptToRestoreFocus(trigger?: unknown) {\n\tconst focusableTrigger = trigger as IFocusable;\n\tif (focusableTrigger?.focus) {\n\t\tfocusElement(focusableTrigger);\n\t} else {\n\t\tconst triggerTargetFocusable = trigger as ITargetFocusable;\n\t\tif (triggerTargetFocusable?.target?.focus) {\n\t\t\tfocusElement(triggerTargetFocusable.target);\n\t\t}\n\t}\n}\n\nfunction focusElement(element: IFocusable) {\n\tsleep(1).then(() => {\n\t\telement.focus?.();\n\t});\n}\n","import { emitToListeners, useListener } from '@/lib/events/listener';\nimport { WatchedValueKeys, WatchedValuesTypeMap } from '@/lib/storage/watchedValueKeys';\nimport { useCallback, useState } from 'react';\n\ninterface ValueWrapper<T> {\n\tvalue: T;\n\ttrigger?: unknown;\n}\n\nexport function useWatchedValue<K extends keyof WatchedValuesTypeMap, T extends WatchedValuesTypeMap[K], D extends T>(\n\tname: K,\n\tdefaultValue: D,\n): ValueWrapper<T> {\n\tconst [value, setValue] = useState<{ value: T; trigger?: unknown }>({ value: defaultValue });\n\tuseListener(\n\t\tname,\n\t\t(newValue: T, trigger) => setValue({ value: newValue, trigger }),\n\t\t[setValue],\n\t);\n\treturn value;\n}\n\nexport function setWatchedValue<K extends keyof WatchedValuesTypeMap, T extends WatchedValuesTypeMap[K]>(\n\tname: WatchedValueKeys,\n\tvalue: T,\n\ttrigger?: unknown,\n): void {\n\temitToListeners(name, value, trigger);\n}\n\nexport function currySetWatchedValue<K extends keyof WatchedValuesTypeMap, T extends WatchedValuesTypeMap[K]>(\n\tname: WatchedValueKeys,\n\tvalue: T,\n\ttrigger?: unknown,\n): (e?: unknown) => void {\n\treturn (e) => setWatchedValue(name, value, trigger ?? e);\n}\n\nexport function useSetWatchedValue<K extends keyof WatchedValuesTypeMap, T extends WatchedValuesTypeMap[K]>(\n\tname: WatchedValueKeys,\n\tvalue: T,\n\ttrigger?: unknown,\n): () => void {\n\treturn useCallback((e?: unknown) => {\n\t\tsetWatchedValue(name, value, trigger ?? e);\n\t}, [name, value, trigger]);\n}\n","import { ConfirmDeletionModal } from '@/components/ConfirmDeletionModal';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { useInstanceBrowseManagePermission } from '@/hooks/usePermissions';\nimport { useDeleteDatabaseMutation } from '@/integrations/api/instance/database/deleteDatabase';\nimport { attemptToRestoreFocus } from '@/lib/attemptToRestoreFocus';\nimport { setWatchedValue, useWatchedValue } from '@/lib/events/watcher';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { useRouter } from '@tanstack/react-router';\nimport { useCallback } from 'react';\nimport { toast } from 'sonner';\n\nexport function DeleteDatabaseModal({ databaseName, onDeleted }: {\n\treadonly databaseName: string;\n\treadonly onDeleted: (deleted: 'table' | 'database') => void;\n}) {\n\tconst { value: isModalOpen, trigger } = useWatchedValue('ShowDeleteDatabase', false);\n\tconst closeModal = useCallback(() => {\n\t\tsetWatchedValue('ShowDeleteDatabase', false);\n\t\tattemptToRestoreFocus(trigger);\n\t}, [trigger]);\n\n\tconst canManageBrowseInstance = useInstanceBrowseManagePermission();\n\tconst queryClient = useQueryClient();\n\tconst instanceParams = useInstanceClientIdParams();\n\tconst router = useRouter();\n\tconst { mutate: deleteDatabase, isPending: isDeletingDatabase } = useDeleteDatabaseMutation();\n\n\tconst onDeleteDatabase = useCallback(() => {\n\t\tdeleteDatabase({\n\t\t\tdatabaseName,\n\t\t\t...instanceParams,\n\t\t\treplicated: instanceParams.entityType === 'cluster',\n\t\t}, {\n\t\t\tonSuccess: async () => {\n\t\t\t\tcloseModal();\n\t\t\t\tawait queryClient.invalidateQueries({\n\t\t\t\t\tqueryKey: [instanceParams.entityId, 'describe_all'],\n\t\t\t\t\trefetchType: 'all',\n\t\t\t\t});\n\t\t\t\tawait router.invalidate();\n\t\t\t\ttoast.success(`Database ${databaseName} dropped successfully`);\n\t\t\t\tonDeleted('database');\n\t\t\t},\n\t\t});\n\t}, [closeModal, databaseName, deleteDatabase, instanceParams, onDeleted, queryClient, router]);\n\n\tif (!canManageBrowseInstance || !databaseName) {\n\t\treturn <></>;\n\t}\n\n\treturn (\n\t\t<ConfirmDeletionModal\n\t\t\ttypeOfThingBeingDeleted=\"database\"\n\t\t\tnameOfThingBeingDeleted={databaseName}\n\t\t\ttransitiveVerb=\"Drop\"\n\t\t\tpresentParticiple=\"Dropping\"\n\t\t\tisModalOpen={isModalOpen}\n\t\t\tsetIsModalOpen={closeModal}\n\t\t\tdeletionConfirmed={onDeleteDatabase}\n\t\t\tdeletionPending={isDeletingDatabase}\n\t\t/>\n\t);\n}\n","import { InstanceClientConfig } from '@/config/instanceClientConfig';\nimport { ReplicatedResponse } from '@/integrations/api/replication';\nimport { useMutation } from '@tanstack/react-query';\n\ninterface DeleteTableData extends InstanceClientConfig {\n\tdatabaseName: string;\n\ttableName: string;\n\treplicated: boolean;\n}\n\nasync function onDeleteTable(\n\t{ databaseName, tableName, replicated, instanceClient }: DeleteTableData,\n): Promise<ReplicatedResponse> {\n\tconst { data } = await instanceClient.post('/', {\n\t\toperation: 'drop_table',\n\t\tdatabase: databaseName,\n\t\ttable: tableName,\n\t\treplicated,\n\t});\n\treturn data;\n}\n\nexport function useDeleteTableMutation() {\n\treturn useMutation({\n\t\tmutationFn: onDeleteTable,\n\t});\n}\n","import { ConfirmDeletionModal } from '@/components/ConfirmDeletionModal';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { useInstanceBrowseManagePermission } from '@/hooks/usePermissions';\nimport { useDeleteTableMutation } from '@/integrations/api/instance/database/deleteTable';\nimport { attemptToRestoreFocus } from '@/lib/attemptToRestoreFocus';\nimport { setWatchedValue, useWatchedValue } from '@/lib/events/watcher';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { useRouter } from '@tanstack/react-router';\nimport { useCallback } from 'react';\nimport { toast } from 'sonner';\n\nexport function DeleteTableModal({ databaseName, tableName, onDeleted }: {\n\treadonly databaseName: string;\n\treadonly tableName: string;\n\treadonly onDeleted: (deleted: 'table' | 'database') => void;\n}) {\n\tconst { value: isModalOpen, trigger } = useWatchedValue('ShowDeleteTable', false);\n\tconst closeModal = useCallback(() => {\n\t\tsetWatchedValue('ShowDeleteTable', false);\n\t\tattemptToRestoreFocus(trigger);\n\t}, [trigger]);\n\n\tconst canManageBrowseInstance = useInstanceBrowseManagePermission();\n\tconst queryClient = useQueryClient();\n\tconst instanceParams = useInstanceClientIdParams();\n\tconst router = useRouter();\n\tconst { mutate: deleteTable, isPending: isDeletingTable } = useDeleteTableMutation();\n\n\tconst onDeleteTable = useCallback(() => {\n\t\tdeleteTable(\n\t\t\t{\n\t\t\t\tdatabaseName,\n\t\t\t\ttableName,\n\t\t\t\t...instanceParams,\n\t\t\t\treplicated: instanceParams.entityType === 'cluster',\n\t\t\t},\n\t\t\t{\n\t\t\t\tonSuccess: async () => {\n\t\t\t\t\tcloseModal();\n\t\t\t\t\tawait queryClient.invalidateQueries({\n\t\t\t\t\t\tqueryKey: [instanceParams.entityId, 'describe_all'],\n\t\t\t\t\t\trefetchType: 'all',\n\t\t\t\t\t});\n\t\t\t\t\tawait router.invalidate();\n\t\t\t\t\ttoast.success(`Table ${tableName} dropped successfully`);\n\t\t\t\t\tonDeleted('table');\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t}, [closeModal, databaseName, deleteTable, instanceParams, onDeleted, queryClient, router, tableName]);\n\n\tif (!canManageBrowseInstance || !databaseName) {\n\t\treturn <></>;\n\t}\n\n\treturn (\n\t\t<ConfirmDeletionModal\n\t\t\ttypeOfThingBeingDeleted=\"table\"\n\t\t\tnameOfThingBeingDeleted={`${databaseName} > ${tableName}`}\n\t\t\ttransitiveVerb=\"Drop\"\n\t\t\tpresentParticiple=\"Dropping\"\n\t\t\tisModalOpen={isModalOpen}\n\t\t\tsetIsModalOpen={closeModal}\n\t\t\tdeletionConfirmed={onDeleteTable}\n\t\t\tdeletionPending={isDeletingTable}\n\t\t/>\n\t);\n}\n","import { Loading } from '@/components/Loading';\nimport { Button } from '@/components/ui/button';\nimport { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';\nimport { useMonacoTheme } from '@/hooks/useMonacoTheme';\nimport { Editor } from '@/lib/monaco/MonacoEditor';\nimport { Save, Trash } from 'lucide-react';\nimport { useCallback, useMemo, useState } from 'react';\n\nexport function EditTableRowModal({\n\tcanEditRecords,\n\tcanDeleteRecords,\n\tsetIsModalOpen,\n\tisModalOpen,\n\tprimaryKey,\n\tdata,\n\tonSaveChanges,\n\tonDeleteRecord,\n\tisUpdateTableRecordsPending,\n\tisDeleteTableRecordsPending,\n}: {\n\tcanEditRecords: boolean;\n\tcanDeleteRecords: boolean;\n\tsetIsModalOpen: (open: boolean) => void;\n\tisModalOpen: boolean;\n\tprimaryKey: string;\n\tdata: { __createdtime__?: number; __updatedtime__?: number; [record: string]: unknown }[];\n\tonSaveChanges: (data: Record<string, unknown>[]) => void;\n\tonDeleteRecord: (data: unknown[]) => void;\n\tisUpdateTableRecordsPending: boolean;\n\tisDeleteTableRecordsPending: boolean;\n}) {\n\tconst monacoTheme = useMonacoTheme();\n\tconst [isValidJSON, setIsValidJSON] = useState(true);\n\tconst [madeChanges, setMadeChanges] = useState(false);\n\tconst [updatedTableRecordData, setUpdatedTableRecordData] = useState<string>();\n\n\tconst value = useMemo(() => {\n\t\tconst dataWithoutTimes = data?.map(({ __createdtime__, __updatedtime__, ...rowWithoutTime }) => rowWithoutTime);\n\t\treturn JSON.stringify(dataWithoutTimes, null, 4);\n\t}, [data]);\n\tconst onValidate = useCallback((markers: unknown[]) => {\n\t\tsetMadeChanges(true);\n\t\tsetIsValidJSON(markers.length === 0);\n\t}, [setIsValidJSON]);\n\n\treturn (\n\t\t<Dialog onOpenChange={setIsModalOpen} open={isModalOpen}>\n\t\t\t{/* NOTE - Is this okay to do for the aria describedby? */}\n\t\t\t<DialogContent\n\t\t\t\taria-describedby={undefined}\n\t\t\t\tautoFocus={canEditRecords}\n\t\t\t\tonEscapeKeyDown={canEditRecords\n\t\t\t\t\t? (event) => {\n\t\t\t\t\t\tif (madeChanges) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t: undefined}\n\t\t\t>\n\t\t\t\t<DialogHeader>\n\t\t\t\t\t<DialogTitle>{canEditRecords ? 'Edit' : 'View'} Row</DialogTitle>\n\t\t\t\t</DialogHeader>\n\t\t\t\t{data\n\t\t\t\t\t? (\n\t\t\t\t\t\t<Editor\n\t\t\t\t\t\t\tclassName=\"w-full h-96\"\n\t\t\t\t\t\t\tlanguage=\"json\"\n\t\t\t\t\t\t\ttheme={monacoTheme}\n\t\t\t\t\t\t\toptions={canEditRecords ? undefined : { readOnly: true }}\n\t\t\t\t\t\t\tvalue={value}\n\t\t\t\t\t\t\tonValidate={onValidate}\n\t\t\t\t\t\t\tonChange={(updatedValue) => {\n\t\t\t\t\t\t\t\tsetUpdatedTableRecordData(updatedValue);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)\n\t\t\t\t\t: <Loading />}\n\t\t\t\t<DialogFooter>\n\t\t\t\t\t<div className=\"flex justify-between w-full\">\n\t\t\t\t\t\t{canDeleteRecords && (\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\tvariant=\"destructive\"\n\t\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tautoFocus={false}\n\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\tconst primaryKeyValue = data[0]?.[primaryKey];\n\t\t\t\t\t\t\t\t\tif (primaryKeyValue) {\n\t\t\t\t\t\t\t\t\t\tonDeleteRecord([primaryKeyValue]);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\tdisabled={isDeleteTableRecordsPending}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Trash /> Delete Row\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{canEditRecords && (\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\tvariant=\"submit\"\n\t\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\t\tautoFocus={true}\n\t\t\t\t\t\t\t\taccessKey=\"s\"\n\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\tif (updatedTableRecordData && isValidJSON) {\n\t\t\t\t\t\t\t\t\t\tonSaveChanges(JSON.parse(updatedTableRecordData));\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tsetIsModalOpen(false);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\tdisabled={!isValidJSON || isUpdateTableRecordsPending}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Save />{' '}\n\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t<u>S</u>ave Changes\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t</DialogFooter>\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n}\n","import { InstanceClientConfig } from '@/config/instanceClientConfig';\nimport { useMutation } from '@tanstack/react-query';\n\nexport interface AddCSVDataFormData {\n\tdatabase: string;\n\ttable: string;\n\tfileData: string;\n}\nexport interface AddCSVDataResponse {\n\tmessage: string;\n\tjob_id: string;\n}\n\nexport async function onAddCSVDataSubmit(formData: AddCSVDataFormData & InstanceClientConfig) {\n\tconst { database, table, fileData, instanceClient } = formData;\n\tconst { data } = await instanceClient.post(\n\t\t'/',\n\t\t{\n\t\t\toperation: 'csv_data_load',\n\t\t\tdatabase,\n\t\t\taction: 'insert',\n\t\t\ttable,\n\t\t\tdata: fileData,\n\t\t},\n\t);\n\treturn data;\n}\n\nexport function useAddCSVDataMutation() {\n\treturn useMutation<AddCSVDataResponse, Error, AddCSVDataFormData & InstanceClientConfig>({\n\t\tmutationFn: onAddCSVDataSubmit,\n\t});\n}\n","import { z } from 'zod';\n\nexport const AddCSVDataFormSchema = z.object({\n\tfileData: z.string(),\n\tdatabase: z.string(),\n\ttable: z.string(),\n});\n","import { Button } from '@/components/ui/button';\nimport {\n\tDialog,\n\tDialogContent,\n\tDialogDescription,\n\tDialogFooter,\n\tDialogHeader,\n\tDialogTitle,\n} from '@/components/ui/dialog';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { AddCSVDataFormData, useAddCSVDataMutation } from '@/integrations/api/instance/database/addCSVData';\nimport { AddCSVDataFormSchema } from '@/integrations/api/instance/database/addCSVDataFormSchema';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { CloudUploadIcon, Save } from 'lucide-react';\nimport { useState } from 'react';\nimport { useForm } from 'react-hook-form';\n\nexport function ImportCSVModal({\n\tsetIsModalOpen,\n\tisModalOpen,\n\tonSaveChanges,\n\tdatabase,\n\ttable,\n}: {\n\tsetIsModalOpen: (open: boolean) => void;\n\tisModalOpen: boolean;\n\tonSaveChanges: (message: string) => void;\n\tdatabase: string;\n\ttable: string;\n}) {\n\tconst [selectedCSVFile, setSelectedCSVFile] = useState<File | null>(null);\n\tconst instanceParams = useInstanceClientIdParams();\n\tconst { mutate: addCSVData, isPending: isAddCSVDataPending } = useAddCSVDataMutation();\n\n\tconst onFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n\t\tif (!e.target.files) { return; }\n\t\tconst file = e.target.files[0];\n\t\tif (file) {\n\t\t\tconst reader = new FileReader();\n\t\t\treader.onload = (event) => {\n\t\t\t\tconst text = event.target?.result;\n\t\t\t\tif (typeof text === 'string') {\n\t\t\t\t\tsetSelectedCSVFile(file);\n\t\t\t\t\tform.setValue('fileData', text);\n\t\t\t\t}\n\t\t\t};\n\t\t\treader.readAsText(file);\n\t\t}\n\t};\n\n\tconst form = useForm({\n\t\tresolver: zodResolver(AddCSVDataFormSchema),\n\t\tdefaultValues: {\n\t\t\tdatabase,\n\t\t\ttable,\n\t\t\tfileData: '',\n\t\t},\n\t});\n\n\tconst submitForm = (formData: AddCSVDataFormData) => {\n\t\taddCSVData(\n\t\t\t{\n\t\t\t\tfileData: formData.fileData,\n\t\t\t\tdatabase,\n\t\t\t\ttable,\n\t\t\t\t...instanceParams,\n\t\t\t},\n\t\t\t{\n\t\t\t\tonSuccess: ({ message }: { message: string }) => {\n\t\t\t\t\tform.reset();\n\t\t\t\t\tsetSelectedCSVFile(null);\n\t\t\t\t\tonSaveChanges(message);\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t};\n\n\treturn (\n\t\t<Dialog\n\t\t\tonOpenChange={() => {\n\t\t\t\tsetIsModalOpen(false);\n\t\t\t\tform.reset();\n\t\t\t}}\n\t\t\topen={isModalOpen}\n\t\t>\n\t\t\t<DialogContent>\n\t\t\t\t<DialogHeader>\n\t\t\t\t\t<DialogTitle>Import CSV</DialogTitle>\n\t\t\t\t\t<DialogDescription>Upload a CSV file to import data into the table.</DialogDescription>\n\t\t\t\t</DialogHeader>\n\t\t\t\t<Form {...form}>\n\t\t\t\t\t<form\n\t\t\t\t\t\tid=\"instance-import-csv-form\"\n\t\t\t\t\t\tname=\"instance-import-csv-form\"\n\t\t\t\t\t\tonSubmit={form.handleSubmit(submitForm)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<div className=\"w-full\">\n\t\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\t\tname=\"fileData\"\n\t\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t\t<FormItem className=\"relative\">\n\t\t\t\t\t\t\t\t\t\t<FormLabel\n\t\t\t\t\t\t\t\t\t\t\thtmlFor=\"dropzone-file\"\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"flex flex-col items-center justify-center w-full h-64 border-2 border-border border-dashed rounded-lg cursor-pointer bg-muted dark:bg-grey-700 hover:bg-muted/80 dark:hover:bg-grey-700/80\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"flex flex-col items-center justify-center pt-5 pb-6\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<CloudUploadIcon className=\"text-muted-foreground\" size={48} />\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<p className=\"mb-2 text-sm text-muted-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{selectedCSVFile\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tselectedCSVFile.name\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"font-semibold\">Click to upload</span> or drag and drop a CSV File\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tid=\"dropzone-file\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"file\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"opacity-0 w-full h-full absolute left-0 top-0 cursor-pointer\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\taccept=\".csv\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tname={field.name}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tref={field.ref}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tonBlur={field.onBlur}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdisabled={field.disabled}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tonChange={onFileChange}\n\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t\t</FormLabel>\n\t\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<DialogFooter className=\"mt-4\">\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\tvariant=\"submit\"\n\t\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\t\taccessKey=\"u\"\n\t\t\t\t\t\t\t\tdisabled={!selectedCSVFile || isAddCSVDataPending}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Save />\n\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t<u>U</u>pload CSV\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t</DialogFooter>\n\t\t\t\t\t</form>\n\t\t\t\t</Form>\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n}\n","import { MouseEvent, useCallback, useMemo, useState } from 'react';\n\nexport function useToggler(defaultValue: boolean = false) {\n\tconst [toggled, setToggled] = useState<boolean>(defaultValue);\n\n\tconst toggle = useCallback((e?: MouseEvent | unknown) => {\n\t\t(e as MouseEvent)?.preventDefault?.();\n\t\tsetToggled((checked: boolean) => {\n\t\t\treturn !checked;\n\t\t});\n\t}, []);\n\tconst toggleOn = useCallback((e?: MouseEvent | unknown) => {\n\t\t(e as MouseEvent)?.preventDefault?.();\n\t\tsetToggled(true);\n\t}, []);\n\tconst toggleOff = useCallback((e?: MouseEvent | unknown) => {\n\t\t(e as MouseEvent)?.preventDefault?.();\n\t\tsetToggled(false);\n\t}, []);\n\n\treturn useMemo(() => {\n\t\treturn {\n\t\t\ttoggled,\n\t\t\tsetToggled,\n\t\t\ttoggle,\n\t\t\ttoggleOn,\n\t\t\ttoggleOff,\n\t\t};\n\t}, [toggle, setToggled, toggleOff, toggleOn, toggled]);\n}\n","import { InstanceClientConfig } from '@/config/instanceClientConfig';\nimport { ReplicatedResponse } from '@/integrations/api/replication';\nimport { useMutation } from '@tanstack/react-query';\n\ninterface CleanupOrphanBlobsParams extends InstanceClientConfig {\n\tdatabaseName: string;\n}\n\nasync function onCleanupOrphanBlobs(\n\t{ databaseName, instanceClient }: CleanupOrphanBlobsParams,\n): Promise<ReplicatedResponse> {\n\tconst { data } = await instanceClient.post('/', {\n\t\toperation: 'cleanup_orphan_blobs',\n\t\tdatabase: databaseName,\n\t});\n\treturn data;\n}\n\nexport function useCleanupOrphanBlobsMutation() {\n\treturn useMutation({\n\t\tmutationFn: onCleanupOrphanBlobs,\n\t});\n}\n","import { InstanceClientConfig } from '@/config/instanceClientConfig';\nimport { useMutation } from '@tanstack/react-query';\n\ninterface DeleteTableRecordsData extends InstanceClientConfig {\n\tdatabaseName: string;\n\ttableName: string;\n\thashValues: unknown[];\n}\n\nexport async function deleteTableRecords(\n\t{ databaseName, tableName, hashValues, instanceClient }: DeleteTableRecordsData,\n) {\n\tconst { data } = await instanceClient.post('/', {\n\t\toperation: 'delete',\n\t\tdatabase: databaseName,\n\t\ttable: tableName,\n\t\thash_values: hashValues,\n\t});\n\treturn data;\n}\n\nexport function useDeleteTableRecords() {\n\treturn useMutation({\n\t\tmutationFn: deleteTableRecords,\n\t});\n}\n","import { InstanceClientIdConfig } from '@/config/instanceClientConfig';\nimport { InstanceTable } from '@/integrations/api/api.patch';\nimport { queryOptions } from '@tanstack/react-query';\n\ninterface GetDescribeTableParams extends InstanceClientIdConfig {\n\tdatabaseName: string;\n\ttableName: string;\n}\n\nexport async function getDescribeTable({ databaseName, tableName, instanceClient }: GetDescribeTableParams) {\n\tconst { data } = await instanceClient.post<InstanceTable>('/', {\n\t\toperation: 'describe_table',\n\t\tdatabase: databaseName,\n\t\ttable: tableName,\n\t});\n\treturn data;\n}\n\nexport function getDescribeTableQueryOptions(params: GetDescribeTableParams) {\n\treturn queryOptions({\n\t\tqueryKey: [params.entityId, params.databaseName, params.tableName, 'describe_table'] as const,\n\t\tqueryFn: () => getDescribeTable(params),\n\t\tstaleTime: 60_000,\n\t\tgcTime: 5_000,\n\t\tenabled: !!params.databaseName && !!params.tableName,\n\t\tretry: false,\n\t});\n}\n","const acceptedTrueValues = [\n\t'1',\n\t'bet',\n\t'k',\n\t'ok',\n\t'si',\n\t'tru',\n\t'true',\n\t'yes',\n\t'yup',\n];\n\nexport function translateKnownBooleanTypedValue(value: string): boolean {\n\tconst lowerValue = value.toLowerCase().trim();\n\treturn acceptedTrueValues.includes(lowerValue);\n}\n","export function isNumber(str: string): boolean {\n\treturn !isNaN(str as unknown as number)\n\t\t&& !isNaN(parseFloat(str));\n}\n","import { isNumber } from '@/lib/numbers/isNumber';\n\n/**\n * function to check if a string is a number based on the rules used by our autocaster\n */\nexport function autoCasterIsNumberCheck(data: string): boolean {\n\tif (data.startsWith('0.') && isNumber(data)) {\n\t\treturn true;\n\t}\n\n\tconst containsE = data.toUpperCase().includes('E');\n\tconst startsWithZero = data !== '0' && data.startsWith('0');\n\treturn !startsWithZero && !containsE && isNumber(data);\n}\n","import { autoCasterIsNumberCheck } from '@/lib/numbers/autoCasterIsNumberCheck';\n\nconst autoCastCommonStringsMap: Record<string, boolean | null | number> = {\n\ttrue: true,\n\tTRUE: true,\n\tfalse: false,\n\tFALSE: false,\n\tundefined: null,\n\tnull: null,\n\tNULL: null,\n\tNaN: NaN,\n};\nconst isoDateRegex =\n\t/^((\\d{4}-[01]\\d-[0-3]\\dT[0-2]\\d:[0-5]\\d:[0-5]\\d\\.\\d+([+-][0-2]\\d:[0-5]\\d|Z))|(\\d{4}-[01]\\d-[0-3]\\dT[0-2]\\d:[0-5]\\d:[0-5]\\d([+-][0-2]\\d:[0-5]\\d|Z))|(\\d{4}-[01]\\d-[0-3]\\dT[0-2]\\d:[0-5]\\d([+-][0-2]\\d:[0-5]\\d|Z)))$/;\n\n/**\n * Takes a raw string value and casts it to a potentially correct data type.\n * @param data\n * @returns\n */\nexport function autoCast(data: unknown) {\n\tif (data === null || data === undefined || data === '') {\n\t\treturn data;\n\t}\n\n\t// if this is already typed other than string, return data\n\tif (typeof data !== 'string') {\n\t\treturn data;\n\t}\n\n\t// Try to make it a common string\n\tif (autoCastCommonStringsMap[data] !== undefined) {\n\t\treturn autoCastCommonStringsMap[data];\n\t}\n\n\tif (autoCasterIsNumberCheck(data)) {\n\t\treturn Number(data);\n\t}\n\n\tif (isoDateRegex.test(data)) { return new Date(data); }\n\n\treturn data;\n}\n","import { InstanceClientIdConfig } from '@/config/instanceClientConfig';\nimport { InstanceAttribute } from '@/integrations/api/api.patch';\nimport { translateKnownBooleanTypedValue } from '@/lib/boolean/translateKnownBooleanTypedValue';\nimport { autoCast } from '@/lib/casting/autoCast';\nimport { queryOptions } from '@tanstack/react-query';\n\ninterface GetSearchByConditionsParams extends InstanceClientIdConfig {\n\tenabled: boolean;\n\tdatabaseName: string;\n\ttableName: string;\n\tconditions: SearchCondition[] | null;\n\tsort: { attribute: string; descending: boolean };\n\tpageIndex: number;\n\tpageSize: number;\n\tonlyIfCached: boolean;\n\theaders?: Record<string, any>;\n}\n\ntype Comparator =\n\t| 'between'\n\t// | 'contains' // Turned off for performance reasons until we add warnings for the user.\n\t// | 'ends_with' // Turned off for performance reasons until we add warnings for the user.\n\t| 'eq'\n\t| 'equals'\n\t| 'greater_than'\n\t| 'greater_than_equal'\n\t| 'less_than'\n\t| 'less_than_equal'\n\t| 'ne'\n\t| 'not_equal'\n\t| 'starts_with';\n\nexport interface SearchCondition {\n\tsearch_attribute: string;\n\tsearch_type: Comparator;\n\tsearch_value: unknown;\n}\n\ninterface SearchByConditionsRequest {\n\toperation: 'search_by_conditions';\n\tdatabase: string;\n\ttable: string;\n\tconditions: SearchCondition[];\n\tsort?: { attribute: string; descending: boolean };\n\toffset: number;\n\tlimit: number;\n\tget_attributes?: string[];\n\tonlyIfCached: boolean;\n\tnoCacheStore: boolean;\n}\n\nexport function getSearchByConditionsOptions(params: GetSearchByConditionsParams) {\n\tconst {\n\t\tenabled,\n\t\tentityId,\n\t\tdatabaseName,\n\t\ttableName,\n\t\tconditions,\n\t\tsort,\n\t\tpageIndex,\n\t\tpageSize,\n\t\tonlyIfCached,\n\t} = params;\n\t// starts_with, equals, etc\n\treturn queryOptions({\n\t\tenabled: enabled && !!conditions,\n\t\tqueryKey: [\n\t\t\tentityId,\n\t\t\tdatabaseName,\n\t\t\ttableName,\n\t\t\t'search_by_conditions',\n\t\t\tconditions,\n\t\t\tsort.attribute || 'default',\n\t\t\tsort.descending || false,\n\t\t\tpageIndex || 0,\n\t\t\tpageSize || 0,\n\t\t\tonlyIfCached,\n\t\t] as const,\n\t\tstaleTime: 60_000,\n\t\tgcTime: 5_000,\n\t\tretry: false,\n\t\tqueryFn: () => getSearchByConditions(params),\n\t});\n}\n\nexport function getSearchByConditions<T = Record<string, unknown>>({\n\tinstanceClient,\n\tdatabaseName,\n\ttableName,\n\tconditions,\n\tsort,\n\tpageIndex,\n\tpageSize,\n\tonlyIfCached,\n\theaders,\n}: Omit<GetSearchByConditionsParams, 'enabled'>) {\n\treturn instanceClient.post<T[]>(\n\t\t'/',\n\t\t{\n\t\t\toperation: 'search_by_conditions',\n\t\t\tget_attributes: ['*'],\n\t\t\tdatabase: databaseName,\n\t\t\ttable: tableName,\n\t\t\tconditions: conditions!,\n\t\t\tsort: sort.attribute.length ? sort : undefined,\n\t\t\toffset: pageIndex * pageSize,\n\t\t\tlimit: pageSize,\n\t\t\tonlyIfCached: onlyIfCached,\n\t\t\tnoCacheStore: onlyIfCached,\n\t\t} satisfies SearchByConditionsRequest,\n\t\t{ timeout: 0, headers },\n\t);\n}\n\nexport function translateColumnFilterToSearchConditions(\n\tkey: string,\n\trawValues: string,\n\tattribute: InstanceAttribute | undefined,\n): SearchCondition[] {\n\tconst split = rawValues.split(/ & /);\n\treturn split.map(rawValue => translateColumnFilterToSearchCondition(key, rawValue, attribute));\n}\n\nexport function translateColumnFilterToSearchCondition(\n\tkey: string,\n\trawValue: string,\n\tattribute: InstanceAttribute | undefined,\n): SearchCondition {\n\tif (rawValue.startsWith(key)) {\n\t\trawValue = rawValue.substring(key.length);\n\t}\n\tconst { comparator, value } = parseComparator(rawValue);\n\tswitch (attribute?.type) {\n\t\tcase 'ID':\n\t\tcase 'String': {\n\t\t\treturn {\n\t\t\t\tsearch_attribute: key,\n\t\t\t\tsearch_type: comparator,\n\t\t\t\tsearch_value: value,\n\t\t\t};\n\t\t}\n\t\tcase 'Int':\n\t\tcase 'BigInt':\n\t\tcase 'Long':\n\t\tcase 'Float': {\n\t\t\tconst parsed = attribute.type.includes('Int') ? parseInt(value, 10) : parseFloat(value);\n\t\t\tif (isNaN(parsed)) {\n\t\t\t\tthrow new Error(`${value} does not appear to be a valid number.`);\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tsearch_attribute: key,\n\t\t\t\tsearch_type: comparator,\n\t\t\t\tsearch_value: parsed,\n\t\t\t};\n\t\t}\n\t\tcase 'Date': {\n\t\t\tconst parsed = new Date(value).toISOString();\n\t\t\treturn {\n\t\t\t\tsearch_attribute: key,\n\t\t\t\tsearch_type: comparator,\n\t\t\t\tsearch_value: parsed,\n\t\t\t};\n\t\t}\n\t\tcase 'Boolean': {\n\t\t\treturn {\n\t\t\t\tsearch_attribute: key,\n\t\t\t\tsearch_type: comparator,\n\t\t\t\tsearch_value: translateKnownBooleanTypedValue(value),\n\t\t\t};\n\t\t}\n\t\tcase 'Blob':\n\t\tcase 'Bytes':\n\t\t\treturn {\n\t\t\t\tsearch_attribute: key,\n\t\t\t\tsearch_type: comparator,\n\t\t\t\tsearch_value: value,\n\t\t\t};\n\t\tcase 'Any':\n\t\tdefault:\n\t\t\treturn {\n\t\t\t\tsearch_attribute: key,\n\t\t\t\tsearch_type: comparator,\n\t\t\t\tsearch_value: autoCast(value),\n\t\t\t};\n\t}\n}\n\nconst comparatorEqualityPrefixMappings: Record<string, Comparator> = {\n\t// equals\n\t'=== ': 'equals',\n\t'== ': 'eq',\n\t'equals ': 'equals',\n\t'equal ': 'equals',\n\t'eq ': 'eq',\n\n\t// not equals\n\t'!== ': 'not_equal',\n\t'!= ': 'ne',\n\t'notequals ': 'not_equal',\n\t'notequal ': 'not_equal',\n\t'ne ': 'ne',\n};\n\nconst comparatorNumericalPrefixMappings: Record<string, Comparator> = {\n\t// greater than\n\t'>': 'greater_than',\n\t'g': 'greater_than',\n\t'gt': 'greater_than',\n\t'=gt': 'greater_than',\n\t'greater': 'greater_than',\n\t'greaterthan': 'greater_than',\n\n\t// greater than or equals\n\t'>=': 'greater_than_equal',\n\t'ge': 'greater_than_equal',\n\t'=ge': 'greater_than_equal',\n\t'gte': 'greater_than_equal',\n\t'greaterorequal': 'greater_than_equal',\n\t'greaterthanequal': 'greater_than_equal',\n\t'greaterthanorequal': 'greater_than_equal',\n\n\t// less than\n\t'<': 'less_than',\n\t'l': 'less_than',\n\t'lt': 'less_than',\n\t'=lt': 'less_than',\n\t'less': 'less_than',\n\t'lessthan': 'less_than',\n\n\t// less than or equals\n\t'<=': 'less_than_equal',\n\t'lte': 'less_than_equal',\n\t'le': 'less_than_equal',\n\t'=le': 'less_than_equal',\n\t'lessorequal': 'less_than_equal',\n\t'lessthanequal': 'less_than_equal',\n\t'lessthanorequal': 'less_than_equal',\n};\n\nexport function parseComparator(value: string): { comparator: Comparator; value: string } {\n\tconst lowered = value.toLowerCase();\n\n\t// Three accepted prefix shapes:\n\t// - symbol-led (>, <, >=, =gt, etc.): no separator needed before the value\n\t// - letters-then-symbol (gte=, lt=, etc.): the symbol acts as the separator\n\t// - letters-only (lt, gt, greaterthan, etc.): a space or underscore separator is required,\n\t// otherwise `LT1` would be ambiguous with values like \"LT1\" that just happen to start with letters\n\tconst numericalComparator = lowered.match(\n\t\t/^ *([>=<]+[a-z]*[_ ]*|[a-z]+[>=<]+[_ ]*|[a-z]+[_ ]+)([\\d._:tz-]+) *$/,\n\t);\n\tif (numericalComparator) {\n\t\tconst prefix = numericalComparator[1]\n\t\t\t.replace(/[_ ]+/g, '')\n\t\t\t.replace(/^([a-z]+)=$/g, '$1');\n\t\tconst number = numericalComparator[2];\n\t\tconst mappedComparator = comparatorNumericalPrefixMappings[prefix];\n\t\tif (mappedComparator) {\n\t\t\treturn {\n\t\t\t\tcomparator: mappedComparator,\n\t\t\t\tvalue: number,\n\t\t\t};\n\t\t}\n\t}\n\n\tfor (const equalityPrefix in comparatorEqualityPrefixMappings) {\n\t\tif (lowered.startsWith(equalityPrefix)) {\n\t\t\tconst equalityComparator = comparatorEqualityPrefixMappings[equalityPrefix];\n\t\t\treturn {\n\t\t\t\tcomparator: equalityComparator,\n\t\t\t\tvalue: value.slice(equalityPrefix.length),\n\t\t\t};\n\t\t}\n\t}\n\n\tif (lowered.endsWith('*')) {\n\t\treturn {\n\t\t\tcomparator: 'starts_with',\n\t\t\tvalue: value.slice(0, -1),\n\t\t};\n\t}\n\n\treturn {\n\t\tcomparator: 'equals',\n\t\tvalue: value,\n\t};\n}\n","import { InstanceClientIdConfig } from '@/config/instanceClientConfig';\nimport { queryOptions } from '@tanstack/react-query';\n\ninterface SearchByIdParams extends InstanceClientIdConfig {\n\tenabled: boolean;\n\tdatabaseName: string;\n\ttableName: string;\n\tids: unknown[] | null;\n}\n\nexport function getSearchByIdOptions(\n\t{ enabled, entityId, instanceClient, databaseName, tableName, ids }: SearchByIdParams,\n) {\n\treturn queryOptions({\n\t\tqueryKey: [entityId, 'search_by_id', databaseName, tableName, ids] as const,\n\t\tqueryFn: () =>\n\t\t\tinstanceClient.post('/', {\n\t\t\t\tget_attributes: ['*'],\n\t\t\t\tids,\n\t\t\t\tnoCacheStore: true,\n\t\t\t\tonlyIfCached: true,\n\t\t\t\toperation: 'search_by_id',\n\t\t\t\tdatabase: databaseName,\n\t\t\t\ttable: tableName,\n\t\t\t}),\n\t\tenabled: enabled && !!ids?.length,\n\t\tretry: false,\n\t});\n}\n","import { InstanceClientConfig } from '@/config/instanceClientConfig';\nimport { useMutation } from '@tanstack/react-query';\n\ninterface UpdateTableRecordsParams extends InstanceClientConfig {\n\tdatabaseName: string;\n\ttableName: string;\n\trecords: object[];\n}\n\nexport async function updateTableRecords(recordsData: UpdateTableRecordsParams) {\n\tconst { databaseName, tableName, records, instanceClient } = recordsData;\n\tconst { data } = await instanceClient.post('/', {\n\t\toperation: 'update',\n\t\tdatabase: databaseName,\n\t\ttable: tableName,\n\t\trecords: records,\n\t});\n\treturn data;\n}\n\nexport function useUpdateTableRecords() {\n\treturn useMutation({\n\t\tmutationFn: updateTableRecords,\n\t});\n}\n","import { BaseSyntheticEvent } from 'react';\n\nexport function onClickStopPropagation(e: BaseSyntheticEvent) {\n\te.stopPropagation();\n}\n","import { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { TableCell, TableHeader, TableRow } from '@/components/ui/table';\nimport { HeaderGroup } from '@tanstack/react-table';\nimport { KeyboardEvent, useCallback } from 'react';\nimport { UseFormReturn } from 'react-hook-form';\nimport { z } from 'zod';\n\nexport const ColumnFiltersSchema = z.record(z.string(), z.string());\n\nexport function ColumnFilters<TData>({\n\tapplyFilters,\n\tcolumnFiltersForm,\n\theaderGroups,\n}: {\n\tapplyFilters: () => void;\n\tcolumnFiltersForm: UseFormReturn<z.infer<typeof ColumnFiltersSchema>>;\n\theaderGroups: HeaderGroup<TData>[];\n}) {\n\tconst handleSubmit = useCallback((e: KeyboardEvent) => {\n\t\tif (e.key === 'Enter') {\n\t\t\te.preventDefault();\n\t\t\tapplyFilters();\n\t\t\treturn false;\n\t\t}\n\t}, [applyFilters]);\n\treturn (\n\t\t<TableHeader>\n\t\t\t<Form {...columnFiltersForm}>\n\t\t\t\t{headerGroups.map((headerGroup) => (\n\t\t\t\t\t<TableRow key={headerGroup.id} className=\"border-none\">\n\t\t\t\t\t\t{headerGroup.headers.map((header) => (\n\t\t\t\t\t\t\t<TableCell key={header.id} style={{ width: `${header.column.getSize()}px` }}>\n\t\t\t\t\t\t\t\t{header.column.columnDef.enableColumnFilter && (\n\t\t\t\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\t\t\t\tcontrol={columnFiltersForm.control}\n\t\t\t\t\t\t\t\t\t\tname={header.id}\n\t\t\t\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t\t\t\t<FormItem className=\"border-r-1 border-r-black\">\n\t\t\t\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"none\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"rounded-none\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tonKeyDown={handleSubmit}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tvalue={field.value ?? ''}\n\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</TableCell>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</TableRow>\n\t\t\t\t))}\n\t\t\t</Form>\n\t\t</TableHeader>\n\t);\n}\n","import { Button } from '@/components/ui/button';\nimport {\n\tDropdownMenu,\n\tDropdownMenuCheckboxItem,\n\tDropdownMenuContent,\n\tDropdownMenuTrigger,\n} from '@/components/ui/dropdownMenu';\nimport { formatBrowseDataTableHeader } from '@/features/instance/databases/functions/formatBrowseDataTableHeader';\nimport { excludeFalsy } from '@/lib/arrays/excludeFalsy';\nimport { VisibilityState } from '@tanstack/react-table';\nimport { Columns3CogIcon } from 'lucide-react';\nimport { useCallback, useMemo } from 'react';\n\nexport function PickColumnsDropdown({\n\tcolumns,\n\tcolumnVisibility,\n\tsetColumnVisibility,\n}: {\n\tcolumns: ReturnType<typeof formatBrowseDataTableHeader>['dataTableColumns'];\n\tcolumnVisibility: VisibilityState;\n\tsetColumnVisibility: (columnVisibility: VisibilityState) => void;\n}) {\n\tconst columnHeaders = useMemo(() => {\n\t\treturn columns\n\t\t\t.map(c => (typeof c.header === 'string' ? c.header : undefined))\n\t\t\t.filter(excludeFalsy);\n\t}, [columns]);\n\tconst toggleColumn = useCallback((columnHeader: string, nextChecked: boolean) => {\n\t\tsetColumnVisibility({\n\t\t\t...columnVisibility,\n\t\t\t[columnHeader]: nextChecked,\n\t\t});\n\t}, [columnVisibility, setColumnVisibility]);\n\treturn (\n\t\t<DropdownMenu>\n\t\t\t<DropdownMenuTrigger asChild>\n\t\t\t\t<Button variant=\"ghost\">\n\t\t\t\t\t<Columns3CogIcon className=\"inline-block \" />\n\t\t\t\t\tColumns\n\t\t\t\t</Button>\n\t\t\t</DropdownMenuTrigger>\n\t\t\t<DropdownMenuContent>\n\t\t\t\t{columnHeaders.map(columnHeader => (\n\t\t\t\t\t<ColumnPicker\n\t\t\t\t\t\tkey={columnHeader}\n\t\t\t\t\t\tcolumnHeader={columnHeader}\n\t\t\t\t\t\tisChecked={columnVisibility[columnHeader] ?? true}\n\t\t\t\t\t\ttoggleColumn={toggleColumn}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</DropdownMenuContent>\n\t\t</DropdownMenu>\n\t);\n}\n\nfunction ColumnPicker({\n\tcolumnHeader,\n\tisChecked,\n\ttoggleColumn,\n}: {\n\tcolumnHeader: string;\n\tisChecked: boolean;\n\ttoggleColumn: (columnHeader: string, nextChecked: boolean) => void;\n}) {\n\tconst onCheckedChange = useCallback((checked: boolean) => {\n\t\ttoggleColumn(columnHeader, checked);\n\t}, [columnHeader, toggleColumn]);\n\treturn (\n\t\t<DropdownMenuCheckboxItem\n\t\t\tchecked={isChecked}\n\t\t\tonCheckedChange={onCheckedChange}\n\t\t\tonSelect={e => e.preventDefault()}\n\t\t>\n\t\t\t{columnHeader}\n\t\t</DropdownMenuCheckboxItem>\n\t);\n}\n","import { cx } from 'class-variance-authority';\nimport { LoaderCircleIcon } from 'lucide-react';\nimport { ComponentProps } from 'react';\n\nexport function LoadingSubtle({ className }: ComponentProps<'div'>) {\n\treturn <LoaderCircleIcon className={cx('animate-spin', className)} />;\n}\n","'use client';\n\nimport { LoadingSubtle } from '@/components/LoadingSubtle';\nimport { TextLoadingSkeleton } from '@/components/TextLoadingSkeleton';\nimport { Button } from '@/components/ui/button';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';\nimport { Table, TableBody, TableCell, TableHeader, TableHeadSortable, TableRow } from '@/components/ui/table';\nimport { addCommasToNumbers } from '@/lib/addCommasToNumbers';\nimport { cn } from '@/lib/cn';\nimport {\n\tCell,\n\tColumnDef,\n\tflexRender,\n\tgetCoreRowModel,\n\tgetPaginationRowModel,\n\tRow,\n\tuseReactTable,\n\tVisibilityState,\n} from '@tanstack/react-table';\nimport { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react';\nimport { Dispatch, SetStateAction, useCallback, useMemo } from 'react';\nimport { UseFormReturn } from 'react-hook-form';\nimport { z } from 'zod';\nimport { ColumnFilters, ColumnFiltersSchema } from './ColumnFilters';\n\ninterface BrowseDataTableProps<TData, TValue> {\n\tapplyFilters: () => void;\n\tcolumnFiltersForm: UseFormReturn<z.infer<typeof ColumnFiltersSchema>>;\n\tcolumns: ColumnDef<TData, TValue>[];\n\tcolumnVisibility: VisibilityState;\n\tdata?: TData[];\n\tisFetching?: boolean;\n\tonColumnClick?: (accessorKey: string, isDescending: boolean) => void;\n\tfiltersToggled: boolean;\n\tonRowClick?: (row: Row<TData>) => void;\n\tpageIndex: number;\n\tpageSize: number;\n\tprimaryKey: string;\n\tsetPageIndex: Dispatch<SetStateAction<number>>;\n\tsetPageSize: Dispatch<SetStateAction<number>>;\n\ttotalPages?: number;\n\ttotalRecords?: number;\n}\n\nexport function TableView<TData, TValue>({\n\tapplyFilters,\n\tcolumnFiltersForm,\n\tcolumns,\n\tcolumnVisibility,\n\tdata,\n\tisFetching,\n\tonColumnClick,\n\tonRowClick,\n\tpageIndex,\n\tpageSize,\n\tprimaryKey,\n\tsetPageIndex,\n\tsetPageSize,\n\tfiltersToggled,\n\ttotalPages,\n\ttotalRecords,\n}: BrowseDataTableProps<TData, TValue>) {\n\tconst table = useReactTable({\n\t\tdata: data || [],\n\t\tcolumns,\n\t\tmanualPagination: true,\n\t\tenableColumnResizing: true,\n\t\tcolumnResizeMode: 'onEnd',\n\t\tpageCount: totalPages,\n\t\tdefaultColumn: {\n\t\t\tminSize: 1,\n\t\t},\n\t\tstate: {\n\t\t\tcolumnVisibility,\n\t\t},\n\t\trowCount: totalRecords,\n\t\tgetCoreRowModel: getCoreRowModel(),\n\t\tgetPaginationRowModel: getPaginationRowModel(),\n\t});\n\n\tconst previousPage = useCallback(() => {\n\t\tsetPageIndex(pageIndex - 1);\n\t}, [pageIndex, setPageIndex]);\n\tconst nextPage = useCallback(() => {\n\t\tsetPageIndex(pageIndex + 1);\n\t}, [pageIndex, setPageIndex]);\n\n\treturn (\n\t\t<>\n\t\t\t<Table containerClassName=\"rounded-md bg-card dark:bg-black-dark grow max-h-[calc(100vh-128px-16px-112px-80px)]\">\n\t\t\t\t<TableHeader>\n\t\t\t\t\t{table.getHeaderGroups().map((headerGroup) => (\n\t\t\t\t\t\t<TableRow key={headerGroup.id} className=\"border-none\">\n\t\t\t\t\t\t\t{headerGroup.headers.map((header) => (\n\t\t\t\t\t\t\t\t<TableHeadSortable key={header.id} header={header} onColumnClick={onColumnClick} />\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</TableRow>\n\t\t\t\t\t))}\n\t\t\t\t</TableHeader>\n\t\t\t\t{filtersToggled && (\n\t\t\t\t\t<ColumnFilters\n\t\t\t\t\t\tapplyFilters={applyFilters}\n\t\t\t\t\t\tcolumnFiltersForm={columnFiltersForm}\n\t\t\t\t\t\theaderGroups={table.getHeaderGroups()}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t<TableBody className=\"bg-background dark:bg-black border border-border dark:border-grey-700\">\n\t\t\t\t\t{table.getRowModel().rows?.length\n\t\t\t\t\t\t? (table.getRowModel().rows.map((row) => (\n\t\t\t\t\t\t\t<TableBodyRow key={row.id} row={row} onRowClick={onRowClick} primaryKey={primaryKey} />\n\t\t\t\t\t\t)))\n\t\t\t\t\t\t: (\n\t\t\t\t\t\t\t<TableRow>\n\t\t\t\t\t\t\t\t<TableCell colSpan={columns.length} className=\"h-24 text-center\">\n\t\t\t\t\t\t\t\t\t{isFetching || data === undefined\n\t\t\t\t\t\t\t\t\t\t? <LoadingSubtle className=\"opacity-50 inline-block\" />\n\t\t\t\t\t\t\t\t\t\t: <span>No results.</span>}\n\t\t\t\t\t\t\t\t</TableCell>\n\t\t\t\t\t\t\t</TableRow>\n\t\t\t\t\t\t)}\n\t\t\t\t</TableBody>\n\t\t\t</Table>\n\t\t\t<div className=\"flex items-center justify-end py-4 space-x-2 pr-4\">\n\t\t\t\t<Button\n\t\t\t\t\tvariant=\"defaultOutline\"\n\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\tonClick={previousPage}\n\t\t\t\t\tclassName=\"select-none\"\n\t\t\t\t\tdisabled={pageIndex === 0}\n\t\t\t\t>\n\t\t\t\t\t<ArrowLeftIcon />\n\t\t\t\t\tPrevious\n\t\t\t\t</Button>\n\n\t\t\t\t<div className=\"grow\"></div>\n\n\t\t\t\t<div className=\"text-center\">\n\t\t\t\t\t<dt className=\"font-medium text-gray-500 text-sm/6 dark:text-gray-400\">Records</dt>\n\t\t\t\t\t<dd className=\"font-semibold tracking-tight\">\n\t\t\t\t\t\t{totalRecords === undefined\n\t\t\t\t\t\t\t? <TextLoadingSkeleton />\n\t\t\t\t\t\t\t: addCommasToNumbers(totalRecords)}\n\t\t\t\t\t</dd>\n\t\t\t\t</div>\n\t\t\t\t{totalRecords !== undefined && totalRecords > 0 && (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t<Select\n\t\t\t\t\t\t\t\tdefaultValue={pageSize.toString()}\n\t\t\t\t\t\t\t\tonValueChange={(value) => {\n\t\t\t\t\t\t\t\t\tsetPageSize(Number(value));\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<SelectTrigger className=\"h-10 w-20\">\n\t\t\t\t\t\t\t\t\t<SelectValue />\n\t\t\t\t\t\t\t\t</SelectTrigger>\n\t\t\t\t\t\t\t\t<SelectContent side=\"top\">\n\t\t\t\t\t\t\t\t\t{[20, 50, 100, 250].map((pageSize) => (\n\t\t\t\t\t\t\t\t\t\t<SelectItem key={pageSize} value={`${pageSize}`}>\n\t\t\t\t\t\t\t\t\t\t\t{pageSize}\n\t\t\t\t\t\t\t\t\t\t</SelectItem>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</SelectContent>\n\t\t\t\t\t\t\t</Select>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t{totalPages !== undefined && totalPages > 1 && (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<div className=\"text-center\">\n\t\t\t\t\t\t\t\t\t<dt className=\"font-medium text-gray-500 text-sm/6 dark:text-gray-400\">Pages</dt>\n\t\t\t\t\t\t\t\t\t<dd className=\"font-semibold tracking-tight\">{addCommasToNumbers(totalPages)}</dd>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div className=\"text-center\">\n\t\t\t\t\t\t\t\t\t<dt className=\"font-medium text-gray-500 text-sm/6 dark:text-gray-400\">Page</dt>\n\t\t\t\t\t\t\t\t\t<dd className=\"font-semibold tracking-tight\">{addCommasToNumbers(pageIndex + 1)}</dd>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</>\n\t\t\t\t)}\n\n\t\t\t\t<div className=\"grow\"></div>\n\n\t\t\t\t<Button\n\t\t\t\t\tvariant=\"defaultOutline\"\n\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\tonClick={nextPage}\n\t\t\t\t\tclassName=\"select-none\"\n\t\t\t\t\tdisabled={totalPages === undefined || pageIndex === totalPages - 1}\n\t\t\t\t>\n\t\t\t\t\tNext\n\t\t\t\t\t<ArrowRightIcon />\n\t\t\t\t</Button>\n\t\t\t</div>\n\t\t</>\n\t);\n}\n\nfunction TableBodyRow<TData>(\n\t{ row, primaryKey, onRowClick }: { row: Row<TData>; primaryKey?: string; onRowClick?: (row: Row<TData>) => void },\n) {\n\tconst cells = useMemo(() => {\n\t\tconst original = row.original as Record<string, unknown>;\n\t\tconst isExpired = original && original.message === 'This entry has expired';\n\t\tconst visibleCells = row.getVisibleCells();\n\n\t\tconsole.log('primaryKey, visibleCells', primaryKey, visibleCells);\n\n\t\tif (isExpired) {\n\t\t\tif (visibleCells[0]?.column?.id === primaryKey) {\n\t\t\t\treturn [\n\t\t\t\t\t<TableBodyRowCell key={visibleCells[0].id} cell={visibleCells[0]} />,\n\t\t\t\t\t<TableBodyRowExpiredSpan key=\"expired\" colSpan={visibleCells.length - 1} />,\n\t\t\t\t];\n\t\t\t}\n\t\t\treturn [\n\t\t\t\t<TableBodyRowExpiredSpan key=\"expired\" colSpan={visibleCells.length} />,\n\t\t\t];\n\t\t}\n\t\treturn visibleCells.map((cell) => <TableBodyRowCell key={cell.id} cell={cell} />);\n\t}, [row, primaryKey]);\n\n\treturn (\n\t\t<TableRow\n\t\t\tdata-state={row.getIsSelected() && 'selected'}\n\t\t\tonClick={() => onRowClick?.(row)}\n\t\t\tclassName={cn('hover:bg-muted/10 data-[state=selected]:bg-muted', onRowClick && 'cursor-pointer')}\n\t\t>\n\t\t\t{cells}\n\t\t</TableRow>\n\t);\n}\n\nfunction TableBodyRowCell<TData>({ cell }: { cell: Cell<TData, unknown> }) {\n\treturn (\n\t\t<TableCell\n\t\t\tstyle={{ width: `${cell.column.getSize()}px` }}\n\t\t\tclassName=\"px-2 py-2 overflow-x-hidden max-w-32 text-ellipsis whitespace-nowrap\"\n\t\t>\n\t\t\t{cell.getValue() == '[object Object]'\n\t\t\t\t? JSON.stringify(cell.getValue())\n\t\t\t\t: flexRender(cell.column.columnDef.cell, cell.getContext())}\n\t\t</TableCell>\n\t);\n}\n\nfunction TableBodyRowExpiredSpan({ colSpan }: { colSpan: number }) {\n\treturn (\n\t\t<TableCell\n\t\t\tcolSpan={colSpan}\n\t\t\tclassName=\"px-2 py-2 overflow-x-hidden max-w-32 text-ellipsis whitespace-nowrap\"\n\t\t>\n\t\t\t<span className=\"text-muted-foreground\">This entry has expired</span>\n\t\t</TableCell>\n\t);\n}\n","import { Button } from '@/components/ui/button';\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdownMenu';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { formatBrowseDataTableHeader } from '@/features/instance/databases/functions/formatBrowseDataTableHeader';\nimport { AddTableRowModal } from '@/features/instance/databases/modals/AddTableRowModal';\nimport { DeleteDatabaseModal } from '@/features/instance/databases/modals/DeleteDatabaseModal';\nimport { DeleteTableModal } from '@/features/instance/databases/modals/DeleteTableModal';\nimport { EditTableRowModal } from '@/features/instance/databases/modals/EditTableRowModal';\nimport { ImportCSVModal } from '@/features/instance/databases/modals/ImportCSVModal';\nimport { useAdminMode } from '@/hooks/useAuth';\nimport { useEffectedState } from '@/hooks/useEffectedState';\nimport { useInstanceBrowseManagePermission, useInstanceSchemaTablePermission } from '@/hooks/usePermissions';\nimport { useRefreshClick } from '@/hooks/useRefreshClick';\nimport { useSessionStorage } from '@/hooks/useSessionStorage';\nimport { useToggler } from '@/hooks/useToggler';\nimport { InstanceDatabaseMap } from '@/integrations/api/api.patch';\nimport { useCleanupOrphanBlobsMutation } from '@/integrations/api/instance/database/cleanupOrphanBlobs';\nimport { useDeleteTableRecords } from '@/integrations/api/instance/database/deleteTableRecords';\nimport { getDescribeTableQueryOptions } from '@/integrations/api/instance/database/getDescribeTable';\nimport {\n\tgetSearchByConditions,\n\tgetSearchByConditionsOptions,\n\tSearchCondition,\n\ttranslateColumnFilterToSearchConditions,\n} from '@/integrations/api/instance/database/getSearchByConditions';\nimport { getSearchByIdOptions } from '@/integrations/api/instance/database/getSearchById';\nimport { getSearchByValue, getSearchByValueOptions } from '@/integrations/api/instance/database/getSearchByValue';\nimport { useUpdateTableRecords } from '@/integrations/api/instance/database/updateTableRecords';\nimport { useSetWatchedValue } from '@/lib/events/watcher';\nimport { keyBy } from '@/lib/keyBy';\nimport { onClickStopPropagation } from '@/lib/onClickStopPropagation';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useQuery, useQueryClient } from '@tanstack/react-query';\nimport { Link, useNavigate, useParams } from '@tanstack/react-router';\nimport { Row, VisibilityState } from '@tanstack/react-table';\nimport {\n\tBrushCleaningIcon,\n\tCircleCheckBigIcon,\n\tCircleIcon,\n\tCloudDownloadIcon,\n\tCloudUploadIcon,\n\tEllipsisIcon,\n\tExternalLinkIcon,\n\tFunnelIcon,\n\tFunnelPlusIcon,\n\tFunnelXIcon,\n\tPlusIcon,\n\tRefreshCwIcon,\n\tTrash2Icon,\n\tTrashIcon,\n} from 'lucide-react';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { ColumnFiltersSchema } from './ColumnFilters';\nimport { PickColumnsDropdown } from './PickColumnsDropdown';\nimport { TableView } from './TableView';\n\nexport function DatabaseTableView({ instanceDatabaseMap, databaseName, tableName }: {\n\tinstanceDatabaseMap?: InstanceDatabaseMap;\n\tdatabaseName: string;\n\ttableName: string;\n}) {\n\tconst allParams: {\n\t\tclusterId?: string;\n\t\tinstanceId?: string;\n\t} = useParams({ strict: false });\n\n\tconst navigate = useNavigate();\n\tconst instanceParams = useInstanceClientIdParams();\n\tconst { clusterId, instanceId } = allParams;\n\n\tconst { toggled: onlyIfCached, toggle: toggleOnlyCached } = useToggler(true);\n\n\tconst adminMode = useAdminMode();\n\tconst canAddRecords = useInstanceSchemaTablePermission(instanceId ?? clusterId, databaseName, tableName, 'insert');\n\tconst canEditRecords = useInstanceSchemaTablePermission(instanceId ?? clusterId, databaseName, tableName, 'update');\n\tconst canDeleteRecords = useInstanceSchemaTablePermission(instanceId ?? clusterId, databaseName, tableName, 'delete');\n\tconst canManageBrowseInstance = useInstanceBrowseManagePermission();\n\n\tconst { data: describeTableData } = useQuery(\n\t\tgetDescribeTableQueryOptions({\n\t\t\t...instanceParams,\n\t\t\tdatabaseName,\n\t\t\ttableName,\n\t\t}),\n\t);\n\tconst attributesMap = useMemo(() => keyBy(describeTableData?.attributes ?? [], 'attribute'), [describeTableData]);\n\tconst [selectedIds, setSelectedIds] = useEffectedState<null | unknown[]>(null, allParams);\n\tconst [isEditModalOpen, setIsEditModalOpen] = useState(false);\n\n\tconst isLastTableInDatabase = useMemo(() => {\n\t\tconst tableNames = databaseName ? Object.keys(instanceDatabaseMap?.[databaseName] || []).sort() : [];\n\t\treturn tableNames.length === 1;\n\t}, [instanceDatabaseMap, databaseName]);\n\n\tconst { toggled: filtersToggled, toggleOn: showFilters, toggleOff: hideFilters } = useToggler(false);\n\tconst columnFiltersForm = useForm({\n\t\tresolver: zodResolver(ColumnFiltersSchema),\n\t});\n\tconst { reset: resetFiltersForm } = columnFiltersForm;\n\tconst columnFiltersValues = columnFiltersForm.watch();\n\n\tconst [appliedSearchConditions, setAppliedSearchConditions] = useEffectedState<SearchCondition[] | null>(null, [\n\t\tallParams.clusterId,\n\t\tallParams.instanceId,\n\t\tdatabaseName,\n\t\ttableName,\n\t]);\n\n\tconst applyFilters = useCallback(() => {\n\t\tconst conditions: SearchCondition[] = [];\n\t\tfor (const key in columnFiltersValues) {\n\t\t\tif (columnFiltersValues[key]?.length) {\n\t\t\t\ttry {\n\t\t\t\t\tconditions.push(\n\t\t\t\t\t\t...translateColumnFilterToSearchConditions(key, columnFiltersValues[key], attributesMap[key]),\n\t\t\t\t\t);\n\t\t\t\t} catch (err) {\n\t\t\t\t\ttoast.error(String(err));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tsetAppliedSearchConditions(conditions.length ? conditions : null);\n\t\tresetFiltersForm({ ...columnFiltersValues });\n\t}, [attributesMap, resetFiltersForm, columnFiltersValues]);\n\tconst clearFilters = useCallback(() => {\n\t\t// Note sure why we need to resetFiltersForm twice here...\n\t\tresetFiltersForm({}, { keepValues: false, keepDirtyValues: false, keepDefaultValues: false });\n\t\tresetFiltersForm();\n\t\tsetAppliedSearchConditions(null);\n\t\thideFilters();\n\t}, [hideFilters, resetFiltersForm]);\n\n\tuseEffect(function clearFiltersWhenParamsChange() {\n\t\treturn clearFilters();\n\t}, [allParams, clearFilters]);\n\n\tconst { dataTableColumns, primaryKey } = formatBrowseDataTableHeader(describeTableData);\n\tconst [isAddModalOpen, setIsAddModalOpen] = useState(false);\n\tconst [isImportCSVModalOpen, setIsImportCSVModalOpen] = useState(false);\n\tconst [sort, setSort] = useEffectedState(\n\t\t{\n\t\t\tattribute: primaryKey,\n\t\t\tdescending: false,\n\t\t},\n\t\tallParams,\n\t);\n\n\tconst [pageIndex, setPageIndex] = useEffectedState(0, [databaseName, tableName]);\n\tconst [pageSize, setPageSize] = useState(20);\n\n\tconst totalRecords = describeTableData?.record_count;\n\tconst totalPages = describeTableData?.record_count ? Math.ceil(describeTableData.record_count / pageSize) : 0;\n\n\tconst useFilteredList = filtersToggled && !!appliedSearchConditions;\n\n\t// Full list\n\tconst searchByValueParams = {\n\t\t...instanceParams,\n\t\tenabled: !useFilteredList && !!primaryKey,\n\t\tdatabaseName,\n\t\ttableName,\n\t\tsearchAttribute: primaryKey,\n\t\tsort,\n\t\tpageSize,\n\t\tpageIndex,\n\t\tonlyIfCached,\n\t};\n\tconst searchByValueOptions = getSearchByValueOptions(searchByValueParams);\n\tconst { data: fullTableData, isFetching: tableDataFetching } = useQuery(searchByValueOptions);\n\n\t// Filtered list\n\tconst searchByConditionsParams = {\n\t\t...instanceParams,\n\t\tenabled: useFilteredList && !!primaryKey,\n\t\tdatabaseName,\n\t\ttableName,\n\t\tconditions: appliedSearchConditions,\n\t\tsort,\n\t\tpageSize,\n\t\tpageIndex,\n\t\tonlyIfCached,\n\t};\n\tconst searchByConditionsOptions = getSearchByConditionsOptions(searchByConditionsParams);\n\tconst { data: filteredTableData, isFetching: tableConditionsDataFetching } = useQuery(searchByConditionsOptions);\n\n\tconst tableData = useFilteredList ? filteredTableData : fullTableData;\n\tconst isFetching = tableDataFetching || tableConditionsDataFetching;\n\n\t// One by id\n\tconst { data: searchByIdData } = useQuery(getSearchByIdOptions({\n\t\t...instanceParams,\n\t\tenabled: isEditModalOpen,\n\t\tdatabaseName: databaseName,\n\t\ttableName: tableName,\n\t\tids: selectedIds,\n\t}));\n\n\tconst { mutate: updateTableRecords, isPending: isUpdateTableRecordsPending } = useUpdateTableRecords();\n\tconst { mutate: deleteTableRecords, isPending: isDeleteTableRecordsPending } = useDeleteTableRecords();\n\tconst { mutate: cleanupOrphanBlobs, isPending: isCleanupOrphanBlobsPending } = useCleanupOrphanBlobsMutation();\n\n\tconst queryClient = useQueryClient();\n\tconst refreshTable = useCallback(\n\t\t() => queryClient.invalidateQueries({ queryKey: [instanceParams.entityId, databaseName, tableName] }),\n\t\t[queryClient, instanceParams.entityId, databaseName, tableName],\n\t);\n\n\tconst onCleanupOrphanBlobs = useCallback(async () => {\n\t\tif (!confirm(`Are you sure you want to cleanup orphan blobs for database \"${databaseName}\"?`)) {\n\t\t\treturn;\n\t\t}\n\n\t\tcleanupOrphanBlobs({\n\t\t\t...instanceParams,\n\t\t\tdatabaseName,\n\t\t}, {\n\t\t\tonSuccess: (data) => {\n\t\t\t\ttoast.success(data.message || 'Orphan blobs cleanup started successfully');\n\t\t\t\trefreshTable();\n\t\t\t},\n\t\t\tonError: (error) => {\n\t\t\t\ttoast.error(error instanceof Error ? error.message : 'Failed to cleanup orphan blobs');\n\t\t\t},\n\t\t});\n\t}, [cleanupOrphanBlobs, databaseName, instanceParams, refreshTable]);\n\n\tconst [isExportingCSV, setisExportingCSV] = useState(false);\n\tconst onExportCSVClicked = useCallback(async () => {\n\t\tif (!primaryKey) {\n\t\t\treturn;\n\t\t}\n\t\tconst id = toast.loading('Loading CSV...');\n\t\tsetisExportingCSV(true);\n\t\tconst allResultsAsCSV = {\n\t\t\tpageIndex: 0,\n\t\t\tpageSize: 1_000_000,\n\t\t\theaders: {\n\t\t\t\tAccept: 'text/csv',\n\t\t\t},\n\t\t};\n\t\tconst response = await (\n\t\t\tuseFilteredList\n\t\t\t\t? getSearchByConditions({ ...searchByConditionsParams, ...allResultsAsCSV })\n\t\t\t\t: getSearchByValue({ ...searchByValueParams, ...allResultsAsCSV })\n\t\t);\n\t\ttoast.loading('Preparing CSV...', { id });\n\t\tconst content = response.data as unknown as string;\n\t\tconst blob = new Blob([content], { type: 'text/csv' });\n\t\tconst url = URL.createObjectURL(blob);\n\t\tconst downloadLink = document.createElement('a');\n\t\tdownloadLink.href = url;\n\t\tdownloadLink.setAttribute('download', `${databaseName}.${tableName}.${new Date().toISOString()}.csv`);\n\t\tdownloadLink.click();\n\t\ttoast.success('CSV Exported!', { id });\n\t\tsetisExportingCSV(false);\n\t}, [databaseName, tableName, searchByValueOptions, searchByConditionsOptions]);\n\n\tconst onRecordUpdate = useCallback((data: Record<string, unknown>[]) => {\n\t\tupdateTableRecords(\n\t\t\t{\n\t\t\t\t...instanceParams,\n\t\t\t\tdatabaseName,\n\t\t\t\ttableName,\n\t\t\t\trecords: data,\n\t\t\t},\n\t\t\t{\n\t\t\t\tonSuccess: () => {\n\t\t\t\t\tvoid refreshTable();\n\t\t\t\t\tsetIsEditModalOpen(false);\n\t\t\t\t\ttoast.success('Record updated successfully');\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t}, [updateTableRecords, instanceParams, databaseName, tableName, refreshTable]);\n\n\tconst onDeleteRecord = useCallback((hashes: unknown[]) => {\n\t\tdeleteTableRecords(\n\t\t\t{\n\t\t\t\t...instanceParams,\n\t\t\t\tdatabaseName,\n\t\t\t\ttableName,\n\t\t\t\thashValues: hashes,\n\t\t\t},\n\t\t\t{\n\t\t\t\tonSuccess: () => {\n\t\t\t\t\tvoid refreshTable();\n\t\t\t\t\tsetIsEditModalOpen(false);\n\t\t\t\t\ttoast.success('Record deleted successfully');\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t}, [deleteTableRecords, instanceParams, databaseName, tableName, refreshTable]);\n\n\tconst onCSVDataAdded = useCallback((message: string) => {\n\t\tvoid refreshTable();\n\t\tsetIsImportCSVModalOpen(false);\n\t\ttoast.success(`${message}. Please wait a few moments then refresh the table.`);\n\t}, [refreshTable]);\n\n\tconst onRowClick = (rowData: Row<Record<string, unknown>>) => {\n\t\tsetSelectedIds([rowData.original[primaryKey]]);\n\t\tsetIsEditModalOpen(!isEditModalOpen);\n\t};\n\tconst onColumnClick = (accessorKey: string, isAscending: boolean) => {\n\t\tsetSort({\n\t\t\tattribute: accessorKey,\n\t\t\tdescending: !isAscending,\n\t\t});\n\t};\n\tconst onRefreshClick = useRefreshClick(refreshTable);\n\n\tconst onAddClicked = useCallback(() => {\n\t\tsetIsAddModalOpen(true);\n\t}, [setIsAddModalOpen]);\n\n\tconst onImportCSVClicked = useCallback(() => {\n\t\tsetIsImportCSVModalOpen(true);\n\t}, [setIsImportCSVModalOpen]);\n\n\tconst onDeleted = useCallback(\n\t\t(deleted: 'table' | 'database') => void navigate({ to: deleted === 'table' ? '../' : '../../' }),\n\t\t[navigate],\n\t);\n\n\tconst [columnVisibility, setColumnVisibility] = useSessionStorage(\n\t\t`ColumnDisplayed/${databaseName}/${tableName}` as 'ColumnDisplayed/{database}/{table}',\n\t\t{} satisfies VisibilityState,\n\t);\n\n\tconst openDeleteTable = useSetWatchedValue('ShowDeleteTable', true);\n\tconst openDeleteDatabase = useSetWatchedValue('ShowDeleteDatabase', true);\n\n\treturn (\n\t\t<>\n\t\t\t<div className=\"flex flex-col md:flex-row items-center justify-between space-y-3 md:space-y-0 md:space-x-3 pt-15 pb-4 pr-4\">\n\t\t\t\t<div className=\"flex space-x-2\">\n\t\t\t\t\t{canAddRecords && (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tvariant=\"positiveOutline\"\n\t\t\t\t\t\t\tonClick={onAddClicked}\n\t\t\t\t\t\t\tdisabled={isAddModalOpen}\n\t\t\t\t\t\t\taccessKey=\"n\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<PlusIcon />\n\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\tAdd <u>N</u>ew Record(s)\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t)}\n\t\t\t\t\t{canAddRecords && (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tvariant=\"positiveOutline\"\n\t\t\t\t\t\t\tonClick={onImportCSVClicked}\n\t\t\t\t\t\t\tdisabled={isImportCSVModalOpen}\n\t\t\t\t\t\t\taccessKey=\"c\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<CloudUploadIcon />\n\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\tImport <u>C</u>SV\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t)}\n\t\t\t\t\t<Button\n\t\t\t\t\t\tvariant=\"positiveOutline\"\n\t\t\t\t\t\tonClick={onExportCSVClicked}\n\t\t\t\t\t\tdisabled={isExportingCSV}\n\t\t\t\t\t\taccessKey=\"e\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<CloudDownloadIcon />\n\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t<u>E</u>xport CSV\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</Button>\n\t\t\t\t</div>\n\n\t\t\t\t<div className=\"flex space-x-2\">\n\t\t\t\t\t{filtersToggled && appliedSearchConditions && (\n\t\t\t\t\t\t<Button type=\"button\" variant=\"ghost\" onClick={clearFilters} accessKey=\"f\">\n\t\t\t\t\t\t\t<FunnelXIcon className=\"inline-block \" />\n\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\tClear <u>F</u>ilters\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t)}\n\t\t\t\t\t{filtersToggled && columnFiltersForm.formState.isDirty && (\n\t\t\t\t\t\t<Button variant=\"default\" onClick={applyFilters}>\n\t\t\t\t\t\t\t<FunnelPlusIcon className=\"inline-block \" />\n\t\t\t\t\t\t\tApply Filters\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t)}\n\t\t\t\t\t{filtersToggled && !appliedSearchConditions && (\n\t\t\t\t\t\t<Button variant=\"ghost\" onClick={hideFilters} accessKey=\"f\">\n\t\t\t\t\t\t\t<FunnelXIcon className=\"inline-block \" />\n\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\tHide <u>F</u>ilters\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{!filtersToggled && (\n\t\t\t\t\t\t<Button variant=\"ghost\" onClick={showFilters} accessKey=\"f\">\n\t\t\t\t\t\t\t<FunnelIcon className=\"inline-block \" />\n\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\tShow <u>F</u>ilters\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<Button\n\t\t\t\t\t\tvariant=\"defaultOutline\"\n\t\t\t\t\t\tonClick={onRefreshClick}\n\t\t\t\t\t\tdisabled={isFetching}\n\t\t\t\t\t>\n\t\t\t\t\t\t<RefreshCwIcon />\n\t\t\t\t\t</Button>\n\n\t\t\t\t\t<PickColumnsDropdown\n\t\t\t\t\t\tcolumns={dataTableColumns}\n\t\t\t\t\t\tcolumnVisibility={columnVisibility}\n\t\t\t\t\t\tsetColumnVisibility={setColumnVisibility}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<DropdownMenu>\n\t\t\t\t\t\t<DropdownMenuTrigger asChild disabled={!instanceDatabaseMap}>\n\t\t\t\t\t\t\t<Button variant=\"ghost\" size=\"icon\" disabled={!instanceDatabaseMap}>\n\t\t\t\t\t\t\t\t<EllipsisIcon aria-label=\"Table options\" />\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t</DropdownMenuTrigger>\n\t\t\t\t\t\t<DropdownMenuContent side=\"bottom\" align=\"end\">\n\t\t\t\t\t\t\t<DropdownMenuItem className=\"focus:bg-primary/70 focus:text-white\" onClick={toggleOnlyCached}>\n\t\t\t\t\t\t\t\t{onlyIfCached ? <CircleCheckBigIcon className=\"text-green\" /> : <CircleIcon />}\n\t\t\t\t\t\t\t\tOnly If Cached\n\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\tto=\"https://docs.harperdb.io/docs/developers/applications/caching#cache-control-header\"\n\t\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\t\t\t\t\t\tonClick={onClickStopPropagation}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<ExternalLinkIcon />\n\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t</DropdownMenuItem>\n\t\t\t\t\t\t\t{canManageBrowseInstance\n\t\t\t\t\t\t\t\t&& adminMode\n\t\t\t\t\t\t\t\t&& !!instanceId && (\n\t\t\t\t\t\t\t\t<DropdownMenuItem\n\t\t\t\t\t\t\t\t\tclassName=\"focus:bg-yellow/70 focus:text-white\"\n\t\t\t\t\t\t\t\t\tonClick={onCleanupOrphanBlobs}\n\t\t\t\t\t\t\t\t\tdisabled={isCleanupOrphanBlobsPending}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<BrushCleaningIcon className=\"text-yellow \" />\n\t\t\t\t\t\t\t\t\tCleanup Orphan Blobs\n\t\t\t\t\t\t\t\t</DropdownMenuItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{canManageBrowseInstance && !isLastTableInDatabase && (\n\t\t\t\t\t\t\t\t<DropdownMenuItem className=\"focus:bg-red/70 focus:text-white\" onClick={openDeleteTable}>\n\t\t\t\t\t\t\t\t\t<TrashIcon className=\"inline-block \" />\n\t\t\t\t\t\t\t\t\tDrop Table\n\t\t\t\t\t\t\t\t</DropdownMenuItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{canManageBrowseInstance\n\t\t\t\t\t\t\t\t&& (\n\t\t\t\t\t\t\t\t\t<DropdownMenuItem className=\"focus:bg-red/70 focus:text-white\" onClick={openDeleteDatabase}>\n\t\t\t\t\t\t\t\t\t\t<Trash2Icon />\n\t\t\t\t\t\t\t\t\t\tDrop Database\n\t\t\t\t\t\t\t\t\t</DropdownMenuItem>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</DropdownMenuContent>\n\t\t\t\t\t</DropdownMenu>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<TableView<Record<string, unknown>, unknown>\n\t\t\t\tprimaryKey={primaryKey}\n\t\t\t\tdata={tableData?.data}\n\t\t\t\tisFetching={isFetching}\n\t\t\t\tfiltersToggled={filtersToggled}\n\t\t\t\tcolumns={dataTableColumns}\n\t\t\t\tcolumnVisibility={columnVisibility}\n\t\t\t\tonRowClick={onRowClick}\n\t\t\t\tonColumnClick={onColumnClick}\n\t\t\t\ttotalPages={totalPages}\n\t\t\t\ttotalRecords={totalRecords}\n\t\t\t\tpageIndex={pageIndex}\n\t\t\t\tpageSize={pageSize}\n\t\t\t\tcolumnFiltersForm={columnFiltersForm}\n\t\t\t\tapplyFilters={applyFilters}\n\t\t\t\tsetPageIndex={setPageIndex}\n\t\t\t\tsetPageSize={setPageSize}\n\t\t\t/>\n\t\t\t{canAddRecords && describeTableData && isAddModalOpen && (\n\t\t\t\t<AddTableRowModal\n\t\t\t\t\tinstanceTable={describeTableData}\n\t\t\t\t\tisModalOpen={isAddModalOpen}\n\t\t\t\t\trefreshTable={refreshTable}\n\t\t\t\t\tsetIsModalOpen={setIsAddModalOpen}\n\t\t\t\t/>\n\t\t\t)}\n\t\t\t<EditTableRowModal\n\t\t\t\tcanEditRecords={canEditRecords}\n\t\t\t\tcanDeleteRecords={canDeleteRecords}\n\t\t\t\tsetIsModalOpen={setIsEditModalOpen}\n\t\t\t\tisModalOpen={isEditModalOpen}\n\t\t\t\tprimaryKey={primaryKey}\n\t\t\t\tdata={searchByIdData?.data}\n\t\t\t\tonSaveChanges={onRecordUpdate}\n\t\t\t\tonDeleteRecord={onDeleteRecord}\n\t\t\t\tisUpdateTableRecordsPending={isUpdateTableRecordsPending}\n\t\t\t\tisDeleteTableRecordsPending={isDeleteTableRecordsPending}\n\t\t\t/>\n\n\t\t\t<DeleteDatabaseModal databaseName={databaseName} onDeleted={onDeleted} />\n\t\t\t<DeleteTableModal databaseName={databaseName} tableName={tableName} onDeleted={onDeleted} />\n\n\t\t\t<ImportCSVModal\n\t\t\t\tisModalOpen={isImportCSVModalOpen}\n\t\t\t\tsetIsModalOpen={setIsImportCSVModalOpen}\n\t\t\t\tonSaveChanges={onCSVDataAdded}\n\t\t\t\tdatabase={databaseName}\n\t\t\t\ttable={tableName}\n\t\t\t/>\n\t\t</>\n\t);\n}\n","import { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { getDescribeAllQueryOptions } from '@/integrations/api/instance/database/getDescribeAll';\nimport { buildAbsoluteLinkToDatabasePage } from '@/lib/urls/buildAbsoluteLinkToDatabasePage';\nimport { useQuery } from '@tanstack/react-query';\nimport { Navigate, useParams } from '@tanstack/react-router';\nimport { DatabasesSidebar } from './components/DatabasesSidebar';\nimport { DatabaseTableView } from './components/DatabaseTableView';\n\nexport function Databases() {\n\tconst params: {\n\t\tclusterId?: string;\n\t\tinstanceId?: string;\n\t\tdatabaseName?: string;\n\t\ttableName?: string;\n\t} = useParams({ strict: false });\n\n\tconst instanceParams = useInstanceClientIdParams();\n\tconst { data: instanceDatabaseMap } = useQuery(getDescribeAllQueryOptions(instanceParams));\n\n\tlet newDatabaseName: string | undefined;\n\tlet newTableName: string | undefined;\n\tif (instanceDatabaseMap) {\n\t\tif (!params.databaseName) {\n\t\t\tnewDatabaseName = Object.keys(instanceDatabaseMap).sort()[0];\n\t\t}\n\t\tconst databaseName = params.databaseName ?? newDatabaseName;\n\t\tif (!params.tableName && databaseName && instanceDatabaseMap[databaseName]) {\n\t\t\tnewTableName = Object.keys(instanceDatabaseMap[databaseName]).sort()[0];\n\t\t}\n\t}\n\tif (newDatabaseName || newTableName) {\n\t\treturn (\n\t\t\t<Navigate\n\t\t\t\tto={buildAbsoluteLinkToDatabasePage({\n\t\t\t\t\t...params,\n\t\t\t\t\tdatabaseName: newDatabaseName ?? params.databaseName,\n\t\t\t\t\ttableName: newTableName,\n\t\t\t\t})}\n\t\t\t\treplace={true}\n\t\t\t/>\n\t\t);\n\t}\n\n\treturn (\n\t\t<main className=\"grid grid-cols-1 gap-4 md:grid-cols-12 min-h-[calc(100vh-(--spacing(36)))]\">\n\t\t\t<section className=\"col-span-1 text-foreground md:col-span-4 lg:col-span-3\">\n\t\t\t\t<DatabasesSidebar instanceDatabaseMap={instanceDatabaseMap} />\n\t\t\t</section>\n\t\t\t<section className=\"col-span-1 text-foreground md:col-span-8 lg:col-span-9 flex flex-col\">\n\t\t\t\t{params.databaseName && params.tableName && (\n\t\t\t\t\t<DatabaseTableView\n\t\t\t\t\t\tinstanceDatabaseMap={instanceDatabaseMap}\n\t\t\t\t\t\tdatabaseName={params.databaseName}\n\t\t\t\t\t\ttableName={params.tableName}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</section>\n\t\t</main>\n\t);\n}\n","import { createInstanceLayoutRoute } from '@/features/instance/instanceLayoutRoute';\nimport { createRoute } from '@tanstack/react-router';\nimport { Databases } from './index';\n\nexport function createBrowseRouteTree(instanceLayoutRoute: ReturnType<typeof createInstanceLayoutRoute>) {\n\treturn createRoute({\n\t\tgetParentRoute: () => instanceLayoutRoute,\n\t\tpath: '/databases/{-$databaseName}/{-$tableName}',\n\t\thead: () => ({ meta: [{ title: 'Databases — Harper Fabric' }] }),\n\t\tcomponent: Databases,\n\t});\n}\n","import { Breadcrumbs } from '@/components/Breadcrumbs';\nimport { Button } from '@/components/ui/button';\nimport {\n\tDropdownMenu,\n\tDropdownMenuContent,\n\tDropdownMenuItem,\n\tDropdownMenuLabel,\n\tDropdownMenuSeparator,\n\tDropdownMenuTrigger,\n} from '@/components/ui/dropdownMenu';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { useInstanceManagePermission } from '@/hooks/usePermissions';\nimport { RegistrationInfoResponse } from '@/integrations/api/instance/status/getRegistrationInfo';\nimport { getStatusQueryOptions } from '@/integrations/api/instance/status/getStatus';\nimport { excludeFalsy } from '@/lib/arrays/excludeFalsy';\nimport { wasAReleasedBeforeB } from '@/lib/string/wasAReleasedBeforeB';\nimport { buildAbsoluteLinkToPage } from '@/lib/urls/buildAbsoluteLinkToPage';\nimport { useQuery } from '@tanstack/react-query';\nimport { Link, useLoaderData, useParams } from '@tanstack/react-router';\nimport { DatabaseIcon, GaugeIcon, Menu, NotepadTextIcon, PackageIcon, ServerIcon, SettingsIcon } from 'lucide-react';\nimport { ReactNode, useMemo } from 'react';\n\ninterface Link {\n\tto: string;\n\tname: string;\n\tshortName?: string;\n\ticon: ReactNode;\n}\n\nconst activeLinkProps = {\n\tclassName: 'text-primary font-semibold bg-primary/10 rounded-md dark:text-white dark:bg-white/10',\n};\n\nexport function InstanceNavBar() {\n\tconst canManage = useInstanceManagePermission();\n\tconst params = useParams({ strict: false });\n\n\tconst { version }: RegistrationInfoResponse = useLoaderData({ strict: false });\n\tconst statusAvailable = wasAReleasedBeforeB('4.6.0', version) && canManage;\n\tconst apisAvailable = wasAReleasedBeforeB('4.7.0-beta.7', version);\n\n\tconst instanceParams = useInstanceClientIdParams();\n\tconst { data: statusData } = useQuery(getStatusQueryOptions(instanceParams, statusAvailable));\n\tconst restartRequired = statusData?.restartRequired ?? false;\n\n\tconst links = useMemo(() =>\n\t\t[\n\t\t\tcanManage && {\n\t\t\t\tto: buildAbsoluteLinkToPage(params),\n\t\t\t\tactiveOptions: { exact: true },\n\t\t\t\tname: 'Applications',\n\t\t\t\tshortName: 'Apps',\n\t\t\t\ticon: <PackageIcon className=\"inline-block\" />,\n\t\t\t},\n\t\t\t{\n\t\t\t\tto: buildAbsoluteLinkToPage(params, 'databases'),\n\t\t\t\ticon: <DatabaseIcon className=\"inline-block\" />,\n\t\t\t\tname: 'Databases',\n\t\t\t},\n\t\t\tcanManage && apisAvailable && {\n\t\t\t\tto: buildAbsoluteLinkToPage(params, 'apis'),\n\t\t\t\tname: 'APIs',\n\t\t\t\ticon: <ServerIcon className=\"inline-block\" />,\n\t\t\t},\n\t\t\tcanManage && statusAvailable && {\n\t\t\t\tto: buildAbsoluteLinkToPage(params, 'status'),\n\t\t\t\ticon: <GaugeIcon className=\"inline-block\" />,\n\t\t\t\tname: 'Status',\n\t\t\t},\n\t\t\tcanManage && {\n\t\t\t\tto: buildAbsoluteLinkToPage(params, 'logs'),\n\t\t\t\ticon: <NotepadTextIcon className=\"inline-block\" />,\n\t\t\t\tname: 'Logs',\n\t\t\t},\n\t\t\tcanManage && {\n\t\t\t\tto: buildAbsoluteLinkToPage(params, 'config'),\n\t\t\t\ticon: <SettingsIcon className=\"inline-block\" />,\n\t\t\t\tname: 'Config',\n\t\t\t},\n\t\t].filter(excludeFalsy) satisfies Link[], [canManage, params, apisAvailable, statusAvailable]);\n\treturn (\n\t\t<>\n\t\t\t<DesktopInstanceNavBar links={links} restartRequired={restartRequired} />\n\t\t\t<MobileInstanceNavBar links={links} restartRequired={restartRequired} />\n\t\t</>\n\t);\n}\n\nfunction DesktopInstanceNavBar({ links, restartRequired }: { links: Link[]; restartRequired: boolean }) {\n\treturn (\n\t\t<div className=\"hidden md:flex items-center justify-between h-full text-sm text-foreground\">\n\t\t\t<Breadcrumbs restartRequired={restartRequired} />\n\t\t\t<div className=\"flex space-x-2\">\n\t\t\t\t{links.map(({ shortName, ...link }) => (\n\t\t\t\t\t<Link\n\t\t\t\t\t\tkey={link.to}\n\t\t\t\t\t\tclassName=\"p-2 text-center text-muted-foreground hover:text-foreground\"\n\t\t\t\t\t\tactiveProps={activeLinkProps}\n\t\t\t\t\t\t{...link}\n\t\t\t\t\t>\n\t\t\t\t\t\t{link.icon}\n\t\t\t\t\t\t<span className=\"hidden xl:inline-block ml-1\">{link.name}</span>\n\t\t\t\t\t\t{shortName && <span className=\"visible xl:hidden ml-1\">{shortName}</span>}\n\t\t\t\t\t</Link>\n\t\t\t\t))}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nfunction MobileInstanceNavBar({ links, restartRequired }: { links: Link[]; restartRequired: boolean }) {\n\treturn (\n\t\t<>\n\t\t\t<div className=\"flex md:hidden items-center justify-between h-full px-2 text-foreground\">\n\t\t\t\t<Breadcrumbs restartRequired={restartRequired} />\n\t\t\t\t<DropdownMenu>\n\t\t\t\t\t<DropdownMenuTrigger asChild>\n\t\t\t\t\t\t<Button variant=\"ghost\" className=\"p-0\">\n\t\t\t\t\t\t\t<Menu className=\"h-8 w-8\" />\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</DropdownMenuTrigger>\n\t\t\t\t\t<DropdownMenuContent>\n\t\t\t\t\t\t<DropdownMenuLabel>Instance Menu</DropdownMenuLabel>\n\t\t\t\t\t\t<DropdownMenuSeparator />\n\n\t\t\t\t\t\t{links.map(link => (\n\t\t\t\t\t\t\t<DropdownMenuItem key={link.to} asChild>\n\t\t\t\t\t\t\t\t<Link to={link.to} activeProps={activeLinkProps}>{link.name}</Link>\n\t\t\t\t\t\t\t</DropdownMenuItem>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</DropdownMenuContent>\n\t\t\t\t</DropdownMenu>\n\t\t\t</div>\n\t\t</>\n\t);\n}\n","import { isLocalStudio } from '@/config/constants';\nimport { InstanceNavBar } from '@/features/instance/InstanceNavBar';\nimport { Outlet } from '@tanstack/react-router';\nimport { lazy, Suspense } from 'react';\n\n// The chat widget pulls in the AI SDK and motion. It's a floating overlay that\n// isn't needed on first paint, so load it lazily to keep both off the initial\n// bundle; a null fallback is fine while its chunk fetches.\nconst FloatingChat = lazy(() =>\n\timport('./applications/components/Chat/FloatingChat').then((m) => ({ default: m.FloatingChat }))\n);\n\nexport function InstanceLayout() {\n\treturn (\n\t\t<>\n\t\t\t<nav className=\"fixed top-20 w-full z-39 h-12 md:px-12 bg-violet-50 border-b border-violet-100 dark:bg-grey-700 dark:border-none\">\n\t\t\t\t<InstanceNavBar />\n\t\t\t</nav>\n\t\t\t<div className=\"mt-32 min-h-[calc(100vh-(--spacing(32)))]\">\n\t\t\t\t<Outlet />\n\t\t\t</div>\n\t\t\t{!isLocalStudio && (\n\t\t\t\t<Suspense fallback={null}>\n\t\t\t\t\t<FloatingChat />\n\t\t\t\t</Suspense>\n\t\t\t)}\n\t\t</>\n\t);\n}\n","import { getInstanceClient } from '@/config/getInstanceClient';\nimport {\n\tAuthenticatedCloudConnection,\n\tAuthenticatedConnection,\n\tauthStore,\n\tOverallAppSignIn,\n} from '@/features/auth/store/authStore';\nimport { clusterLayoutRoute } from '@/features/cluster/clusterLayoutRoute';\nimport { InstanceLayout } from '@/features/instance/InstanceLayout';\nimport { getOrganizationClusterInstancePermissions, getOrganizationClusterPermissions } from '@/hooks/usePermissions';\nimport { getInstanceUserInfo } from '@/integrations/api/instance/status/getInstanceUserInfo';\nimport { buildRedirectInSearch } from '@/lib/urls/buildRedirectInSearch';\nimport { dashboardLayout } from '@/router/dashboardRoute';\nimport { createRoute, redirect } from '@tanstack/react-router';\nimport { registrationInfoLoader } from './registrationInfoLoader';\n\nexport function createInstanceLayoutRoute(mode: 'local' | 'cluster' | 'instance') {\n\tswitch (mode) {\n\t\tcase 'local':\n\t\t\treturn createRoute({\n\t\t\t\tgetParentRoute: () => dashboardLayout,\n\t\t\t\tid: '_instanceLayout',\n\t\t\t\tcomponent: InstanceLayout,\n\t\t\t\tloader: registrationInfoLoader,\n\t\t\t});\n\t\tcase 'cluster':\n\t\t\treturn createRoute({\n\t\t\t\tgetParentRoute: () => clusterLayoutRoute,\n\t\t\t\tid: '_instanceLayout',\n\t\t\t\tcomponent: InstanceLayout,\n\t\t\t\tbeforeLoad: checkClusterInstanceAuthenticationBeforeLoad,\n\t\t\t\tloader: registrationInfoLoader,\n\t\t\t});\n\t\tcase 'instance':\n\t\t\treturn createRoute({\n\t\t\t\tgetParentRoute: () => clusterLayoutRoute,\n\t\t\t\tpath: 'instance/$instanceId',\n\t\t\t\tcomponent: InstanceLayout,\n\t\t\t\tbeforeLoad: checkClusterInstanceAuthenticationBeforeLoad,\n\t\t\t\tloader: registrationInfoLoader,\n\t\t\t});\n\t}\n}\n\nasync function checkClusterInstanceAuthenticationBeforeLoad({\n\tcontext,\n\tparams,\n}: {\n\tcontext: { authentication: Record<string, AuthenticatedConnection> };\n\tparams: { organizationId: string; clusterId: string; instanceId?: string };\n}) {\n\t// Are we already authenticated?\n\tconst auth = context.authentication[params.instanceId || params.clusterId];\n\tif (auth?.isLoading || auth?.user) {\n\t\treturn;\n\t}\n\n\t// See if we can Fabric Connect.\n\tconst overallAuth = context.authentication[OverallAppSignIn] as AuthenticatedCloudConnection;\n\tif (overallAuth?.isLoading) {\n\t\treturn;\n\t}\n\tconst { update } = params.instanceId\n\t\t? getOrganizationClusterInstancePermissions(overallAuth.user, params.organizationId, params.clusterId)\n\t\t: getOrganizationClusterPermissions(overallAuth.user, params.organizationId, params.clusterId);\n\tif (update) {\n\t\tconst entityId = params.instanceId || params.clusterId;\n\t\tconst instanceClient = getInstanceClient({\n\t\t\tid: entityId,\n\t\t\tforceFabricConnect: true,\n\t\t});\n\t\ttry {\n\t\t\tconst user = await getInstanceUserInfo({ instanceClient });\n\t\t\tauthStore.setUserForIdAndKey(\n\t\t\t\tentityId,\n\t\t\t\tinstanceClient.defaults.baseURL!,\n\t\t\t\tuser,\n\t\t\t);\n\t\t\tauthStore.flagForFabricConnect(entityId, true);\n\t\t\treturn;\n\t\t} catch (err) {\n\t\t\t// Expected: the instance may be down, restarting, or unauthorized. We fall\n\t\t\t// through to the sign-in redirect below. Use debug so RUM doesn't forward it\n\t\t\t// to Datadog as an error (RUM only forwards console.error).\n\t\t\tconsole.debug('Fabric Connect not established', err);\n\t\t}\n\t}\n\n\tconst to = `/${params.organizationId}/${params.clusterId}/`\n\t\t+ (params.instanceId ? `instance/${params.instanceId}` : '')\n\t\t+ `/sign-in`;\n\tthrow redirect({ to, search: buildRedirectInSearch() });\n}\n","import { cva } from 'class-variance-authority';\n\nexport const toggleVariants = cva(\n\t`inline-flex \n items-center \n justify-center \n gap-2 \n whitespace-nowrap \n rounded-lg \n text-sm \n transition-[color,box-shadow] \n disabled:pointer-events-none \n disabled:opacity-50 \n [&_svg]:pointer-events-none \n [&_svg:not([class*='size-'])]:size-4 \n [&_svg]:shrink-0 \n ring-ring/10 \n dark:ring-ring/20 \n dark:outline-ring/40 \n outline-ring/50 \n focus-visible:ring-1 \n focus-visible:outline-1 \n focus-visible:ring-purple-200 \n aria-invalid:focus-visible:ring-0`,\n\t{\n\t\tvariants: {\n\t\t\tvariant: {\n\t\t\t\tdefault: 'bg-primary text-primary-foreground shadow-sm hover:bg-primary/90',\n\t\t\t\toutline:\n\t\t\t\t\t'border bg-default border-primary border-2 text-foreground shadow-xs hover:-translate-y-1 transition duration-200 hover:bg-accent/60 dark:text-white dark:hover:bg-grey-700/40',\n\t\t\t},\n\t\t\tsize: {\n\t\t\t\tdefault: 'h-9 px-4 py-2 has-[>svg]:px-3',\n\t\t\t\tsm: 'h-8 px-1.5 min-w-8',\n\t\t\t\tlg: 'h-10 px-2.5 min-w-10',\n\t\t\t},\n\t\t},\n\t\tdefaultVariants: {\n\t\t\tvariant: 'default',\n\t\t\tsize: 'default',\n\t\t},\n\t},\n);\n","import { toggleVariants } from '@/components/ui/toggleVariants';\nimport { cn } from '@/lib/cn';\nimport * as TogglePrimitive from '@radix-ui/react-toggle';\nimport { type VariantProps } from 'class-variance-authority';\nimport * as React from 'react';\n\nexport function Toggle({\n\tclassName,\n\tvariant,\n\tsize,\n\t...props\n}: React.ComponentProps<typeof TogglePrimitive.Root> & VariantProps<typeof toggleVariants>) {\n\treturn (\n\t\t<TogglePrimitive.Root data-slot=\"toggle\" className={cn(toggleVariants({ variant, size, className }))} {...props} />\n\t);\n}\n","export type BadgeLogLevelVariant =\n\t| 'notify'\n\t| 'error'\n\t| 'warn'\n\t| 'info'\n\t| 'debug'\n\t| 'trace'\n\t| 'stderr'\n\t| 'stdout'\n\t| undefined;\n\ntype BadgeStatusVariantValues = 'warning' | 'success' | 'secondary' | 'destructive';\n\nexport function renderBadgeLogLevelVariant(value: BadgeLogLevelVariant): BadgeStatusVariantValues {\n\tswitch (value) {\n\t\tcase 'warn':\n\t\t\treturn 'warning';\n\t\tcase 'notify':\n\t\t\treturn 'success';\n\t\tcase 'info':\n\t\tcase 'debug':\n\t\tcase 'trace':\n\t\tcase undefined:\n\t\tcase 'stdout':\n\t\t\treturn 'secondary';\n\t\tcase 'stderr':\n\t\tcase 'error':\n\t\t\treturn 'destructive';\n\t\tdefault:\n\t\t\treturn value;\n\t}\n}\n","const nodeVariant = ['secondary', 'default', 'warning', 'outline', 'success', 'destructive'] as const;\n\nlet nodeEntries = 0;\nconst cache = new Map<string, BadgeNodeVariantValues>();\n\nconst memoizeNodeNames = (nodeName: string): BadgeNodeVariantValues => {\n\tif (cache.has(nodeName)) { return cache.get(nodeName)!; }\n\tnodeEntries++;\n\tconst nodeVariantIndex = nodeEntries % nodeVariant.length;\n\tconst memoized = nodeVariant[nodeVariantIndex] as BadgeNodeVariantValues;\n\tcache.set(nodeName, memoized);\n\treturn memoized;\n};\n\nexport type BadgeNodeVariantValues = (typeof nodeVariant)[number];\n\nexport { memoizeNodeNames, nodeVariant };\n","'use client';\n\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';\nimport { ReadLogItem } from '@/integrations/api/instance/status/getReadLog';\nimport { cn } from '@/lib/cn';\nimport { ColumnDef, flexRender, getCoreRowModel, Row, useReactTable } from '@tanstack/react-table';\n\ninterface DataTableProps<TData extends ReadLogItem, TValue> {\n\tcolumns: ColumnDef<ReadLogItem, TValue>[];\n\tdata: TData[];\n\tonRowClick?: (row: Row<TData>) => void;\n\tcontainerClassName?: string;\n}\n\nfunction getLogLevelAccent(level: ReadLogItem['level']) {\n\tswitch (level) {\n\t\tcase 'error':\n\t\tcase 'stderr':\n\t\t\treturn 'border-l-destructive';\n\t\tcase 'warn':\n\t\t\treturn 'border-l-yellow-500';\n\t\tcase 'notify':\n\t\t\treturn 'border-l-green-500';\n\t\tdefault:\n\t\t\treturn 'border-l-transparent';\n\t}\n}\n\nexport function LogsDataTable<TData extends ReadLogItem, TValue>({\n\tcolumns,\n\tdata,\n\tonRowClick,\n}: DataTableProps<TData, TValue>) {\n\tconst table = useReactTable({\n\t\tdata,\n\t\tcolumns,\n\t\tgetCoreRowModel: getCoreRowModel(),\n\t});\n\n\treturn (\n\t\t<div className=\"rounded-md bg-card dark:bg-black-dark logsTable overflow-hidden\">\n\t\t\t<Table className=\"text-xs\">\n\t\t\t\t<TableHeader>\n\t\t\t\t\t{table.getHeaderGroups().map((headerGroup) => (\n\t\t\t\t\t\t<TableRow key={headerGroup.id} className=\"border-b border-border\">\n\t\t\t\t\t\t\t{headerGroup.headers.map((header) => {\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t<TableHead key={header.id} className=\"p-4 max-w-96\">\n\t\t\t\t\t\t\t\t\t\t{header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}\n\t\t\t\t\t\t\t\t\t</TableHead>\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t</TableRow>\n\t\t\t\t\t))}\n\t\t\t\t</TableHeader>\n\t\t\t\t<TableBody className=\"bg-background dark:bg-black\">\n\t\t\t\t\t{table.getRowModel().rows?.length\n\t\t\t\t\t\t? (\n\t\t\t\t\t\t\ttable.getRowModel().rows.map((row) => (\n\t\t\t\t\t\t\t\t<TableRow\n\t\t\t\t\t\t\t\t\tkey={row.id}\n\t\t\t\t\t\t\t\t\tdata-state={row.getIsSelected() && 'selected'}\n\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t'hover:bg-muted/20 data-[state=selected]:bg-muted max-w-full border-l-2',\n\t\t\t\t\t\t\t\t\t\tgetLogLevelAccent(row.original.level),\n\t\t\t\t\t\t\t\t\t\tonRowClick && 'cursor-pointer',\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\tonClick={() => onRowClick?.(row as Row<TData>)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{row.getVisibleCells().map((cell) => (\n\t\t\t\t\t\t\t\t\t\t<TableCell key={cell.id} className=\"p-2\">\n\t\t\t\t\t\t\t\t\t\t\t{flexRender(cell.column.columnDef.cell, cell.getContext())}\n\t\t\t\t\t\t\t\t\t\t</TableCell>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</TableRow>\n\t\t\t\t\t\t\t))\n\t\t\t\t\t\t)\n\t\t\t\t\t\t: (\n\t\t\t\t\t\t\t<TableRow>\n\t\t\t\t\t\t\t\t<TableCell colSpan={columns.length} className=\"h-24 text-center\">\n\t\t\t\t\t\t\t\t\tNo results.\n\t\t\t\t\t\t\t\t</TableCell>\n\t\t\t\t\t\t\t</TableRow>\n\t\t\t\t\t\t)}\n\t\t\t\t</TableBody>\n\t\t\t</Table>\n\t\t</div>\n\t);\n}\n","import { Loading } from '@/components/Loading';\nimport { Badge } from '@/components/ui/badge';\nimport { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';\nimport { renderBadgeLogLevelVariant } from '@/components/ui/utils/badgeLogLevel';\nimport { BadgeNodeVariantValues, memoizeNodeNames } from '@/components/ui/utils/badgeNode';\nimport { useMonacoTheme } from '@/hooks/useMonacoTheme';\nimport { ReadLogItem } from '@/integrations/api/instance/status/getReadLog';\nimport { Editor } from '@/lib/monaco/MonacoEditor';\nimport { capitalizeWords } from '@/lib/string/capitalizeWords';\n\nfunction isJsonString(str: string) {\n\ttry {\n\t\tJSON.parse(str);\n\t} catch {\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nfunction MetaRow({ label, children }: { label: string; children: React.ReactNode }) {\n\treturn (\n\t\t<div className=\"flex items-start gap-3 py-1.5 border-b border-border/50 last:border-0\">\n\t\t\t<span className=\"text-xs font-medium text-muted-foreground w-20 shrink-0 pt-0.5\">{label}</span>\n\t\t\t<span className=\"text-xs\">{children}</span>\n\t\t</div>\n\t);\n}\n\nexport function ViewLogModal({\n\tsetIsModalOpen,\n\tisModalOpen,\n\tdata,\n}: {\n\tsetIsModalOpen: (open: boolean) => void;\n\tisModalOpen: boolean;\n\tdata: ReadLogItem | undefined;\n}) {\n\tconst variant: BadgeNodeVariantValues = data ? memoizeNodeNames(data.node) : 'default';\n\tconst monacoTheme = useMonacoTheme();\n\n\treturn (\n\t\t<Dialog onOpenChange={setIsModalOpen} open={isModalOpen}>\n\t\t\t<DialogContent aria-describedby={undefined} className=\"max-w-2xl\">\n\t\t\t\t<DialogHeader>\n\t\t\t\t\t<DialogTitle>Log Entry</DialogTitle>\n\t\t\t\t</DialogHeader>\n\t\t\t\t{data\n\t\t\t\t\t? (\n\t\t\t\t\t\t<div className=\"flex flex-col gap-2 text-popover-foreground\">\n\t\t\t\t\t\t\t<div className=\"rounded-md border border-border/50 bg-muted/20 px-3 py-1\">\n\t\t\t\t\t\t\t\t<MetaRow label=\"Level\">\n\t\t\t\t\t\t\t\t\t<Badge variant={renderBadgeLogLevelVariant(data.level)}>\n\t\t\t\t\t\t\t\t\t\t{capitalizeWords(data.level)}\n\t\t\t\t\t\t\t\t\t</Badge>\n\t\t\t\t\t\t\t\t</MetaRow>\n\t\t\t\t\t\t\t\t<MetaRow label=\"Timestamp\">\n\t\t\t\t\t\t\t\t\t<span className=\"tabular-nums\">{new Date(data.timestamp).toLocaleString()}</span>\n\t\t\t\t\t\t\t\t</MetaRow>\n\t\t\t\t\t\t\t\t<MetaRow label=\"Thread\">\n\t\t\t\t\t\t\t\t\t<span className=\"tabular-nums font-mono\">{data.thread}</span>\n\t\t\t\t\t\t\t\t</MetaRow>\n\t\t\t\t\t\t\t\t{data.node && (\n\t\t\t\t\t\t\t\t\t<MetaRow label=\"Node\">\n\t\t\t\t\t\t\t\t\t\t<Badge variant={variant}>{data.node}</Badge>\n\t\t\t\t\t\t\t\t\t</MetaRow>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t{data.tags && data.tags.length > 0 && (\n\t\t\t\t\t\t\t\t\t<MetaRow label=\"Tags\">\n\t\t\t\t\t\t\t\t\t\t<span className=\"font-mono\">{data.tags}</span>\n\t\t\t\t\t\t\t\t\t</MetaRow>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t<p className=\"text-xs font-medium text-muted-foreground mb-1.5\">Message</p>\n\t\t\t\t\t\t\t\t<div className=\"rounded-md overflow-hidden border border-border/50 h-72\">\n\t\t\t\t\t\t\t\t\t<Editor\n\t\t\t\t\t\t\t\t\t\tclassName=\"w-full h-full\"\n\t\t\t\t\t\t\t\t\t\tlanguage={isJsonString(data.message) ? 'json' : 'text'}\n\t\t\t\t\t\t\t\t\t\ttheme={monacoTheme}\n\t\t\t\t\t\t\t\t\t\tvalue={data.message}\n\t\t\t\t\t\t\t\t\t\toptions={{\n\t\t\t\t\t\t\t\t\t\t\treadOnly: true,\n\t\t\t\t\t\t\t\t\t\t\tminimap: { enabled: false },\n\t\t\t\t\t\t\t\t\t\t\tscrollBeyondLastLine: false,\n\t\t\t\t\t\t\t\t\t\t\tfontSize: 12,\n\t\t\t\t\t\t\t\t\t\t\tpadding: { top: 12, bottom: 12 },\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)\n\t\t\t\t\t: <Loading />}\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n}\n","import { InstanceClientIdConfig } from '@/config/instanceClientConfig';\nimport { LogFiltersFormSchema } from '@/integrations/api/instance/status/logFiltersFormSchema';\nimport { queryOptions } from '@tanstack/react-query';\nimport { z } from 'zod';\n\nexport interface ReadLogItem {\n\tlevel: 'notify' | 'error' | 'warn' | 'info' | 'debug' | 'trace' | 'stderr' | 'stdout';\n\ttimestamp: string;\n\tthread: string;\n\ttags: string[];\n\tnode: string;\n\tmessage: string;\n}\n\ninterface GetReadLogParams {\n\tlogFilters: z.infer<typeof LogFiltersFormSchema>;\n\treplicated: boolean;\n\tisAutoRefreshEnabled: boolean;\n}\n\nexport async function getReadLog(\n\t{ instanceClient, logFilters, replicated }: Omit<GetReadLogParams, 'isAutoRefreshEnabled'> & InstanceClientIdConfig,\n): Promise<ReadLogItem[]> {\n\tconst { data } = await instanceClient.post<ReadLogItem[]>('/', {\n\t\toperation: 'read_log',\n\t\tstart: 0,\n\t\treplicated,\n\t\tlimit: logFilters.limit ? parseInt(logFilters.limit, 10) : undefined,\n\t\tlevel: logFilters.level !== 'undefined' ? logFilters.level : undefined,\n\t\tfrom: logFilters.from ? new Date(logFilters.from).toISOString() : undefined,\n\t\tuntil: logFilters.until ? new Date(logFilters.until).toISOString() : undefined,\n\t\tlog_name: logFilters.log_name ?? undefined,\n\t\tfilter: logFilters.filter ? logFilters.filter : undefined,\n\t\torder: 'desc',\n\t});\n\treturn data;\n}\n\nexport function getReadLogQueryOptions(params: GetReadLogParams & InstanceClientIdConfig) {\n\tconst logFilters = params.logFilters;\n\treturn queryOptions({\n\t\tqueryKey: [\n\t\t\tparams.entityId,\n\t\t\t'read_log',\n\t\t\tlogFilters.limit,\n\t\t\tlogFilters.level,\n\t\t\tlogFilters.from,\n\t\t\tlogFilters.until,\n\t\t\tlogFilters.log_name,\n\t\t\tlogFilters.filter,\n\t\t\tparams.replicated,\n\t\t] as const,\n\t\tqueryFn: () => getReadLog(params),\n\t\tretry: false,\n\t\trefetchInterval: params.isAutoRefreshEnabled ? 5000 : false,\n\t});\n}\n","import { z } from 'zod';\n\nexport const LogFiltersFormSchema = z.object({\n\tlimit: z.string().or(z.undefined()).or(z.null()).optional(),\n\tlevel: z.enum(['notify', 'error', 'warn', 'info', 'debug', 'trace', 'undefined']).or(z.undefined()).or(z.null())\n\t\t.optional(),\n\tfrom: z.string().or(z.undefined()).or(z.null()).optional(),\n\tuntil: z.string().or(z.undefined()).or(z.null()).optional(),\n\tlog_name: z.enum(['hdb.log', 'system.log']).or(z.undefined()).or(z.null()).optional(),\n\tfilter: z.string().or(z.undefined()).or(z.null()).optional(),\n});\n","import { Button } from '@/components/ui/button';\nimport { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';\nimport { LogFiltersFormSchema } from '@/integrations/api/instance/status/logFiltersFormSchema';\nimport { cn } from '@/lib/cn';\nimport { ChevronDownIcon, SearchIcon, SlidersHorizontalIcon } from 'lucide-react';\nimport { useState } from 'react';\nimport { UseFormReturn } from 'react-hook-form';\nimport z from 'zod';\n\nexport function LogsFiltersForm({\n\tform,\n\tresetFilters,\n\tsubmitFilters,\n\tshowLogName,\n\tshowFilter,\n}: {\n\tform: UseFormReturn<z.infer<typeof LogFiltersFormSchema>>;\n\tresetFilters: () => void;\n\tsubmitFilters: (data: z.infer<typeof LogFiltersFormSchema>) => void;\n\tshowLogName?: boolean;\n\tshowFilter?: boolean;\n}) {\n\tconst [isOpen, setIsOpen] = useState(false);\n\n\treturn (\n\t\t<Card>\n\t\t\t<CardHeader>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tonClick={() => setIsOpen((open) => !open)}\n\t\t\t\t\taria-expanded={isOpen}\n\t\t\t\t\taria-controls=\"logs-filters-content\"\n\t\t\t\t\tclassName=\"flex w-full items-center justify-between md:pointer-events-none\"\n\t\t\t\t>\n\t\t\t\t\t<CardTitle className=\"flex items-center gap-2 text-base\">\n\t\t\t\t\t\t<SlidersHorizontalIcon className=\"size-4 text-muted-foreground\" />\n\t\t\t\t\t\tFilters\n\t\t\t\t\t</CardTitle>\n\t\t\t\t\t<ChevronDownIcon\n\t\t\t\t\t\tclassName={cn('size-4 text-muted-foreground transition-transform md:hidden', isOpen && 'rotate-180')}\n\t\t\t\t\t/>\n\t\t\t\t</button>\n\t\t\t</CardHeader>\n\t\t\t<CardContent id=\"logs-filters-content\" className={cn(!isOpen && 'hidden', 'md:block')}>\n\t\t\t\t<Form {...form}>\n\t\t\t\t\t<form\n\t\t\t\t\t\tid=\"instance-edit-log-filters-form\"\n\t\t\t\t\t\tname=\"instance-edit-log-filters-form\"\n\t\t\t\t\t\tonSubmit={form.handleSubmit(submitFilters)}\n\t\t\t\t\t\tclassName=\"flex-col space-y-4\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{showFilter && (\n\t\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\t\tname=\"filter\"\n\t\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t\t<div className=\"relative\">\n\t\t\t\t\t\t\t\t\t\t\t\t<SearchIcon className=\"pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground\" />\n\t\t\t\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"search\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tplaceholder=\"Search logs…\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"pl-9\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tvalue={field.value ?? ''}\n\t\t\t\t\t\t\t\t\t\t\t\t\tonChange={field.onChange}\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{showLogName && (\n\t\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\t\tname=\"log_name\"\n\t\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t\t<FormLabel>Log file</FormLabel>\n\t\t\t\t\t\t\t\t\t\t<Select onValueChange={field.onChange} value={field.value ?? undefined}>\n\t\t\t\t\t\t\t\t\t\t\t<SelectTrigger className=\"w-full bg-white dark:bg-grey-700\">\n\t\t\t\t\t\t\t\t\t\t\t\t<SelectValue placeholder=\"Select log file\" />\n\t\t\t\t\t\t\t\t\t\t\t</SelectTrigger>\n\t\t\t\t\t\t\t\t\t\t\t<SelectContent>\n\t\t\t\t\t\t\t\t\t\t\t\t<SelectGroup>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<SelectItem value=\"hdb.log\">Application (hdb.log)</SelectItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<SelectItem value=\"system.log\">System (system.log)</SelectItem>\n\t\t\t\t\t\t\t\t\t\t\t\t</SelectGroup>\n\t\t\t\t\t\t\t\t\t\t\t</SelectContent>\n\t\t\t\t\t\t\t\t\t\t</Select>\n\t\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<div className=\"grid grid-cols-2 gap-3\">\n\t\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\t\tname=\"limit\"\n\t\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t\t<FormLabel>Limit</FormLabel>\n\t\t\t\t\t\t\t\t\t\t<Select onValueChange={field.onChange} value={field.value ?? undefined}>\n\t\t\t\t\t\t\t\t\t\t\t<SelectTrigger className=\"w-full bg-white dark:bg-grey-700\">\n\t\t\t\t\t\t\t\t\t\t\t\t<SelectValue placeholder=\"Limit\" />\n\t\t\t\t\t\t\t\t\t\t\t</SelectTrigger>\n\t\t\t\t\t\t\t\t\t\t\t<SelectContent>\n\t\t\t\t\t\t\t\t\t\t\t\t<SelectGroup>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<SelectItem value=\"1000\">1000</SelectItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<SelectItem value=\"500\">500</SelectItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<SelectItem value=\"250\">250</SelectItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<SelectItem value=\"100\">100</SelectItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<SelectItem value=\"10\">10</SelectItem>\n\t\t\t\t\t\t\t\t\t\t\t\t</SelectGroup>\n\t\t\t\t\t\t\t\t\t\t\t</SelectContent>\n\t\t\t\t\t\t\t\t\t\t</Select>\n\t\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\t\tname=\"level\"\n\t\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t\t<FormLabel>Level</FormLabel>\n\t\t\t\t\t\t\t\t\t\t<Select onValueChange={field.onChange} value={field.value ?? undefined}>\n\t\t\t\t\t\t\t\t\t\t\t<SelectTrigger className=\"w-full bg-white dark:bg-grey-700\">\n\t\t\t\t\t\t\t\t\t\t\t\t<SelectValue placeholder=\"Level\" />\n\t\t\t\t\t\t\t\t\t\t\t</SelectTrigger>\n\t\t\t\t\t\t\t\t\t\t\t<SelectContent>\n\t\t\t\t\t\t\t\t\t\t\t\t<SelectGroup>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<SelectItem value=\"undefined\">All</SelectItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<SelectItem value=\"notify\">Notify</SelectItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<SelectItem value=\"error\">Error</SelectItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<SelectItem value=\"warn\">Warn</SelectItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<SelectItem value=\"info\">Info</SelectItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<SelectItem value=\"debug\">Debug</SelectItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<SelectItem value=\"trace\">Trace</SelectItem>\n\t\t\t\t\t\t\t\t\t\t\t\t</SelectGroup>\n\t\t\t\t\t\t\t\t\t\t\t</SelectContent>\n\t\t\t\t\t\t\t\t\t\t</Select>\n\t\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"from\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t<FormLabel>Start date</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Input type=\"datetime-local\" value={field.value ?? undefined} onChange={field.onChange} />\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<FormField\n\t\t\t\t\t\t\tcontrol={form.control}\n\t\t\t\t\t\t\tname=\"until\"\n\t\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t\t<FormLabel>End date</FormLabel>\n\t\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t\t<Input type=\"datetime-local\" value={field.value ?? undefined} onChange={field.onChange} />\n\t\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t<div className=\"flex items-center gap-2 pt-1\">\n\t\t\t\t\t\t\t<Button type=\"submit\" variant=\"positiveOutline\" className=\"grow\">\n\t\t\t\t\t\t\t\tApply Filters\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t<Button type=\"reset\" variant=\"destructiveOutline\" onClick={resetFilters}>\n\t\t\t\t\t\t\t\tClear\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</form>\n\t\t\t\t</Form>\n\t\t\t</CardContent>\n\t\t</Card>\n\t);\n}\n","import { Badge } from '@/components/ui/badge';\nimport { Button } from '@/components/ui/button';\nimport { Skeleton } from '@/components/ui/skeleton';\nimport { Toggle } from '@/components/ui/toggle';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';\nimport { renderBadgeLogLevelVariant } from '@/components/ui/utils/badgeLogLevel';\nimport { BadgeNodeVariantValues, memoizeNodeNames } from '@/components/ui/utils/badgeNode';\nimport { isLocalStudio } from '@/config/constants';\nimport { useInstanceClientIdParams } from '@/config/useInstanceClient';\nimport { LogsDataTable } from '@/features/instance/log/LogsDataTable';\nimport { ViewLogModal } from '@/features/instance/log/modals/ViewLogModal';\nimport { useRefreshClick } from '@/hooks/useRefreshClick';\nimport { getReadLogQueryOptions, ReadLogItem } from '@/integrations/api/instance/status/getReadLog';\nimport { getRegistrationInfoQueryOptions } from '@/integrations/api/instance/status/getRegistrationInfo';\nimport { LogFiltersFormSchema } from '@/integrations/api/instance/status/logFiltersFormSchema';\nimport { capitalizeWords } from '@/lib/string/capitalizeWords';\nimport { wasAReleasedBeforeB } from '@/lib/string/wasAReleasedBeforeB';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useQuery } from '@tanstack/react-query';\nimport { ColumnDef } from '@tanstack/react-table';\nimport {\n\tActivityIcon,\n\tAlertCircleIcon,\n\tAlertTriangleIcon,\n\tBellIcon,\n\tBugIcon,\n\tInfoIcon,\n\tRefreshCwIcon,\n\tTerminalIcon,\n} from 'lucide-react';\nimport { useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { z } from 'zod';\nimport { LogsFiltersForm } from './components/LogsFiltersForm';\n\ntype RowData = {\n\toriginal: ReadLogItem;\n};\n\nconst defaultFormValues: z.infer<typeof LogFiltersFormSchema> = {\n\tlog_name: 'hdb.log',\n\tlimit: '100',\n\tlevel: 'undefined',\n\tfrom: '',\n\tuntil: '',\n\tfilter: '',\n};\n\nconst levelIcons: Record<ReadLogItem['level'], React.ReactNode> = {\n\terror: <AlertCircleIcon className=\"size-3\" />,\n\tstderr: <AlertCircleIcon className=\"size-3\" />,\n\twarn: <AlertTriangleIcon className=\"size-3\" />,\n\tnotify: <BellIcon className=\"size-3\" />,\n\tinfo: <InfoIcon className=\"size-3\" />,\n\tdebug: <BugIcon className=\"size-3\" />,\n\ttrace: <ActivityIcon className=\"size-3\" />,\n\tstdout: <TerminalIcon className=\"size-3\" />,\n};\n\nconst columns: ColumnDef<ReadLogItem>[] = [\n\t{\n\t\taccessorKey: 'level',\n\t\theader: 'Level',\n\t\tcell: ({ row }) => {\n\t\t\tconst { level } = row.original;\n\t\t\treturn (\n\t\t\t\t<Badge variant={renderBadgeLogLevelVariant(level)}>\n\t\t\t\t\t{levelIcons[level]}\n\t\t\t\t\t{capitalizeWords(level)}\n\t\t\t\t</Badge>\n\t\t\t);\n\t\t},\n\t},\n\t{\n\t\taccessorKey: 'timestamp',\n\t\theader: 'Timestamp',\n\t\tcell: ({ row }) => {\n\t\t\tconst { timestamp } = row.original;\n\t\t\tconst date = new Date(timestamp);\n\t\t\tconst sameYear = date.getFullYear() === new Date().getFullYear();\n\t\t\tconst dateStr = sameYear\n\t\t\t\t? date.toLocaleDateString(undefined, { month: 'numeric', day: '2-digit' })\n\t\t\t\t: date.toLocaleDateString();\n\t\t\treturn (\n\t\t\t\t<span className=\"tabular-nums whitespace-nowrap text-muted-foreground\">\n\t\t\t\t\t{dateStr} {date.toLocaleTimeString()}\n\t\t\t\t</span>\n\t\t\t);\n\t\t},\n\t},\n\t{\n\t\taccessorKey: 'message',\n\t\theader: 'Message',\n\t\tcell: ({ row }) => {\n\t\t\tconst { message } = row.original;\n\t\t\treturn (\n\t\t\t\t<span className=\"block max-w-xl truncate font-mono text-xs\">\n\t\t\t\t\t{message}\n\t\t\t\t</span>\n\t\t\t);\n\t\t},\n\t},\n\t{\n\t\taccessorKey: 'thread',\n\t\theader: 'Thread',\n\t\tcell: ({ row }) => <span className=\"text-muted-foreground tabular-nums\">{row.original.thread}</span>,\n\t},\n\t{\n\t\taccessorKey: 'node',\n\t\theader: 'Node',\n\t\tcell: ({ row }) => {\n\t\t\tconst { node } = row.original;\n\t\t\tconst variant: BadgeNodeVariantValues = memoizeNodeNames(node);\n\t\t\treturn (\n\t\t\t\t<>\n\t\t\t\t\t{node\n\t\t\t\t\t\t? (\n\t\t\t\t\t\t\t<Tooltip>\n\t\t\t\t\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t\t\t\t\t<Badge variant={variant}>{node.split('.')[0]}...</Badge>\n\t\t\t\t\t\t\t\t</TooltipTrigger>\n\t\t\t\t\t\t\t\t<TooltipContent\n\t\t\t\t\t\t\t\t\tclassName=\"bg-popover text-popover-foreground border border-border\"\n\t\t\t\t\t\t\t\t\tarrowClassName=\"bg-popover fill-popover\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{node}\n\t\t\t\t\t\t\t\t</TooltipContent>\n\t\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t)\n\t\t\t\t\t\t: null}\n\t\t\t\t</>\n\t\t\t);\n\t\t},\n\t},\n\t{\n\t\taccessorKey: 'tags',\n\t\theader: 'Tags',\n\t\tcell: ({ row }) => {\n\t\t\tconst { tags } = row.original;\n\t\t\treturn tags && tags.length > 0\n\t\t\t\t? <span className=\"text-muted-foreground text-xs\">{tags}</span>\n\t\t\t\t: null;\n\t\t},\n\t},\n];\n\nconst isValidDateRange = (startDate?: string | null, endDate?: string | null) => {\n\tif (!startDate && !endDate) { return true; }\n\tif (!startDate || !endDate) { return true; }\n\n\tconst start = new Date(startDate);\n\tconst end = new Date(endDate);\n\treturn start <= end;\n};\n\nfunction LogsTableSkeleton() {\n\treturn (\n\t\t<div className=\"rounded-md bg-card dark:bg-black-dark overflow-hidden\">\n\t\t\t<div className=\"flex gap-4 p-4 border-b border-border\">\n\t\t\t\t{['w-14', 'w-32', 'w-14', 'w-24', 'w-16', 'flex-1'].map((w, i) => <Skeleton key={i} className={`h-4 ${w}`} />)}\n\t\t\t</div>\n\t\t\t{Array.from({ length: 12 }).map((_, i) => (\n\t\t\t\t<div key={i} className=\"flex gap-4 p-3 border-b border-border/40 border-l-2 border-l-transparent\">\n\t\t\t\t\t<Skeleton className=\"h-5 w-14\" />\n\t\t\t\t\t<Skeleton className=\"h-5 w-32\" />\n\t\t\t\t\t<Skeleton className=\"h-5 w-10\" />\n\t\t\t\t\t<Skeleton className=\"h-5 w-20\" />\n\t\t\t\t\t<Skeleton className=\"h-5 w-12\" />\n\t\t\t\t\t<Skeleton className=\"h-5 flex-1 max-w-xs\" />\n\t\t\t\t</div>\n\t\t\t))}\n\t\t</div>\n\t);\n}\n\nexport function Logs() {\n\tconst [logFilters, setLogFilters] = useState<z.infer<typeof LogFiltersFormSchema>>(defaultFormValues);\n\n\tconst [isViewLogModalOpen, setIsViewLogModalOpen] = useState(false);\n\tconst [selectedLogData, setSelectedLogData] = useState<ReadLogItem | undefined>();\n\tconst [isAutoRefreshEnabled, setIsAutoRefreshEnabled] = useState(false);\n\n\tconst instanceParams = useInstanceClientIdParams();\n\n\tconst { data: registrationInfo } = useQuery(getRegistrationInfoQueryOptions(instanceParams));\n\tconst version = registrationInfo?.version;\n\tconst showLogName = !isLocalStudio && !!version && wasAReleasedBeforeB('5.0.13', version);\n\tconst showFilter = !!version && wasAReleasedBeforeB('4.7.16', version);\n\n\tconst {\n\t\tdata: instanceLogs,\n\t\tisLoading,\n\t\trefetch: refetchReadLogQueryOptions,\n\t\tisFetching: isFetchingInstanceLogs,\n\t} = useQuery(\n\t\tgetReadLogQueryOptions({\n\t\t\tlogFilters,\n\t\t\t...instanceParams,\n\t\t\treplicated: instanceParams.entityType === 'cluster',\n\t\t\tisAutoRefreshEnabled,\n\t\t}),\n\t);\n\n\tconst form = useForm({\n\t\tresolver: zodResolver(LogFiltersFormSchema),\n\t\tdefaultValues: defaultFormValues,\n\t\tmode: 'onChange',\n\t});\n\n\tconst onRowClick = (rowData: RowData): void => {\n\t\tsetSelectedLogData(rowData.original);\n\t\tsetIsViewLogModalOpen(true);\n\t};\n\n\tconst submitFilters = async (data: z.infer<typeof LogFiltersFormSchema>) => {\n\t\tif (!isValidDateRange(data.from, data.until)) {\n\t\t\tform.setError('from', {\n\t\t\t\ttype: 'onChange',\n\t\t\t\tmessage: 'Start date must be before end date',\n\t\t\t});\n\t\t\tform.setError('until', {\n\t\t\t\ttype: 'onChange',\n\t\t\t\tmessage: 'End date must be after start date',\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tsetLogFilters(data);\n\t};\n\n\tconst resetFilters = async () => {\n\t\tform.reset();\n\t\tsetLogFilters(defaultFormValues);\n\t};\n\n\tconst onRefreshClick = useRefreshClick(refetchReadLogQueryOptions);\n\n\treturn (\n\t\t<div className=\"grid grid-cols-1 gap-4 pt-2 text-foreground md:grid-cols-12\">\n\t\t\t<section className=\"col-span-1 md:col-span-4 lg:col-span-3 px-2 pb-4 md:self-start md:sticky md:top-34 md:max-h-[calc(100vh-(--spacing(34)))] md:overflow-y-auto\">\n\t\t\t\t<LogsFiltersForm\n\t\t\t\t\tform={form}\n\t\t\t\t\tresetFilters={resetFilters}\n\t\t\t\t\tsubmitFilters={submitFilters}\n\t\t\t\t\tshowLogName={showLogName}\n\t\t\t\t\tshowFilter={showFilter}\n\t\t\t\t/>\n\n\t\t\t\t<div className=\"flex items-center gap-2 mt-3\">\n\t\t\t\t\t<Button\n\t\t\t\t\t\tvariant=\"defaultOutline\"\n\t\t\t\t\t\tonClick={onRefreshClick}\n\t\t\t\t\t\tdisabled={isFetchingInstanceLogs || isLoading || isAutoRefreshEnabled}\n\t\t\t\t\t\tclassName=\"grow\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<RefreshCwIcon />\n\t\t\t\t\t\tRefresh\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Tooltip>\n\t\t\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t\t\t<Toggle\n\t\t\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\t\t\taria-label=\"Toggle Auto Refresh\"\n\t\t\t\t\t\t\t\tpressed={isAutoRefreshEnabled}\n\t\t\t\t\t\t\t\tonPressedChange={setIsAutoRefreshEnabled}\n\t\t\t\t\t\t\t\tclassName=\"shrink-0\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<RefreshCwIcon className={isAutoRefreshEnabled ? 'animate-spin' : ''} />\n\t\t\t\t\t\t\t\tAuto\n\t\t\t\t\t\t\t</Toggle>\n\t\t\t\t\t\t</TooltipTrigger>\n\t\t\t\t\t\t<TooltipContent>\n\t\t\t\t\t\t\t{isAutoRefreshEnabled ? 'Auto refresh on — click to disable' : 'Enable auto refresh (every 5s)'}\n\t\t\t\t\t\t</TooltipContent>\n\t\t\t\t\t</Tooltip>\n\t\t\t\t</div>\n\t\t\t</section>\n\t\t\t<section className=\"col-span-1 md:col-span-8 lg:col-span-9\">\n\t\t\t\t{isLoading\n\t\t\t\t\t? <LogsTableSkeleton />\n\t\t\t\t\t: <LogsDataTable columns={columns} data={instanceLogs || []} onRowClick={onRowClick} />}\n\t\t\t</section>\n\t\t\t<ViewLogModal isModalOpen={isViewLogModalOpen} setIsModalOpen={setIsViewLogModalOpen} data={selectedLogData} />\n\t\t</div>\n\t);\n}\n","import { createInstanceLayoutRoute } from '@/features/instance/instanceLayoutRoute';\nimport { Logs } from '@/features/instance/log/index';\nimport { createRoute } from '@tanstack/react-router';\n\nexport function createLogRouteTree(instanceLayoutRoute: ReturnType<typeof createInstanceLayoutRoute>) {\n\treturn createRoute({\n\t\tgetParentRoute: () => instanceLayoutRoute,\n\t\tpath: 'logs',\n\t\thead: () => ({ meta: [{ title: 'Logs — Harper Fabric' }] }),\n\t\tcomponent: Logs,\n\t});\n}\n","import { createInstanceLayoutRoute } from '@/features/instance/instanceLayoutRoute';\nimport { createRoute, lazyRouteComponent } from '@tanstack/react-router';\n\nexport function createStatusRouteTree(instanceLayoutRoute: ReturnType<typeof createInstanceLayoutRoute>) {\n\tconst instanceConfigRoute = createRoute({\n\t\tgetParentRoute: () => instanceLayoutRoute,\n\t\tpath: 'status',\n\t\thead: () => ({ meta: [{ title: 'Status — Harper Fabric' }] }),\n\t\tcomponent: lazyRouteComponent(async () => import('@/features/instance/status/index'), 'StatusIndex'),\n\t});\n\treturn instanceConfigRoute;\n}\n","import { createAPIsRouteTree } from '@/features/instance/apis/routes';\nimport { createApplicationsRoutes } from '@/features/instance/applications/routes';\nimport { createConfigRouteTree } from '@/features/instance/config/routes';\nimport { createBrowseRouteTree } from '@/features/instance/databases/routes';\nimport { createInstanceLayoutRoute } from '@/features/instance/instanceLayoutRoute';\nimport { createLogRouteTree } from '@/features/instance/log/routes';\nimport { createStatusRouteTree } from '@/features/instance/status/routes';\n\nexport function createInstanceRouteTree(mode: 'local' | 'cluster' | 'instance') {\n\tconst instanceLayoutRoute = createInstanceLayoutRoute(mode);\n\n\tconst children = [\n\t\tcreateLogRouteTree(instanceLayoutRoute),\n\t\t...createApplicationsRoutes(instanceLayoutRoute),\n\t\tcreateAPIsRouteTree(instanceLayoutRoute),\n\t\tcreateStatusRouteTree(instanceLayoutRoute),\n\t\tcreateConfigRouteTree(instanceLayoutRoute),\n\t\tcreateBrowseRouteTree(instanceLayoutRoute),\n\t];\n\n\treturn instanceLayoutRoute.addChildren(children);\n}\n","import { dashboardLayout } from '@/router/dashboardRoute';\nimport { createRoute, lazyRouteComponent } from '@tanstack/react-router';\n\nconst profileRoute = createRoute({\n\tgetParentRoute: () => dashboardLayout,\n\tpath: 'profile',\n\thead: () => ({ meta: [{ title: 'Profile — Harper Fabric' }] }),\n\tcomponent: lazyRouteComponent(async () => import('@/features/profile/index'), 'ProfileIndex'),\n});\n\nexport const profileRoutes = [profileRoute];\n","import { isLocalStudio } from '@/config/constants';\nimport { authRouteTree, localAuthRoutes } from '@/features/auth/routes';\nimport { clusterLayoutRoute } from '@/features/cluster/clusterLayoutRoute';\nimport { clusterRoutes } from '@/features/cluster/routes';\nimport { clusterEditRoutes, clustersLayoutRoute, clustersRoutes, newClusterRoute } from '@/features/clusters/routes';\nimport { createInstanceRouteTree } from '@/features/instance/routes';\nimport { orgLayoutRoute, orgRoutes } from '@/features/organization/routes';\nimport { orgsLayoutRoute, orgsRoutes } from '@/features/organizations/routes';\nimport { profileRoutes } from '@/features/profile/routes';\nimport { dashboardLayout } from '@/router/dashboardRoute';\nimport { rootRoute } from '@/router/rootRoute';\n\nexport const rootRouteTree = isLocalStudio\n\t? rootRoute.addChildren([\n\t\t...localAuthRoutes,\n\t\tdashboardLayout.addChildren([\n\t\t\tcreateInstanceRouteTree('local'),\n\t\t]),\n\t])\n\t: rootRoute.addChildren([\n\t\tauthRouteTree,\n\t\tdashboardLayout.addChildren([\n\t\t\t...profileRoutes,\n\t\t\torgsLayoutRoute.addChildren([\n\t\t\t\t...orgsRoutes,\n\t\t\t\torgLayoutRoute.addChildren([\n\t\t\t\t\t...orgRoutes,\n\t\t\t\t\tnewClusterRoute,\n\t\t\t\t\tclustersLayoutRoute.addChildren([\n\t\t\t\t\t\t...clustersRoutes,\n\t\t\t\t\t\tclusterLayoutRoute.addChildren([\n\t\t\t\t\t\t\t...clusterRoutes,\n\t\t\t\t\t\t\t...clusterEditRoutes,\n\t\t\t\t\t\t\t// Every route nested under clusterLayoutRoute must also be wired in here,\n\t\t\t\t\t\t\t// because each declares `getParentRoute: () => clusterLayoutRoute`. Mounting\n\t\t\t\t\t\t\t// any of them a level up (under clustersLayoutRoute) makes its declared parent\n\t\t\t\t\t\t\t// a sibling, which TanStack Router 1.170 resolves into a corrupted route tree\n\t\t\t\t\t\t\t// (path params mis-parsed, `organizationId` lost → /Organization/undefined).\n\t\t\t\t\t\t\tcreateInstanceRouteTree('cluster'),\n\t\t\t\t\t\t\tcreateInstanceRouteTree('instance'),\n\t\t\t\t\t\t]),\n\t\t\t\t\t]),\n\t\t\t\t]),\n\t\t\t]),\n\t\t]),\n\t]);\n","import { ErrorComponent } from '@/components/ErrorComponent';\nimport { NotFoundComponent } from '@/components/NotFoundComponent';\nimport { AuthenticatedConnection, EntityIds } from '@/features/auth/store/authStore';\nimport { browserIsTouchBased } from '@/lib/browserIsTouchBased';\nimport { queryClient } from '@/react-query/queryClient';\nimport { rootRouteTree } from '@/router/rootRouteTree';\nimport { createHashHistory, createRouter } from '@tanstack/react-router';\n\nexport function useNewRouter({ routeTree = rootRouteTree, authentication }: {\n\trouteTree?: typeof rootRouteTree;\n\tauthentication?: Record<EntityIds, AuthenticatedConnection>;\n}) {\n\tconst hashHistory = createHashHistory();\n\treturn createRouter({\n\t\trouteTree,\n\t\thistory: hashHistory,\n\t\tdefaultNotFoundComponent: NotFoundComponent,\n\t\tdefaultErrorComponent: ErrorComponent,\n\t\tdefaultPreload: browserIsTouchBased() ? false : 'intent',\n\t\ttrailingSlash: 'never',\n\t\t// Since we're using React Query, we don't want loader calls to ever be stale\n\t\t// This will ensure that the loader is always called when the route is preloaded or visited\n\t\tdefaultPreloadStaleTime: 0,\n\t\tscrollRestoration: true,\n\t\tcontext: {\n\t\t\tqueryClient,\n\t\t\tauthentication: authentication || {},\n\t\t},\n\t});\n}\n","import { useRootAuthenticationContext } from '@/hooks/useAuth';\nimport { useNewRouter } from '@/router/useNewRouter';\nimport { RouterProvider } from '@tanstack/react-router';\nimport { TanStackRouterDevtools } from '@tanstack/react-router-devtools';\n\nexport function AppRouted() {\n\tconst authentication = useRootAuthenticationContext();\n\tconst router = useNewRouter({ authentication });\n\treturn (\n\t\t<>\n\t\t\t<RouterProvider router={router} context={{ authentication }} />\n\t\t\t{!import.meta.env.VITE_DISABLE_DEVTOOLS && <TanStackRouterDevtools router={router} position=\"bottom-right\" />}\n\t\t</>\n\t);\n}\n","// import { useTheme } from 'next-themes';\nimport { Toaster as Sonner, ToasterProps } from 'sonner';\n\nconst Toaster = ({ ...props }: ToasterProps) => {\n\t// const { theme = 'system' } = useTheme();\n\n\treturn (\n\t\t<Sonner\n\t\t\t// theme={theme as ToasterProps['theme']}\n\t\t\tclassName=\"toaster group\"\n\t\t\ttoastOptions={{\n\t\t\t\tclassNames: {\n\t\t\t\t\ttoast:\n\t\t\t\t\t\t'group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg',\n\t\t\t\t\tdescription: 'group-[.toast]:text-muted-foreground',\n\t\t\t\t\tactionButton: 'group-[.toast]:bg-primary group-[.toast]:text-primary-foreground font-medium',\n\t\t\t\t\tcancelButton: 'group-[.toast]:bg-muted group-[.toast]:text-muted-foreground font-medium',\n\t\t\t\t},\n\t\t\t}}\n\t\t\t{...props}\n\t\t/>\n\t);\n};\n\nexport { Toaster };\n","import { isLocalStudio } from '@/config/constants';\nimport { useEffect } from 'react';\n\nlet initialized = false;\nconst enabled = !import.meta.env.DEV && !isLocalStudio;\n\nexport function useGTM() {\n\tuseEffect(() => {\n\t\tif (initialized) {\n\t\t\treturn;\n\t\t}\n\t\tinitialized = true;\n\t\tif (enabled) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\t(function(w: any, d: any, s, l, i) {\n\t\t\t\tw[l] = w[l] || [];\n\t\t\t\tw[l].push({\n\t\t\t\t\t'gtm.start': new Date().getTime(),\n\t\t\t\t\tevent: 'gtm.js',\n\t\t\t\t});\n\t\t\t\tconst f = d.getElementsByTagName(s)[0];\n\t\t\t\tconst j = d.createElement(s);\n\t\t\t\tconst dl = l !== 'dataLayer' ? `&l=${l}` : '';\n\t\t\t\tj.async = true;\n\t\t\t\tj.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl;\n\t\t\t\tf.parentNode.insertBefore(j, f);\n\t\t\t})(window, document, 'script', 'dataLayer', 'GTM-5QQX432');\n\t\t}\n\t}, []);\n}\n","import { AppRouted } from '@/AppRouted';\nimport { Toaster } from '@/components/ui/sonner';\nimport { ThemeProvider } from '@/hooks/useTheme';\nimport { useDatadog } from '@/integrations/datadog/datadog';\nimport { useGTM } from '@/integrations/google/gtm';\nimport { useReo } from '@/integrations/reo/reo';\nimport { queryClient } from '@/react-query/queryClient';\nimport { QueryClientProvider } from '@tanstack/react-query';\nimport { ReactQueryDevtools } from '@tanstack/react-query-devtools';\n\nexport function App() {\n\tuseReo();\n\tuseDatadog();\n\tuseGTM();\n\treturn (\n\t\t<ThemeProvider>\n\t\t\t<QueryClientProvider client={queryClient}>\n\t\t\t\t<AppRouted />\n\t\t\t\t{!import.meta.env.VITE_DISABLE_DEVTOOLS && <ReactQueryDevtools buttonPosition=\"bottom-right\" />}\n\t\t\t</QueryClientProvider>\n\t\t\t<Toaster richColors />\n\t\t</ThemeProvider>\n\t);\n}\n","import { App } from '@/App';\nimport { addReactError } from '@datadog/browser-rum-react';\nimport { StrictMode } from 'react';\nimport { createRoot } from 'react-dom/client';\nimport './index.css';\n\ncreateRoot(\n\tdocument.getElementById('root')!,\n\t{\n\t\tonUncaughtError: (error, errorInfo) => {\n\t\t\t// Report uncaught errors to Datadog\n\t\t\taddReactError(error as Error, errorInfo);\n\t\t\tconsole.error('Uncaught error:', error, errorInfo);\n\t\t},\n\t\tonCaughtError: (error, errorInfo) => {\n\t\t\t// Report caught errors to Datadog\n\t\t\taddReactError(error as Error, errorInfo);\n\t\t\tconsole.error('Caught error:', error, errorInfo);\n\t\t},\n\t\tonRecoverableError: (error, errorInfo) => {\n\t\t\t// Report recoverable errors to Datadog\n\t\t\taddReactError(error as Error, errorInfo);\n\t\t\tconsole.warn('Recoverable error:', error, errorInfo);\n\t\t},\n\t},\n).render(\n\t<StrictMode>\n\t\t<App />\n\t</StrictMode>,\n);\n"],"file":"index-oRZw5GW3.js"}