From 641b4c52f342c8ab7eb12792d9374000dd0e764a Mon Sep 17 00:00:00 2001 From: Jake Laderman Date: Tue, 27 Aug 2024 19:45:06 -0400 Subject: [PATCH 01/17] implement new home page, add route for new cluster-create screen --- www/index.html | 1 + www/src/App.tsx | 6 +- www/src/components/Plural.tsx | 17 +- www/src/components/app/App.tsx | 3 +- www/src/components/cluster/Cluster.tsx | 3 +- .../create-cluster/CreateCluster.tsx | 3 + .../components/layout/ApplicationLayout.tsx | 16 +- www/src/components/overview/Overview.tsx | 10 +- .../components/overview/OverviewHeader.tsx | 17 +- www/src/components/overview/apps/Apps.tsx | 14 -- .../clusters/ClusterListEmptyState.tsx | 90 ++++--- .../components/overview/clusters/Clusters.tsx | 31 ++- .../overview/clusters/ClustersHelpSection.tsx | 234 +++++------------- 13 files changed, 158 insertions(+), 287 deletions(-) create mode 100644 www/src/components/create-cluster/CreateCluster.tsx delete mode 100644 www/src/components/overview/apps/Apps.tsx diff --git a/www/index.html b/www/index.html index 2c5fd41cf..fdf05e697 100644 --- a/www/index.html +++ b/www/index.html @@ -136,6 +136,7 @@ html, body { background-color: #171a21; + overflow: auto hidden; } html[data-theme-mode='light'], html[data-theme-mode='light'] body { diff --git a/www/src/App.tsx b/www/src/App.tsx index d31a4075a..e38381a83 100644 --- a/www/src/App.tsx +++ b/www/src/App.tsx @@ -79,10 +79,10 @@ const SSOCallback = lazy(() => const RootBoxSC = styled.div(({ theme }) => ({ display: 'flex', - flexdirection: 'column', + flexDirection: 'column', boxSizing: 'border-box', - maxwidth: '100%', - minwidth: 0, + maxWidth: '100%', + minWidth: 0, minHeight: 0, height: '100vh', width: '100vw', diff --git a/www/src/components/Plural.tsx b/www/src/components/Plural.tsx index 0857ee7c2..ca6c635f7 100644 --- a/www/src/components/Plural.tsx +++ b/www/src/components/Plural.tsx @@ -76,8 +76,12 @@ const Clusters = lazy(() => default: module.Clusters, })) ) -const Apps = lazy(() => - import('./overview/apps/Apps').then((module) => ({ default: module.Apps })) + +// Create cluster. +const CreateCluster = lazy(() => + import('./create-cluster/CreateCluster').then((module) => ({ + default: module.CreateCluster, + })) ) // Cluster and app. @@ -638,11 +642,12 @@ export function PluralInner() { path="clusters" element={} /> - } - /> + {/* CREATE CLUSTER */} + } + /> {/* CLUSTERS */} Create Cluster +} diff --git a/www/src/components/layout/ApplicationLayout.tsx b/www/src/components/layout/ApplicationLayout.tsx index 76f8f8dfe..5a1cba933 100644 --- a/www/src/components/layout/ApplicationLayout.tsx +++ b/www/src/components/layout/ApplicationLayout.tsx @@ -1,13 +1,12 @@ -import { A, Flex, Span } from 'honorable' import { Toast } from '@pluralsh/design-system' +import { A, Flex, Span } from 'honorable' import BillingMigrationModal from '../account/billing/BillingMigrationModal' -import Sidebar from './Sidebar' -import WithApplicationUpdate from './WithApplicationUpdate' import Header from './Header' +import Sidebar from './Sidebar' import Subheader from './Subheader' -import { ContentOverlay } from './Overlay' +import WithApplicationUpdate from './WithApplicationUpdate' function ApplicationLayout({ children }: any) { const isProduction = import.meta.env.MODE === 'production' @@ -16,14 +15,12 @@ function ApplicationLayout({ children }: any) { <> {isProduction && ( @@ -51,15 +48,14 @@ function ApplicationLayout({ children }: any) { minWidth={0} minHeight={0} flexGrow={1} + overflowX="auto" > - {children} diff --git a/www/src/components/overview/Overview.tsx b/www/src/components/overview/Overview.tsx index bd6d63fd6..78753483b 100644 --- a/www/src/components/overview/Overview.tsx +++ b/www/src/components/overview/Overview.tsx @@ -1,9 +1,13 @@ -import { ReactElement } from 'react' +import { ReactElement, useContext } from 'react' import { Outlet } from 'react-router-dom' import { Flex } from 'honorable' import { useSetBreadcrumbs } from '@pluralsh/design-system' +import ClustersContext from 'contexts/ClustersContext' + +import { isEmpty } from 'lodash' + import OverviewHeader from './OverviewHeader' export const CLUSTERS_ROOT_CRUMB = { label: 'clusters', url: '/overview' } @@ -13,6 +17,8 @@ const breadcrumbs = [ ] export function Overview(): ReactElement { + const { clusters } = useContext(ClustersContext) + useSetBreadcrumbs(breadcrumbs) return ( @@ -22,7 +28,7 @@ export function Overview(): ReactElement { padding="large" overflowY="auto" > - + {!isEmpty(clusters) && } ) diff --git a/www/src/components/overview/OverviewHeader.tsx b/www/src/components/overview/OverviewHeader.tsx index 0c81e2b68..78c7fc1cc 100644 --- a/www/src/components/overview/OverviewHeader.tsx +++ b/www/src/components/overview/OverviewHeader.tsx @@ -1,19 +1,16 @@ -import { SubTab, TabList } from '@pluralsh/design-system' +import { Button, SubTab, TabList } from '@pluralsh/design-system' import { Flex } from 'honorable' import { ReactElement, useRef } from 'react' -import { useLocation } from 'react-router-dom' +import { useLocation, useNavigate } from 'react-router-dom' import { LinkTabWrap } from '../utils/Tabs' -import CreateClusterButton from './CreateClusterAction' - -const DIRECTORY = [ - { path: '/overview/clusters', label: 'Cluster overview' }, - // { path: '/overview/apps', label: 'Installed applications' }, -] +// TODO: add toggle between self-hosted and plural-cloud instances +const DIRECTORY = [{ path: '/overview/clusters', label: 'Cluster overview' }] export default function OverviewHeader(): ReactElement { const tabStateRef = useRef(null) + const navigate = useNavigate() const { pathname } = useLocation() const currentTab = DIRECTORY.find((tab) => pathname?.startsWith(tab.path)) @@ -39,7 +36,9 @@ export default function OverviewHeader(): ReactElement { ))} - + ) } diff --git a/www/src/components/overview/apps/Apps.tsx b/www/src/components/overview/apps/Apps.tsx deleted file mode 100644 index e8cb8ea56..000000000 --- a/www/src/components/overview/apps/Apps.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { useSetBreadcrumbs } from '@pluralsh/design-system' - -import { CLUSTERS_ROOT_CRUMB } from '../Overview' - -const breadcrumbs = [ - CLUSTERS_ROOT_CRUMB, - { label: 'installed apps', url: '/overview/apps' }, -] - -export function Apps(): null { - useSetBreadcrumbs(breadcrumbs) - - return null -} diff --git a/www/src/components/overview/clusters/ClusterListEmptyState.tsx b/www/src/components/overview/clusters/ClusterListEmptyState.tsx index 712f7b3bc..bc782fa5f 100644 --- a/www/src/components/overview/clusters/ClusterListEmptyState.tsx +++ b/www/src/components/overview/clusters/ClusterListEmptyState.tsx @@ -1,57 +1,51 @@ -import { BrowseAppsIcon, Button, Card } from '@pluralsh/design-system' -import { Div, Flex } from 'honorable' -import { Link } from 'react-router-dom' +import { Button, Card, ClusterIcon, Flex } from '@pluralsh/design-system' +import { useNavigate } from 'react-router-dom' +import styled, { useTheme } from 'styled-components' export default function ClusterListEmptyState() { + const theme = useTheme() + const navigate = useNavigate() + return ( -
- - -
- Create your first cluster and install applications. -
+ + + - - + Once you create your first cluster, you will find an overview of its + details here. + - -
+ + + ) } + +const Wrapper = styled.div(({ theme }) => ({ + margin: 'auto', + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + maxWidth: '600px', + padding: `${theme.spacing.xxxlarge}px`, + gap: `${theme.spacing.medium}px`, +})) diff --git a/www/src/components/overview/clusters/Clusters.tsx b/www/src/components/overview/clusters/Clusters.tsx index 14e6b3951..ea97c79de 100644 --- a/www/src/components/overview/clusters/Clusters.tsx +++ b/www/src/components/overview/clusters/Clusters.tsx @@ -2,6 +2,8 @@ import { isEmpty } from 'lodash' import { ReactElement, useContext, useMemo } from 'react' import { useTheme } from 'styled-components' +import { useSetBreadcrumbs } from '@pluralsh/design-system' + import ClustersContext from '../../../contexts/ClustersContext' import { ClusterList } from './ClusterList' @@ -19,8 +21,17 @@ import { import Upgrades from './Upgrades' +export const CLUSTERS_ROOT_CRUMB = { label: 'clusters', url: '/overview' } + +const breadcrumbs = [ + { label: 'overview', url: '/overview/clusters' }, + CLUSTERS_ROOT_CRUMB, +] + export function Clusters(): ReactElement | null { const theme = useTheme() + + useSetBreadcrumbs(breadcrumbs) const { clusters } = useContext(ClustersContext) const columns = useMemo( @@ -37,28 +48,14 @@ export function Clusters(): ReactElement | null { [] ) - // useEffect(() => subscribeToMore({ - // document: UPGRADE_QUEUE_SUB, - // updateQuery: (prev, - // { - // subscriptionData: { - // data: { - // upgradeQueueDelta: { delta, payload }, - // }, - // }, - // }) => (delta === 'CREATE' - // ? { ...prev, upgradeQueues: [payload, ...prev.upgradeQueues] } - // : prev), - // }), - // [subscribeToMore]) - return (
{ - const smallMediaQuery = `@media only screen and (min-width: ${theme.breakpoints.desktopSmall}px)` - - return { - display: 'flex', - flexDirection: 'column', - gap: theme.spacing.medium, - marginTop: theme.spacing.xsmall, - - 'ol, ul': { - ...theme.partials.text.body2, - paddingLeft: theme.spacing.large, - }, - - ol: { - ...theme.partials.text.body2Bold, - lineHeight: '24px', - }, - - 'a.link': { - ...theme.partials.text.inlineLink, - }, - - '.get-started': { - display: 'flex', - gap: theme.spacing.medium, - - '@media (max-width: 999px)': { - flexDirection: 'column', - }, - }, - - '.video': { - [smallMediaQuery]: { - minWidth: 540, - width: 640, - }, - }, - - '.card': { - ...theme.partials.text.body2, - display: 'flex', - flexGrow: 1, - flexDirection: 'column', - padding: theme.spacing.large, - color: theme.colors['text-light'], - - '.header': { - ...theme.partials.text.overline, - color: theme.colors['text-xlight'], - marginBottom: theme.spacing.medium, - }, - - '.subheader': { - fontWeight: 600, - marginBottom: theme.spacing.medium, - }, - - '.resources': { - display: 'flex', - flexDirection: 'row', - gap: theme.spacing.xxlarge, - }, - - '.cta': { - display: 'flex', - flexGrow: 1, - alignItems: 'center', - }, - }, - } -}) - export default function ClustersHelpSection(): ReactElement { - const navigate = useNavigate() const { show } = useIntercom() return ( - -
- -
Get started in 3 easy steps
-
    -
  1. Configure your cloud and Git credentials.
  2. -
  3. Install applications.
  4. -
  5. Build and deploy to your cluster.
  6. -
-

- After these 3 steps you will be able to manage cluster and access - your applications from the Plural console. -

-
- -
-
-
- -
-
- + <> + +
Helpful resources
-
- -
-
Questions or feedback?
- -
-
-
Need support?
- -
-
-
-
+ + } + forwardedAs="a" + href="https://docs.plural.sh/getting-started/" + target="_blank" + rel="noopener noreferrer" + > + Documentation + + } + forwardedAs="a" + href="mailto:sales@plural.sh" + target="_blank" + rel="noopener noreferrer" + > + Contact sales + + } + onClick={() => show()} + > + Chat on Intercom + + + + ) } + +const ResourcesCard = styled(Card)(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + gap: theme.spacing.large, + padding: theme.spacing.xlarge, + minWidth: 'max-content', + '.header': { + ...theme.partials.text.overline, + color: theme.colors['text-xlight'], + }, +})) + +const ResourcesButton = styled(Button)({ + flex: 1, + minWidth: 'fit-content', +}) From 8326dd40387a7d23083acf440f6f0e015c1c24fd Mon Sep 17 00:00:00 2001 From: Jake Laderman Date: Wed, 28 Aug 2024 00:13:13 -0400 Subject: [PATCH 02/17] add scaffolding for wizard --- .../create-cluster/CreateCluster.tsx | 77 ++++++++++++++++++- .../create-cluster/CreateClusterWizard.tsx | 63 +++++++++++++++ .../steps/HostingOptionsStep.tsx | 9 +++ .../shell/onboarding/OnboardingCard.tsx | 2 +- 4 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 www/src/components/create-cluster/CreateClusterWizard.tsx create mode 100644 www/src/components/create-cluster/steps/HostingOptionsStep.tsx diff --git a/www/src/components/create-cluster/CreateCluster.tsx b/www/src/components/create-cluster/CreateCluster.tsx index 3f4b1b096..0133c289e 100644 --- a/www/src/components/create-cluster/CreateCluster.tsx +++ b/www/src/components/create-cluster/CreateCluster.tsx @@ -1,3 +1,78 @@ +import { + Button, + Flex, + ReturnIcon, + SendMessageIcon, + Stepper, +} from '@pluralsh/design-system' +import { useNavigate } from 'react-router-dom' +import { useTheme } from 'styled-components' + +import { useState } from 'react' + +import { + CreateClusterStepKey, + cloudSteps, + localSteps, +} from './CreateClusterWizard' + export function CreateCluster() { - return
Create Cluster
+ const theme = useTheme() + const navigate = useNavigate() + const [curStep, setCurStep] = useState( + CreateClusterStepKey.HostingOptions + ) + const [hostingOption, setHostingOption] = useState<'local' | 'cloud'>('local') + const steps = hostingOption === 'local' ? localSteps : cloudSteps + const curStepIndex = steps.findIndex((step) => step.key === curStep) + + return ( + + + + + + + + Create Cluster + + + {steps[curStepIndex]?.component} + + + ) } diff --git a/www/src/components/create-cluster/CreateClusterWizard.tsx b/www/src/components/create-cluster/CreateClusterWizard.tsx new file mode 100644 index 000000000..364b7ab43 --- /dev/null +++ b/www/src/components/create-cluster/CreateClusterWizard.tsx @@ -0,0 +1,63 @@ +import { CliIcon, CloudIcon, StepperSteps } from '@pluralsh/design-system' + +import { HostingOptionsStep } from './steps/HostingOptionsStep' + +export enum CreateClusterStepKey { + HostingOptions = 'hosting-options', + ConfigureCloudInstance = 'configure-cloud-instance', + InstallCli = 'install-cli', + Authentication = 'authentication', + DeployLocally = 'deploy-locally', +} + +type CreateClusterStep = StepperSteps[number] & { + component: React.ReactNode +} + +export const localSteps: CreateClusterStep[] = [ + { + key: CreateClusterStepKey.HostingOptions, + stepTitle: 'Hosting options', + IconComponent: CloudIcon, + component: , + }, + { + key: CreateClusterStepKey.InstallCli, + stepTitle: 'Install Plural CLI', + IconComponent: CliIcon, + component:
TODO
, + }, + { + key: CreateClusterStepKey.DeployLocally, + stepTitle: 'Deploy locally', + IconComponent: CloudIcon, + component:
TODO
, + }, +] + +export const cloudSteps: CreateClusterStep[] = [ + { + key: CreateClusterStepKey.HostingOptions, + stepTitle: 'Hosting options', + IconComponent: CloudIcon, + component: , + }, + { + key: CreateClusterStepKey.ConfigureCloudInstance, + stepTitle: 'Configure cloud instance', + IconComponent: CloudIcon, + component:
TODO
, + }, + { + key: CreateClusterStepKey.InstallCli, + stepTitle: 'Install Plural CLI', + IconComponent: CloudIcon, + component:
TODO
, + }, + { + key: CreateClusterStepKey.Authentication, + stepTitle: 'Authentication', + IconComponent: CloudIcon, + component:
TODO
, + }, +] diff --git a/www/src/components/create-cluster/steps/HostingOptionsStep.tsx b/www/src/components/create-cluster/steps/HostingOptionsStep.tsx new file mode 100644 index 000000000..88790a661 --- /dev/null +++ b/www/src/components/create-cluster/steps/HostingOptionsStep.tsx @@ -0,0 +1,9 @@ +import OnboardingCard from 'components/shell/onboarding/OnboardingCard' + +export function HostingOptionsStep() { + return ( + +
TODO
+
+ ) +} diff --git a/www/src/components/shell/onboarding/OnboardingCard.tsx b/www/src/components/shell/onboarding/OnboardingCard.tsx index e54f3a789..831c01e55 100644 --- a/www/src/components/shell/onboarding/OnboardingCard.tsx +++ b/www/src/components/shell/onboarding/OnboardingCard.tsx @@ -2,7 +2,7 @@ import { Flex, H2 } from 'honorable' interface OnboardingCardProps { title?: string - mode: 'Compact' | 'Default' + mode?: 'Compact' | 'Default' children: JSX.Element | Array | unknown } From c45216da37bd17491b1291950a199013ac60b8ed Mon Sep 17 00:00:00 2001 From: Jake Laderman Date: Wed, 28 Aug 2024 13:06:59 -0400 Subject: [PATCH 03/17] add error boundary for dev mode --- www/package.json | 3 +- www/src/App.tsx | 6 ++- .../components/utils/PluralErrorBoundary.tsx | 38 +++++++++++++++++++ www/yarn.lock | 12 ++++++ 4 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 www/src/components/utils/PluralErrorBoundary.tsx diff --git a/www/package.json b/www/package.json index 4783ef430..ec606c011 100644 --- a/www/package.json +++ b/www/package.json @@ -162,6 +162,7 @@ "lint-staged": "15.2.0", "npm-run-all": "4.1.5", "prettier": "3.0.3", + "react-error-boundary": "4.0.11", "rollup-plugin-polyfill-node": "0.12.0", "serve": "14.2.0", "source-map-explorer": "2.5.3", @@ -178,4 +179,4 @@ "lint-staged": { "./src/**/*.{js,jsx,ts,tsx,graphql,md}": "prettier --write" } -} +} \ No newline at end of file diff --git a/www/src/App.tsx b/www/src/App.tsx index e38381a83..df93ebb26 100644 --- a/www/src/App.tsx +++ b/www/src/App.tsx @@ -20,6 +20,8 @@ import { mergeDeep } from '@apollo/client/utilities' import mpRecipe from 'honorable-recipe-mp' import { GrowthBook, GrowthBookProvider } from '@growthbook/growthbook-react' +import { PluralErrorBoundary } from 'components/utils/PluralErrorBoundary' + import { client } from './helpers/client' import { INTERCOM_APP_ID } from './constants' import { DEFAULT_THEME } from './theme' @@ -184,7 +186,9 @@ function App() { theme={mergedStyledTheme as any as ThemeType} themeMode="dark" > - {routes} + + {routes} + diff --git a/www/src/components/utils/PluralErrorBoundary.tsx b/www/src/components/utils/PluralErrorBoundary.tsx new file mode 100644 index 000000000..69f7c32c2 --- /dev/null +++ b/www/src/components/utils/PluralErrorBoundary.tsx @@ -0,0 +1,38 @@ +import { Callout } from '@pluralsh/design-system' +import { ComponentProps } from 'react' +import { ErrorBoundary } from 'react-error-boundary' + +function logError(error: Error, info: { componentStack: string }) { + // Do something with the error, e.g. log to an external API + console.error('Error:', error) + console.error(`Component stack:\n${info.componentStack}`) +} + +function ErrorFallback({ error }: any) { + return ( + + {error.message} + + ) +} + +export function PluralErrorBoundary( + props: Partial> +) { + return ( + + ) +} diff --git a/www/yarn.lock b/www/yarn.lock index ffe5bacae..882931493 100644 --- a/www/yarn.lock +++ b/www/yarn.lock @@ -15548,6 +15548,17 @@ __metadata: languageName: node linkType: hard +"react-error-boundary@npm:4.0.11": + version: 4.0.11 + resolution: "react-error-boundary@npm:4.0.11" + dependencies: + "@babel/runtime": ^7.12.5 + peerDependencies: + react: ">=16.13.1" + checksum: b3c157fea4e8f78411e9aa0fbf5241f6907b66ede1cd8b7bb22faaeb0339ebeb3dc8e63bf90ef3f740bfa8fd994ca6edf975089cd371b664ad6c2735e7512d38 + languageName: node + linkType: hard + "react-fast-compare@npm:^3.0.1": version: 3.2.2 resolution: "react-fast-compare@npm:3.2.2" @@ -19894,6 +19905,7 @@ __metadata: react-dnd: 16.0.1 react-dnd-html5-backend: 16.0.1 react-dom: 18.3.1 + react-error-boundary: 4.0.11 react-file-icon: 1.3.0 react-file-picker: 0.0.6 react-icons: 4.9.0 From 3d6d0328a5da7462238b72acdb3e553c3bea89a1 Mon Sep 17 00:00:00 2001 From: Jake Laderman Date: Wed, 28 Aug 2024 15:23:10 -0400 Subject: [PATCH 04/17] add step flow and context --- .../create-cluster/CreateCluster.tsx | 87 +++++++++++++------ .../create-cluster/CreateClusterActions.tsx | 55 ++++++++++++ .../create-cluster/CreateClusterWizard.tsx | 59 ++++++++++--- .../steps/AuthenticationStep.tsx | 3 + .../steps/ConfigureCloudInstanceStep.tsx | 3 + .../steps/DeployLocallyStep.tsx | 3 + .../steps/HostingOptionsStep.tsx | 39 ++++++++- .../create-cluster/steps/InstallCliStep.tsx | 3 + .../shell/onboarding/OnboardingCard.tsx | 2 +- 9 files changed, 212 insertions(+), 42 deletions(-) create mode 100644 www/src/components/create-cluster/CreateClusterActions.tsx create mode 100644 www/src/components/create-cluster/steps/AuthenticationStep.tsx create mode 100644 www/src/components/create-cluster/steps/ConfigureCloudInstanceStep.tsx create mode 100644 www/src/components/create-cluster/steps/DeployLocallyStep.tsx create mode 100644 www/src/components/create-cluster/steps/InstallCliStep.tsx diff --git a/www/src/components/create-cluster/CreateCluster.tsx b/www/src/components/create-cluster/CreateCluster.tsx index 0133c289e..59d871eb5 100644 --- a/www/src/components/create-cluster/CreateCluster.tsx +++ b/www/src/components/create-cluster/CreateCluster.tsx @@ -1,16 +1,19 @@ import { Button, - Flex, ReturnIcon, SendMessageIcon, Stepper, } from '@pluralsh/design-system' import { useNavigate } from 'react-router-dom' -import { useTheme } from 'styled-components' +import styled, { useTheme } from 'styled-components' -import { useState } from 'react' +import { useMemo, useState } from 'react' +import OnboardingCard from 'components/shell/onboarding/OnboardingCard' + +import { CreateClusterActions } from './CreateClusterActions' import { + CreateClusterContext, CreateClusterStepKey, cloudSteps, localSteps, @@ -22,20 +25,13 @@ export function CreateCluster() { const [curStep, setCurStep] = useState( CreateClusterStepKey.HostingOptions ) - const [hostingOption, setHostingOption] = useState<'local' | 'cloud'>('local') + const [hostingOption, setHostingOption] = useState<'local' | 'cloud'>('cloud') const steps = hostingOption === 'local' ? localSteps : cloudSteps const curStepIndex = steps.findIndex((step) => step.key === curStep) return ( - - + + - - {steps[curStepIndex]?.component} - - + + ({ curStep, setCurStep, hostingOption, setHostingOption }), + [curStep, setCurStep, hostingOption, setHostingOption] + )} + > + + {steps[curStepIndex]?.component} + + + + + ) } + +const MainWrapperSC = styled.div(({ theme }) => ({ + display: 'flex', + justifyContent: 'space-between', + gap: theme.spacing.xlarge, + padding: theme.spacing.large, + '::after': { + // makes the spacing look a little nicer + content: '""', + flex: 0.35, + }, +})) + +const SidebarWrapperSC = styled.div(({ theme }) => ({ + display: 'flex', + minWidth: 256, + flexDirection: 'column', + gap: theme.spacing.large, +})) + +const ContentWrapperSC = styled.div(({ theme }) => ({ + display: 'flex', + margin: 'auto', + minWidth: 600, + maxWidth: 720, + flexDirection: 'column', + gap: theme.spacing.large, +})) + +const ContentHeaderSC = styled.div({ + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', +}) diff --git a/www/src/components/create-cluster/CreateClusterActions.tsx b/www/src/components/create-cluster/CreateClusterActions.tsx new file mode 100644 index 000000000..fb431c850 --- /dev/null +++ b/www/src/components/create-cluster/CreateClusterActions.tsx @@ -0,0 +1,55 @@ +import { Button, Divider, Flex } from '@pluralsh/design-system' +import { useTheme } from 'styled-components' + +import { + cloudSteps, + localSteps, + useCreateClusterContext, +} from './CreateClusterWizard' + +export function CreateClusterActions() { + const theme = useTheme() + const { curStep, setCurStep, hostingOption } = useCreateClusterContext() + + const steps = hostingOption === 'local' ? localSteps : cloudSteps + const curStepIndex = steps.findIndex((step) => step.key === curStep) + const prevStep = steps[curStepIndex - 1]?.key + const nextStep = steps[curStepIndex + 1]?.key + + return ( + <> + + + + + {prevStep && ( + + )} + {nextStep && ( + + )} + + + + ) +} diff --git a/www/src/components/create-cluster/CreateClusterWizard.tsx b/www/src/components/create-cluster/CreateClusterWizard.tsx index 364b7ab43..d63322e95 100644 --- a/www/src/components/create-cluster/CreateClusterWizard.tsx +++ b/www/src/components/create-cluster/CreateClusterWizard.tsx @@ -1,6 +1,18 @@ -import { CliIcon, CloudIcon, StepperSteps } from '@pluralsh/design-system' +import { + CliIcon, + CloudIcon, + ListIcon, + ShieldOutlineIcon, + StepperSteps, +} from '@pluralsh/design-system' + +import React, { createContext, useContext } from 'react' import { HostingOptionsStep } from './steps/HostingOptionsStep' +import { InstallCliStep } from './steps/InstallCliStep' +import { AuthenticationStep } from './steps/AuthenticationStep' +import { ConfigureCloudInstanceStep } from './steps/ConfigureCloudInstanceStep' +import { DeployLocallyStep } from './steps/DeployLocallyStep' export enum CreateClusterStepKey { HostingOptions = 'hosting-options', @@ -10,10 +22,37 @@ export enum CreateClusterStepKey { DeployLocally = 'deploy-locally', } -type CreateClusterStep = StepperSteps[number] & { +type CreateClusterStep = Omit & { + key: CreateClusterStepKey + stepTitle?: string component: React.ReactNode } +type HostingOption = 'local' | 'cloud' + +type CreateClusterContextType = { + hostingOption: HostingOption + setHostingOption: (option: HostingOption) => void + curStep: CreateClusterStepKey + setCurStep: (step: CreateClusterStepKey) => void +} + +export const CreateClusterContext = createContext< + CreateClusterContextType | undefined +>(undefined) + +export const useCreateClusterContext = () => { + const ctx = useContext(CreateClusterContext) + + if (!ctx) { + throw new Error( + 'useCreateClusterContext must be used within a CreateClusterProvider' + ) + } + + return ctx +} + export const localSteps: CreateClusterStep[] = [ { key: CreateClusterStepKey.HostingOptions, @@ -25,13 +64,13 @@ export const localSteps: CreateClusterStep[] = [ key: CreateClusterStepKey.InstallCli, stepTitle: 'Install Plural CLI', IconComponent: CliIcon, - component:
TODO
, + component: , }, { key: CreateClusterStepKey.DeployLocally, stepTitle: 'Deploy locally', - IconComponent: CloudIcon, - component:
TODO
, + IconComponent: ListIcon, + component: , }, ] @@ -46,18 +85,18 @@ export const cloudSteps: CreateClusterStep[] = [ key: CreateClusterStepKey.ConfigureCloudInstance, stepTitle: 'Configure cloud instance', IconComponent: CloudIcon, - component:
TODO
, + component: , }, { key: CreateClusterStepKey.InstallCli, stepTitle: 'Install Plural CLI', - IconComponent: CloudIcon, - component:
TODO
, + IconComponent: CliIcon, + component: , }, { key: CreateClusterStepKey.Authentication, stepTitle: 'Authentication', - IconComponent: CloudIcon, - component:
TODO
, + IconComponent: ShieldOutlineIcon, + component: , }, ] diff --git a/www/src/components/create-cluster/steps/AuthenticationStep.tsx b/www/src/components/create-cluster/steps/AuthenticationStep.tsx new file mode 100644 index 000000000..e66662c37 --- /dev/null +++ b/www/src/components/create-cluster/steps/AuthenticationStep.tsx @@ -0,0 +1,3 @@ +export function AuthenticationStep() { + return
AuthenticationStep
+} diff --git a/www/src/components/create-cluster/steps/ConfigureCloudInstanceStep.tsx b/www/src/components/create-cluster/steps/ConfigureCloudInstanceStep.tsx new file mode 100644 index 000000000..5b505dac6 --- /dev/null +++ b/www/src/components/create-cluster/steps/ConfigureCloudInstanceStep.tsx @@ -0,0 +1,3 @@ +export function ConfigureCloudInstanceStep() { + return
ConfigureCloudInstanceStep
+} diff --git a/www/src/components/create-cluster/steps/DeployLocallyStep.tsx b/www/src/components/create-cluster/steps/DeployLocallyStep.tsx new file mode 100644 index 000000000..4131cd771 --- /dev/null +++ b/www/src/components/create-cluster/steps/DeployLocallyStep.tsx @@ -0,0 +1,3 @@ +export function DeployLocallyStep() { + return
DeployLocallyStep
+} diff --git a/www/src/components/create-cluster/steps/HostingOptionsStep.tsx b/www/src/components/create-cluster/steps/HostingOptionsStep.tsx index 88790a661..a120801fb 100644 --- a/www/src/components/create-cluster/steps/HostingOptionsStep.tsx +++ b/www/src/components/create-cluster/steps/HostingOptionsStep.tsx @@ -1,9 +1,40 @@ -import OnboardingCard from 'components/shell/onboarding/OnboardingCard' +import { CloudIcon, Flex } from '@pluralsh/design-system' +import { CloudOption } from 'components/shell/onboarding/sections/cloud/CloudOption' + +import { useTheme } from 'styled-components' + +import { useCreateClusterContext } from '../CreateClusterWizard' export function HostingOptionsStep() { + const theme = useTheme() + const { hostingOption, setHostingOption } = useCreateClusterContext() + return ( - -
TODO
-
+ + setHostingOption('local')} + icon={ + + } + header="Deploy Yourself" + description="Host your control plane in your own cloud." + /> + setHostingOption('cloud')} + icon={ + + } + header="Use Plural Cloud" + description="Host your control plane in a Plural Cloud instance." + /> + ) } diff --git a/www/src/components/create-cluster/steps/InstallCliStep.tsx b/www/src/components/create-cluster/steps/InstallCliStep.tsx new file mode 100644 index 000000000..8daf981ed --- /dev/null +++ b/www/src/components/create-cluster/steps/InstallCliStep.tsx @@ -0,0 +1,3 @@ +export function InstallCliStep() { + return
InstallCliStep
+} diff --git a/www/src/components/shell/onboarding/OnboardingCard.tsx b/www/src/components/shell/onboarding/OnboardingCard.tsx index 831c01e55..66ae8cf7f 100644 --- a/www/src/components/shell/onboarding/OnboardingCard.tsx +++ b/www/src/components/shell/onboarding/OnboardingCard.tsx @@ -22,7 +22,7 @@ function OnboardingCard({ border="1px solid border" borderRadius="large" paddingVertical={mode === 'Default' ? 'xlarge' : 'medium'} - paddingHorizontal={mode === 'Default' ? 64 : 0} + paddingHorizontal={mode === 'Default' ? 'xlarge' : 0} overflowY="auto" {...props} > From 1501e6bd5c4cd14e2a3710628b874da3f841ebac Mon Sep 17 00:00:00 2001 From: Jake Laderman Date: Wed, 28 Aug 2024 16:12:27 -0400 Subject: [PATCH 05/17] add deploy local steps --- .../create-cluster/CreateCluster.tsx | 29 ++++++-- .../create-cluster/CreateClusterActions.tsx | 16 ++++- .../create-cluster/CreateClusterWizard.tsx | 2 + .../steps/DeployLocallyStep.tsx | 66 ++++++++++++++++++- .../steps/HostingOptionsStep.tsx | 19 +----- .../create-cluster/steps/InstallCliStep.tsx | 22 ++++++- .../sections/cli/CLIInstallationStep.tsx | 49 +++++++++----- 7 files changed, 158 insertions(+), 45 deletions(-) diff --git a/www/src/components/create-cluster/CreateCluster.tsx b/www/src/components/create-cluster/CreateCluster.tsx index 59d871eb5..4a9890d94 100644 --- a/www/src/components/create-cluster/CreateCluster.tsx +++ b/www/src/components/create-cluster/CreateCluster.tsx @@ -25,10 +25,30 @@ export function CreateCluster() { const [curStep, setCurStep] = useState( CreateClusterStepKey.HostingOptions ) - const [hostingOption, setHostingOption] = useState<'local' | 'cloud'>('cloud') + const [hostingOption, setHostingOption] = useState<'local' | 'cloud'>('local') + const [finishEnabled, setFinishEnabled] = useState(false) const steps = hostingOption === 'local' ? localSteps : cloudSteps const curStepIndex = steps.findIndex((step) => step.key === curStep) + const context = useMemo( + () => ({ + curStep, + setCurStep, + hostingOption, + setHostingOption, + finishEnabled, + setFinishEnabled, + }), + [ + curStep, + setCurStep, + hostingOption, + setHostingOption, + finishEnabled, + setFinishEnabled, + ] + ) + return ( @@ -60,12 +80,7 @@ export function CreateCluster() { Contact sales - ({ curStep, setCurStep, hostingOption, setHostingOption }), - [curStep, setCurStep, hostingOption, setHostingOption] - )} - > + {steps[curStepIndex]?.component} diff --git a/www/src/components/create-cluster/CreateClusterActions.tsx b/www/src/components/create-cluster/CreateClusterActions.tsx index fb431c850..dfb69a286 100644 --- a/www/src/components/create-cluster/CreateClusterActions.tsx +++ b/www/src/components/create-cluster/CreateClusterActions.tsx @@ -9,13 +9,18 @@ import { export function CreateClusterActions() { const theme = useTheme() - const { curStep, setCurStep, hostingOption } = useCreateClusterContext() + const { curStep, setCurStep, hostingOption, finishEnabled } = + useCreateClusterContext() const steps = hostingOption === 'local' ? localSteps : cloudSteps const curStepIndex = steps.findIndex((step) => step.key === curStep) const prevStep = steps[curStepIndex - 1]?.key const nextStep = steps[curStepIndex + 1]?.key + const handleFinish = () => { + // TODO + } + return ( <> )} - {nextStep && ( + {nextStep ? ( + ) : ( + )} diff --git a/www/src/components/create-cluster/CreateClusterWizard.tsx b/www/src/components/create-cluster/CreateClusterWizard.tsx index d63322e95..a40569b36 100644 --- a/www/src/components/create-cluster/CreateClusterWizard.tsx +++ b/www/src/components/create-cluster/CreateClusterWizard.tsx @@ -35,6 +35,8 @@ type CreateClusterContextType = { setHostingOption: (option: HostingOption) => void curStep: CreateClusterStepKey setCurStep: (step: CreateClusterStepKey) => void + finishEnabled: boolean + setFinishEnabled: (enabled: boolean) => void } export const CreateClusterContext = createContext< diff --git a/www/src/components/create-cluster/steps/DeployLocallyStep.tsx b/www/src/components/create-cluster/steps/DeployLocallyStep.tsx index 4131cd771..3fa5f7093 100644 --- a/www/src/components/create-cluster/steps/DeployLocallyStep.tsx +++ b/www/src/components/create-cluster/steps/DeployLocallyStep.tsx @@ -1,3 +1,67 @@ +import { Callout, Checkbox, Codeline, Flex } from '@pluralsh/design-system' +import { CSSProp, useTheme } from 'styled-components' + +import { useCreateClusterContext } from '../CreateClusterWizard' + export function DeployLocallyStep() { - return
DeployLocallyStep
+ const theme = useTheme() + const { finishEnabled, setFinishEnabled } = useCreateClusterContext() + + return ( + + + We recommend keeping this tab open and proceeding once your control + plane is deployed. + + + + Now that you've installed the Plural CLI, all that's needed is to run + one command. This will provide everything you need to run your control + plane. + + + plural up + + + For a full guide on properly deploying your cloud instance and cluster + with `plural up`,{' '} + + visit our documentation. + + + + + setFinishEnabled(e.target.checked)} + css={ + { + '& .label': { + userSelect: 'none', + }, + } as CSSProp + } + > + The `plural up` command has finished running. + * + + + + ) } diff --git a/www/src/components/create-cluster/steps/HostingOptionsStep.tsx b/www/src/components/create-cluster/steps/HostingOptionsStep.tsx index a120801fb..d32213177 100644 --- a/www/src/components/create-cluster/steps/HostingOptionsStep.tsx +++ b/www/src/components/create-cluster/steps/HostingOptionsStep.tsx @@ -1,12 +1,9 @@ -import { CloudIcon, Flex } from '@pluralsh/design-system' +import { CloudIcon, ConsoleIcon, Flex } from '@pluralsh/design-system' import { CloudOption } from 'components/shell/onboarding/sections/cloud/CloudOption' -import { useTheme } from 'styled-components' - import { useCreateClusterContext } from '../CreateClusterWizard' export function HostingOptionsStep() { - const theme = useTheme() const { hostingOption, setHostingOption } = useCreateClusterContext() return ( @@ -14,24 +11,14 @@ export function HostingOptionsStep() { setHostingOption('local')} - icon={ - - } + icon={} header="Deploy Yourself" description="Host your control plane in your own cloud." /> setHostingOption('cloud')} - icon={ - - } + icon={} header="Use Plural Cloud" description="Host your control plane in a Plural Cloud instance." /> diff --git a/www/src/components/create-cluster/steps/InstallCliStep.tsx b/www/src/components/create-cluster/steps/InstallCliStep.tsx index 8daf981ed..93fd878a5 100644 --- a/www/src/components/create-cluster/steps/InstallCliStep.tsx +++ b/www/src/components/create-cluster/steps/InstallCliStep.tsx @@ -1,3 +1,23 @@ +import { Callout, Flex } from '@pluralsh/design-system' +import { CliInstallationBaseInfo } from 'components/shell/onboarding/sections/cli/CLIInstallationStep' + +import { useCreateClusterContext } from '../CreateClusterWizard' + export function InstallCliStep() { - return
InstallCliStep
+ const { hostingOption } = useCreateClusterContext() + + return ( + + {hostingOption === 'cloud' && ( + + This will help to setup and properly configure the control plane and + Plural Cloud instance with your local environment. + + )} + + + ) } diff --git a/www/src/components/shell/onboarding/sections/cli/CLIInstallationStep.tsx b/www/src/components/shell/onboarding/sections/cli/CLIInstallationStep.tsx index 350e076cb..57969f371 100644 --- a/www/src/components/shell/onboarding/sections/cli/CLIInstallationStep.tsx +++ b/www/src/components/shell/onboarding/sections/cli/CLIInstallationStep.tsx @@ -9,6 +9,7 @@ import { TabList, TabPanel, } from '@pluralsh/design-system' +import { useTheme } from 'styled-components' const TAB_MAC = 'TAB_MAC' const TAB_CURL = 'TAB_CURL' @@ -43,6 +44,29 @@ const DIRECTORY = [ ] function CliInstallation({ onBack, onNext }) { + return ( + <> + + + + + + + ) +} +export function CliInstallationBaseInfo() { + const theme = useTheme() const [tab, setTab] = useState(TAB_MAC) const tabStateRef = useRef(null) const currentTab = useMemo(() => DIRECTORY.find((t) => t.key === tab), [tab]) @@ -110,9 +134,14 @@ function CliInstallation({ onBack, onNext }) { <>
{tab === TAB_MAC ? ( - {currentTab?.command} + + {currentTab?.command} + ) : ( - {}}> + {}} + > {currentTab?.command || ''} )} @@ -184,22 +213,6 @@ function CliInstallation({ onBack, onNext }) { )} - - - - - ) } From f9da94654424d521d2d21c8caf90983e0604c9bf Mon Sep 17 00:00:00 2001 From: Jake Laderman Date: Wed, 28 Aug 2024 23:53:24 -0400 Subject: [PATCH 06/17] configure cloud instance step progress --- .../create-cluster/CreateCluster.tsx | 8 +- .../create-cluster/CreateClusterActions.tsx | 6 +- .../create-cluster/CreateClusterWizard.tsx | 4 +- .../steps/ConfigureCloudInstanceStep.tsx | 126 +++++++++++++++++- 4 files changed, 139 insertions(+), 5 deletions(-) diff --git a/www/src/components/create-cluster/CreateCluster.tsx b/www/src/components/create-cluster/CreateCluster.tsx index 4a9890d94..f9eedc6b8 100644 --- a/www/src/components/create-cluster/CreateCluster.tsx +++ b/www/src/components/create-cluster/CreateCluster.tsx @@ -7,7 +7,7 @@ import { import { useNavigate } from 'react-router-dom' import styled, { useTheme } from 'styled-components' -import { useMemo, useState } from 'react' +import { ReactElement, useMemo, useState } from 'react' import OnboardingCard from 'components/shell/onboarding/OnboardingCard' @@ -27,6 +27,8 @@ export function CreateCluster() { ) const [hostingOption, setHostingOption] = useState<'local' | 'cloud'>('local') const [finishEnabled, setFinishEnabled] = useState(false) + const [continueBtn, setContinueBtn] = useState() + const steps = hostingOption === 'local' ? localSteps : cloudSteps const curStepIndex = steps.findIndex((step) => step.key === curStep) @@ -38,6 +40,8 @@ export function CreateCluster() { setHostingOption, finishEnabled, setFinishEnabled, + continueBtn, + setContinueBtn, }), [ curStep, @@ -46,6 +50,8 @@ export function CreateCluster() { setHostingOption, finishEnabled, setFinishEnabled, + continueBtn, + setContinueBtn, ] ) diff --git a/www/src/components/create-cluster/CreateClusterActions.tsx b/www/src/components/create-cluster/CreateClusterActions.tsx index dfb69a286..8fa2626c8 100644 --- a/www/src/components/create-cluster/CreateClusterActions.tsx +++ b/www/src/components/create-cluster/CreateClusterActions.tsx @@ -9,7 +9,7 @@ import { export function CreateClusterActions() { const theme = useTheme() - const { curStep, setCurStep, hostingOption, finishEnabled } = + const { curStep, setCurStep, hostingOption, finishEnabled, continueBtn } = useCreateClusterContext() const steps = hostingOption === 'local' ? localSteps : cloudSteps @@ -51,7 +51,9 @@ export function CreateClusterActions() { )} {nextStep ? ( - + continueBtn || ( + + ) ) : ( + ) + + return () => { + setContinueBtn(undefined) + } + }, [canSubmit, setContinueBtn, setCurStep]) + + return ( + + + After completing this step it may take a few minutes for your Console to + deploy. It will run in the background as you proceed. + + + setClusterName(e.target.value)} + /> + + + + + + + + {cloudProvider === CloudProvider.Aws && ( + + + + )} + + ) } + +const FormFieldSC = styled(FormField)(({ theme }) => ({ + color: theme.colors.text, +})) + +const regions = ['us-east-1'] From 72c2323c8ffaa30f64299705b0dbb1992f48ba7e Mon Sep 17 00:00:00 2001 From: Jake Laderman Date: Thu, 29 Aug 2024 16:45:59 -0400 Subject: [PATCH 07/17] add mutation to create instance add authentication screen --- .../create-cluster/ConsoleCreationStatus.tsx | 62 ++ .../create-cluster/CreateCluster.tsx | 37 +- .../create-cluster/CreateClusterActions.tsx | 20 +- .../create-cluster/CreateClusterWizard.tsx | 7 +- .../steps/AuthenticationStep.tsx | 66 ++- .../steps/ConfigureCloudInstanceStep.tsx | 67 ++- .../steps/DeployLocallyStep.tsx | 34 +- .../overview/clusters/ClusterHealth.tsx | 23 +- www/src/components/utils/Alert.tsx | 2 +- www/src/generated/graphql.ts | 553 ++++++++++++++---- www/src/graph/cluster.graphql | 78 +-- www/src/graph/pluralCloud.graphql | 118 ++++ 12 files changed, 847 insertions(+), 220 deletions(-) create mode 100644 www/src/components/create-cluster/ConsoleCreationStatus.tsx create mode 100644 www/src/graph/pluralCloud.graphql diff --git a/www/src/components/create-cluster/ConsoleCreationStatus.tsx b/www/src/components/create-cluster/ConsoleCreationStatus.tsx new file mode 100644 index 000000000..2bb3d48e6 --- /dev/null +++ b/www/src/components/create-cluster/ConsoleCreationStatus.tsx @@ -0,0 +1,62 @@ +import { Card, Flex, Spinner, SuccessIcon } from '@pluralsh/design-system' +import { useIsClusterHealthy } from 'components/overview/clusters/ClusterHealth' +import { ConsoleInstanceFragment } from 'generated/graphql' +import styled, { useTheme } from 'styled-components' + +export function ConsoleCreationStatus({ + consoleInstance, +}: { + consoleInstance: ConsoleInstanceFragment +}) { + const theme = useTheme() + const loading = !useIsClusterHealthy(consoleInstance?.console?.pingedAt) + + return ( + + + + + {loading + ? 'Creating console instance...' + : 'Console successfully provisioned'} + + + + + {loading + ? 'Your Console is being deployed in the background on your Plural Cloud instance. This might take a few minutes.' + : 'You are now ready to complete your cluster creation.'} + + + {loading && ( + + Status: {consoleInstance?.status} + + + )} + + ) +} + +const CreationStatusCardSC = styled(Card)(({ theme }) => ({ + padding: theme.spacing.medium, + display: 'flex', + flexDirection: 'column', + gap: theme.spacing.medium, +})) diff --git a/www/src/components/create-cluster/CreateCluster.tsx b/www/src/components/create-cluster/CreateCluster.tsx index f9eedc6b8..c9ed6642f 100644 --- a/www/src/components/create-cluster/CreateCluster.tsx +++ b/www/src/components/create-cluster/CreateCluster.tsx @@ -11,6 +11,11 @@ import { ReactElement, useMemo, useState } from 'react' import OnboardingCard from 'components/shell/onboarding/OnboardingCard' +import { useConsoleInstanceQuery } from 'generated/graphql' + +import { GqlError } from 'components/utils/Alert' + +import { ConsoleCreationStatus } from './ConsoleCreationStatus' import { CreateClusterActions } from './CreateClusterActions' import { CreateClusterContext, @@ -28,10 +33,22 @@ export function CreateCluster() { const [hostingOption, setHostingOption] = useState<'local' | 'cloud'>('local') const [finishEnabled, setFinishEnabled] = useState(false) const [continueBtn, setContinueBtn] = useState() + const [consoleInstanceId, setConsoleInstanceId] = useState< + string | undefined + >() const steps = hostingOption === 'local' ? localSteps : cloudSteps const curStepIndex = steps.findIndex((step) => step.key === curStep) + const { data, error } = useConsoleInstanceQuery({ + variables: { + id: consoleInstanceId ?? '', + }, + skip: !consoleInstanceId, + fetchPolicy: 'cache-and-network', + pollInterval: 10000, + }) + const context = useMemo( () => ({ curStep, @@ -42,16 +59,17 @@ export function CreateCluster() { setFinishEnabled, continueBtn, setContinueBtn, + consoleInstanceId, + setConsoleInstanceId, + consoleUrl: data?.consoleInstance?.url, }), [ curStep, - setCurStep, hostingOption, - setHostingOption, finishEnabled, - setFinishEnabled, continueBtn, - setContinueBtn, + consoleInstanceId, + data?.consoleInstance?.url, ] ) @@ -71,6 +89,13 @@ export function CreateCluster() { steps={steps} stepIndex={curStepIndex} /> + {error ? ( + + ) : ( + data?.consoleInstance && ( + + ) + )} @@ -113,7 +138,7 @@ const SidebarWrapperSC = styled.div(({ theme }) => ({ display: 'flex', minWidth: 256, flexDirection: 'column', - gap: theme.spacing.large, + gap: theme.spacing.xlarge, })) const ContentWrapperSC = styled.div(({ theme }) => ({ @@ -122,7 +147,7 @@ const ContentWrapperSC = styled.div(({ theme }) => ({ minWidth: 600, maxWidth: 720, flexDirection: 'column', - gap: theme.spacing.large, + gap: theme.spacing.xlarge, })) const ContentHeaderSC = styled.div({ diff --git a/www/src/components/create-cluster/CreateClusterActions.tsx b/www/src/components/create-cluster/CreateClusterActions.tsx index 8fa2626c8..939a479e9 100644 --- a/www/src/components/create-cluster/CreateClusterActions.tsx +++ b/www/src/components/create-cluster/CreateClusterActions.tsx @@ -1,16 +1,27 @@ import { Button, Divider, Flex } from '@pluralsh/design-system' import { useTheme } from 'styled-components' +import { useNavigate } from 'react-router-dom' + import { cloudSteps, localSteps, useCreateClusterContext, } from './CreateClusterWizard' +export const NEW_CONSOLE_INSTANCE_KEY = 'new-console-instance' + export function CreateClusterActions() { const theme = useTheme() - const { curStep, setCurStep, hostingOption, finishEnabled, continueBtn } = - useCreateClusterContext() + const navigate = useNavigate() + const { + curStep, + setCurStep, + hostingOption, + finishEnabled, + continueBtn, + consoleInstanceId, + } = useCreateClusterContext() const steps = hostingOption === 'local' ? localSteps : cloudSteps const curStepIndex = steps.findIndex((step) => step.key === curStep) @@ -18,7 +29,10 @@ export function CreateClusterActions() { const nextStep = steps[curStepIndex + 1]?.key const handleFinish = () => { - // TODO + if (consoleInstanceId) { + localStorage.setItem(NEW_CONSOLE_INSTANCE_KEY, consoleInstanceId) + } + navigate('/overview') } return ( diff --git a/www/src/components/create-cluster/CreateClusterWizard.tsx b/www/src/components/create-cluster/CreateClusterWizard.tsx index 9d432d6a2..b60b3a637 100644 --- a/www/src/components/create-cluster/CreateClusterWizard.tsx +++ b/www/src/components/create-cluster/CreateClusterWizard.tsx @@ -8,11 +8,11 @@ import { import React, { ReactElement, createContext, useContext } from 'react' -import { HostingOptionsStep } from './steps/HostingOptionsStep' -import { InstallCliStep } from './steps/InstallCliStep' import { AuthenticationStep } from './steps/AuthenticationStep' import { ConfigureCloudInstanceStep } from './steps/ConfigureCloudInstanceStep' import { DeployLocallyStep } from './steps/DeployLocallyStep' +import { HostingOptionsStep } from './steps/HostingOptionsStep' +import { InstallCliStep } from './steps/InstallCliStep' export enum CreateClusterStepKey { HostingOptions = 'hosting-options', @@ -39,6 +39,9 @@ type CreateClusterContextType = { setFinishEnabled: (enabled: boolean) => void continueBtn?: ReactElement setContinueBtn: (continueBtn?: ReactElement) => void + consoleInstanceId?: string + setConsoleInstanceId: (consoleInstanceId?: string) => void + consoleUrl?: string } export const CreateClusterContext = createContext< diff --git a/www/src/components/create-cluster/steps/AuthenticationStep.tsx b/www/src/components/create-cluster/steps/AuthenticationStep.tsx index e66662c37..f0c0208bd 100644 --- a/www/src/components/create-cluster/steps/AuthenticationStep.tsx +++ b/www/src/components/create-cluster/steps/AuthenticationStep.tsx @@ -1,3 +1,67 @@ +import { + ArrowTopRightIcon, + Button, + Checkbox, + Codeline, + Flex, +} from '@pluralsh/design-system' +import { CSSProp, useTheme } from 'styled-components' + +import { useCreateClusterContext } from '../CreateClusterWizard' + export function AuthenticationStep() { - return
AuthenticationStep
+ const theme = useTheme() + const { consoleUrl, finishEnabled, setFinishEnabled } = + useCreateClusterContext() + + return ( + + You're almost done — just one last step! + + Now that `plural up` has completed you will have access to your Plural + Console. You must generate an access token there and run it on your + local machine to authenticate the new cloud instance. + + + + 1. Go to your newly deployed Console. The link is in the Clusters Tab. + + + {'2. Navigate to Settings > Access Tokens'} + 3. Generate a new access token. + + 4. Run the command below, locally, and enter the access token. + + + + plural up --cloud + + setFinishEnabled(e.target.checked)} + css={ + { + '& .label': { + userSelect: 'none', + }, + } as CSSProp + } + > + I successfully authenticated my cloud instance locally. + * + + + ) } diff --git a/www/src/components/create-cluster/steps/ConfigureCloudInstanceStep.tsx b/www/src/components/create-cluster/steps/ConfigureCloudInstanceStep.tsx index 069851eaa..0be5847c7 100644 --- a/www/src/components/create-cluster/steps/ConfigureCloudInstanceStep.tsx +++ b/www/src/components/create-cluster/steps/ConfigureCloudInstanceStep.tsx @@ -7,10 +7,16 @@ import { ListBoxItem, Select, } from '@pluralsh/design-system' -import { CloudProvider, ConsoleSize } from 'generated/graphql' +import { + CloudProvider, + ConsoleSize, + useCreateConsoleInstanceMutation, +} from 'generated/graphql' import { useLayoutEffect, useState } from 'react' import styled, { useTheme } from 'styled-components' +import { GqlError } from 'components/utils/Alert' + import { CreateClusterStepKey, useCreateClusterContext, @@ -18,30 +24,44 @@ import { export function ConfigureCloudInstanceStep() { const theme = useTheme() - const { setCurStep, setContinueBtn } = useCreateClusterContext() + const { setCurStep, setContinueBtn, setConsoleInstanceId } = + useCreateClusterContext() - const [clusterName, setClusterName] = useState('') - const [clusterSize, setClusterSize] = useState(ConsoleSize.Small) - const [cloudProvider, setCloudProvider] = useState( - CloudProvider.Aws - ) - const [region, setRegion] = useState(regions[0]) + const [name, setName] = useState('') + const [size, setSize] = useState(ConsoleSize.Small) + const [cloud, setCloud] = useState(CloudProvider.Aws) + const [region, setRegion] = useState(regions[0]) const canSubmit = !!( - clusterName && - clusterSize && - cloudProvider && - (cloudProvider === CloudProvider.Aws ? region : true) + name && + size && + cloud && + (cloud === CloudProvider.Aws ? region : true) ) + const [mutation, { loading, error }] = useCreateConsoleInstanceMutation({ + variables: { + attributes: { + name, + size, + cloud, + region, + }, + }, + onCompleted: (data) => { + setConsoleInstanceId(data?.createConsoleInstance?.id) + setCurStep(CreateClusterStepKey.InstallCli) + }, + }) + // using layout effect to avoid flickering useLayoutEffect(() => { setContinueBtn( @@ -50,13 +70,14 @@ export function ConfigureCloudInstanceStep() { return () => { setContinueBtn(undefined) } - }, [canSubmit, setContinueBtn, setCurStep]) + }, [canSubmit, loading, mutation, setContinueBtn]) return ( + {error && } setClusterName(e.target.value)} + value={name} + onChange={(e) => setName(e.target.value)} /> - setCloudProvider(cloudProvider as CloudProvider) - } + selectedKey={cloud} + onSelectionChange={(cloud) => setCloud(cloud as CloudProvider)} > {Object.values(CloudProvider).map((value) => ( - {cloudProvider === CloudProvider.Aws && ( + {cloud === CloudProvider.Aws && ( @@ -139,7 +141,7 @@ export function ConfigureCloudInstanceStep() { ) } -const FormFieldSC = styled(FormField)(({ theme }) => ({ +export const FormFieldSC = styled(FormField)(({ theme }) => ({ color: theme.colors.text, })) diff --git a/www/src/components/overview/clusters/plural-cloud/CloudInstanceTableCols.tsx b/www/src/components/overview/clusters/plural-cloud/CloudInstanceTableCols.tsx index cafa001a9..c5942018a 100644 --- a/www/src/components/overview/clusters/plural-cloud/CloudInstanceTableCols.tsx +++ b/www/src/components/overview/clusters/plural-cloud/CloudInstanceTableCols.tsx @@ -1,4 +1,12 @@ -import { AppIcon, Chip, ConsoleIcon, Flex } from '@pluralsh/design-system' +import { + AppIcon, + Button, + Chip, + ConsoleIcon, + Flex, + ListBoxItem, + PeopleIcon, +} from '@pluralsh/design-system' import { createColumnHelper } from '@tanstack/react-table' import { ProviderIcon } from 'components/utils/ProviderIcon' @@ -7,11 +15,21 @@ import { ConsoleInstanceStatus, } from 'generated/graphql' +import { MoreMenu } from 'components/account/MoreMenu' +import ConsoleInstancesContext from 'contexts/ConsoleInstancesContext' +import { useCallback, useContext, useState } from 'react' +import { useTheme } from 'styled-components' + +import { ClusterAdminsModal } from 'components/cluster/ClusterAdminsModal' + import { CellCaption, CellWrap } from '../SelfHostedTableCols' +import { EditInstanceSizeModal } from './EditInstance' +import { DeleteInstanceModal } from './DeleteInstance' + const columnHelper = createColumnHelper() -const formatStr = (string: Nullable) => +export const firstLetterUppercase = (string: Nullable) => string && string.charAt(0).toUpperCase() + string.slice(1).toLowerCase() function getStatusSeverity( @@ -32,6 +50,7 @@ const ColInstance = columnHelper.accessor((instance) => instance.name, { id: 'instance', header: 'Instance', enableSorting: true, + meta: { gridTemplate: '1fr' }, cell: ({ getValue }) => ( instance.status, { enableSorting: true, cell: ({ getValue }) => ( - {formatStr(getValue())} + {firstLetterUppercase(getValue())} ), }) @@ -88,12 +107,13 @@ const ColSize = columnHelper.accessor((instance) => instance.size, { id: 'size', header: 'Size', enableSorting: true, - cell: ({ getValue }) => formatStr(getValue()), + cell: ({ getValue }) => firstLetterUppercase(getValue()), }) const ColOwner = columnHelper.accessor((instance) => instance.owner, { id: 'owner', header: 'Owner', + meta: { gridTemplate: '1fr' }, enableSorting: true, sortingFn: (rowA, rowB) => (rowA.original.owner?.name ?? '') < (rowB.original.owner?.name ?? '') @@ -107,10 +127,91 @@ const ColOwner = columnHelper.accessor((instance) => instance.owner, { ), }) +enum MenuItemKey { + EditSize = 'editSize', + EditOidc = 'editOidc', + Delete = 'delete', +} + const ColActions = columnHelper.accessor((instance) => instance, { id: 'actions', header: '', - cell: ({ getValue }) =>
actions
, + meta: { gridTemplate: 'max-content' }, + cell: function Cell({ getValue }) { + const theme = useTheme() + const [menuKey, setMenuKey] = useState>('') + const instance = getValue() + const { refetchInstances } = useContext(ConsoleInstancesContext) + const onClose = useCallback(() => setMenuKey(''), []) + + return ( + + + + setMenuKey(newKey)}> + + + + + {/* Modals */} + + + + + ) + }, }) export const cloudInstanceCols = [ @@ -120,5 +221,5 @@ export const cloudInstanceCols = [ ColRegion, ColSize, ColOwner, - // ColActions, + ColActions, ] diff --git a/www/src/components/overview/clusters/plural-cloud/DeleteInstance.tsx b/www/src/components/overview/clusters/plural-cloud/DeleteInstance.tsx new file mode 100644 index 000000000..672b21c3c --- /dev/null +++ b/www/src/components/overview/clusters/plural-cloud/DeleteInstance.tsx @@ -0,0 +1,101 @@ +import { useTheme } from 'styled-components' + +import { Button, Flex, Input, Modal } from '@pluralsh/design-system' +import { GqlError } from 'components/utils/Alert' +import { + ConsoleInstanceFragment, + useDeleteConsoleInstanceMutation, +} from 'generated/graphql' +import { useState } from 'react' + +export function DeleteInstanceModal({ + open, + onClose, + refetch, + instance, +}: { + open: boolean + onClose: () => void + refetch: () => void + instance: ConsoleInstanceFragment +}) { + return ( + + + + ) +} + +function DeleteInstance({ + onClose, + refetch, + instance, +}: { + onClose: () => void + refetch: () => void + instance: ConsoleInstanceFragment +}) { + const theme = useTheme() + const [mutation, { loading, error }] = useDeleteConsoleInstanceMutation({ + variables: { id: instance.id }, + onCompleted: () => { + onClose() + refetch() + }, + }) + + const [confirmText, setConfirmText] = useState('') + + return ( + + {error && } + + Are you sure you want to delete this cloud instance? This action is not + reversible. + + + Type " + + {instance.name} + + " to confirm deletion. + + setConfirmText(e.target.value)} + /> + + + + + + ) +} diff --git a/www/src/components/overview/clusters/plural-cloud/EditInstance.tsx b/www/src/components/overview/clusters/plural-cloud/EditInstance.tsx new file mode 100644 index 000000000..537d2fee7 --- /dev/null +++ b/www/src/components/overview/clusters/plural-cloud/EditInstance.tsx @@ -0,0 +1,115 @@ +import { + Button, + Flex, + ListBoxItem, + Modal, + Select, +} from '@pluralsh/design-system' +import { FormFieldSC } from 'components/create-cluster/steps/ConfigureCloudInstanceStep' +import { + ConsoleInstanceFragment, + ConsoleSize, + useUpdateConsoleInstanceMutation, +} from 'generated/graphql' +import { useState } from 'react' + +import { GqlError } from 'components/utils/Alert' + +import { useTheme } from 'styled-components' + +import { firstLetterUppercase } from './CloudInstanceTableCols' + +export function EditInstanceSizeModal({ + open, + onClose, + refetch, + instance, +}: { + open: boolean + onClose: () => void + refetch?: () => void + instance: ConsoleInstanceFragment +}) { + return ( + + + + ) +} + +function EditInstanceSize({ + onClose, + refetch, + instance, +}: { + onClose: () => void + refetch?: () => void + instance: ConsoleInstanceFragment +}) { + const theme = useTheme() + const [size, setSize] = useState(instance.size) + const [mutation, { loading, error }] = useUpdateConsoleInstanceMutation({ + variables: { + id: instance.id, + attributes: { + size, + }, + }, + onCompleted: () => { + refetch?.() + onClose() + }, + }) + + return ( + + {error && } + + + + + + + + + ) +} diff --git a/www/src/components/overview/clusters/plural-cloud/PluralCloudInstances.tsx b/www/src/components/overview/clusters/plural-cloud/PluralCloudInstances.tsx index 551b04826..b0ed56831 100644 --- a/www/src/components/overview/clusters/plural-cloud/PluralCloudInstances.tsx +++ b/www/src/components/overview/clusters/plural-cloud/PluralCloudInstances.tsx @@ -28,7 +28,6 @@ export function PluralCloudInstances() { useEffect(() => { const id = localStorage.getItem(NEW_CONSOLE_INSTANCE_KEY) - console.log(id) if (id && instances.some((i) => i.id === id)) { localStorage.removeItem(NEW_CONSOLE_INSTANCE_KEY) setShowToast(true) diff --git a/www/src/contexts/ConsoleInstancesContext.tsx b/www/src/contexts/ConsoleInstancesContext.tsx index 7a17409ae..aff540742 100644 --- a/www/src/contexts/ConsoleInstancesContext.tsx +++ b/www/src/contexts/ConsoleInstancesContext.tsx @@ -11,11 +11,12 @@ import { ClustersContextProvider } from './ClustersContext' type ConsoleInstancesContextType = { instances: ConsoleInstanceFragment[] - refetchInstances?: () => Promise + refetchInstances: () => void } const ConsoleInstancesContext = createContext({ instances: [], + refetchInstances: () => {}, }) const Error = styled.div(({ theme }) => ({ diff --git a/www/src/generated/graphql.ts b/www/src/generated/graphql.ts index 152b76d12..75f1b33f0 100644 --- a/www/src/generated/graphql.ts +++ b/www/src/generated/graphql.ts @@ -5605,14 +5605,14 @@ export type InvoicesQueryVariables = Exact<{ [key: string]: never; }>; export type InvoicesQuery = { __typename?: 'RootQueryType', invoices?: { __typename?: 'InvoiceConnection', edges?: Array<{ __typename?: 'InvoiceEdge', node?: { __typename?: 'Invoice', number: string, amountDue: number, amountPaid: number, currency: string, status?: string | null, createdAt?: Date | null, hostedInvoiceUrl?: string | null, lines?: Array<{ __typename?: 'InvoiceItem', amount: number, currency: string, description?: string | null } | null> | null } | null } | null> | null } | null }; -export type ConsoleInstanceFragment = { __typename?: 'ConsoleInstance', id: string, name: string, subdomain: string, url: string, cloud: CloudProvider, size: ConsoleSize, region: string, status: ConsoleInstanceStatus, deletedAt?: Date | null, insertedAt?: Date | null, updatedAt?: Date | null, console?: { __typename?: 'Cluster', id: string, pingedAt?: Date | null } | null, owner?: { __typename?: 'User', name: string, email: string } | null }; +export type ConsoleInstanceFragment = { __typename?: 'ConsoleInstance', id: string, name: string, subdomain: string, url: string, cloud: CloudProvider, size: ConsoleSize, region: string, status: ConsoleInstanceStatus, deletedAt?: Date | null, insertedAt?: Date | null, updatedAt?: Date | null, console?: { __typename?: 'Cluster', id: string, pingedAt?: Date | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null } | null, owner?: { __typename?: 'User', name: string, email: string } | null }; export type ConsoleInstanceQueryVariables = Exact<{ id: Scalars['ID']['input']; }>; -export type ConsoleInstanceQuery = { __typename?: 'RootQueryType', consoleInstance?: { __typename?: 'ConsoleInstance', id: string, name: string, subdomain: string, url: string, cloud: CloudProvider, size: ConsoleSize, region: string, status: ConsoleInstanceStatus, deletedAt?: Date | null, insertedAt?: Date | null, updatedAt?: Date | null, console?: { __typename?: 'Cluster', id: string, pingedAt?: Date | null } | null, owner?: { __typename?: 'User', name: string, email: string } | null } | null }; +export type ConsoleInstanceQuery = { __typename?: 'RootQueryType', consoleInstance?: { __typename?: 'ConsoleInstance', id: string, name: string, subdomain: string, url: string, cloud: CloudProvider, size: ConsoleSize, region: string, status: ConsoleInstanceStatus, deletedAt?: Date | null, insertedAt?: Date | null, updatedAt?: Date | null, console?: { __typename?: 'Cluster', id: string, pingedAt?: Date | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null } | null, owner?: { __typename?: 'User', name: string, email: string } | null } | null }; export type ConsoleInstancesQueryVariables = Exact<{ after?: InputMaybe; @@ -5622,14 +5622,14 @@ export type ConsoleInstancesQueryVariables = Exact<{ }>; -export type ConsoleInstancesQuery = { __typename?: 'RootQueryType', consoleInstances?: { __typename?: 'ConsoleInstanceConnection', edges?: Array<{ __typename?: 'ConsoleInstanceEdge', node?: { __typename?: 'ConsoleInstance', id: string, name: string, subdomain: string, url: string, cloud: CloudProvider, size: ConsoleSize, region: string, status: ConsoleInstanceStatus, deletedAt?: Date | null, insertedAt?: Date | null, updatedAt?: Date | null, console?: { __typename?: 'Cluster', id: string, pingedAt?: Date | null } | null, owner?: { __typename?: 'User', name: string, email: string } | null } | null } | null> | null, pageInfo: { __typename?: 'PageInfo', endCursor?: string | null, hasNextPage: boolean } } | null }; +export type ConsoleInstancesQuery = { __typename?: 'RootQueryType', consoleInstances?: { __typename?: 'ConsoleInstanceConnection', edges?: Array<{ __typename?: 'ConsoleInstanceEdge', node?: { __typename?: 'ConsoleInstance', id: string, name: string, subdomain: string, url: string, cloud: CloudProvider, size: ConsoleSize, region: string, status: ConsoleInstanceStatus, deletedAt?: Date | null, insertedAt?: Date | null, updatedAt?: Date | null, console?: { __typename?: 'Cluster', id: string, pingedAt?: Date | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null } | null, owner?: { __typename?: 'User', name: string, email: string } | null } | null } | null> | null, pageInfo: { __typename?: 'PageInfo', endCursor?: string | null, hasNextPage: boolean } } | null }; export type CreateConsoleInstanceMutationVariables = Exact<{ attributes: ConsoleInstanceAttributes; }>; -export type CreateConsoleInstanceMutation = { __typename?: 'RootMutationType', createConsoleInstance?: { __typename?: 'ConsoleInstance', id: string, name: string, subdomain: string, url: string, cloud: CloudProvider, size: ConsoleSize, region: string, status: ConsoleInstanceStatus, deletedAt?: Date | null, insertedAt?: Date | null, updatedAt?: Date | null, console?: { __typename?: 'Cluster', id: string, pingedAt?: Date | null } | null, owner?: { __typename?: 'User', name: string, email: string } | null } | null }; +export type CreateConsoleInstanceMutation = { __typename?: 'RootMutationType', createConsoleInstance?: { __typename?: 'ConsoleInstance', id: string, name: string, subdomain: string, url: string, cloud: CloudProvider, size: ConsoleSize, region: string, status: ConsoleInstanceStatus, deletedAt?: Date | null, insertedAt?: Date | null, updatedAt?: Date | null, console?: { __typename?: 'Cluster', id: string, pingedAt?: Date | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null } | null, owner?: { __typename?: 'User', name: string, email: string } | null } | null }; export type UpdateConsoleInstanceMutationVariables = Exact<{ id: Scalars['ID']['input']; @@ -5637,14 +5637,14 @@ export type UpdateConsoleInstanceMutationVariables = Exact<{ }>; -export type UpdateConsoleInstanceMutation = { __typename?: 'RootMutationType', updateConsoleInstance?: { __typename?: 'ConsoleInstance', id: string, name: string, subdomain: string, url: string, cloud: CloudProvider, size: ConsoleSize, region: string, status: ConsoleInstanceStatus, deletedAt?: Date | null, insertedAt?: Date | null, updatedAt?: Date | null, console?: { __typename?: 'Cluster', id: string, pingedAt?: Date | null } | null, owner?: { __typename?: 'User', name: string, email: string } | null } | null }; +export type UpdateConsoleInstanceMutation = { __typename?: 'RootMutationType', updateConsoleInstance?: { __typename?: 'ConsoleInstance', id: string, name: string, subdomain: string, url: string, cloud: CloudProvider, size: ConsoleSize, region: string, status: ConsoleInstanceStatus, deletedAt?: Date | null, insertedAt?: Date | null, updatedAt?: Date | null, console?: { __typename?: 'Cluster', id: string, pingedAt?: Date | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null } | null, owner?: { __typename?: 'User', name: string, email: string } | null } | null }; export type DeleteConsoleInstanceMutationVariables = Exact<{ id: Scalars['ID']['input']; }>; -export type DeleteConsoleInstanceMutation = { __typename?: 'RootMutationType', deleteConsoleInstance?: { __typename?: 'ConsoleInstance', id: string, name: string, subdomain: string, url: string, cloud: CloudProvider, size: ConsoleSize, region: string, status: ConsoleInstanceStatus, deletedAt?: Date | null, insertedAt?: Date | null, updatedAt?: Date | null, console?: { __typename?: 'Cluster', id: string, pingedAt?: Date | null } | null, owner?: { __typename?: 'User', name: string, email: string } | null } | null }; +export type DeleteConsoleInstanceMutation = { __typename?: 'RootMutationType', deleteConsoleInstance?: { __typename?: 'ConsoleInstance', id: string, name: string, subdomain: string, url: string, cloud: CloudProvider, size: ConsoleSize, region: string, status: ConsoleInstanceStatus, deletedAt?: Date | null, insertedAt?: Date | null, updatedAt?: Date | null, console?: { __typename?: 'Cluster', id: string, pingedAt?: Date | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null } | null, owner?: { __typename?: 'User', name: string, email: string } | null } | null }; export type RecipeFragment = { __typename?: 'Recipe', id: string, name: string, description?: string | null, restricted?: boolean | null, provider?: Provider | null, tests?: Array<{ __typename?: 'RecipeTest', type: TestType, name: string, message?: string | null, args?: Array<{ __typename?: 'TestArgument', name: string, repo: string, key: string } | null> | null } | null> | null, repository?: { __typename?: 'Repository', id: string, name: string } | null, oidcSettings?: { __typename?: 'OidcSettings', uriFormat?: string | null, uriFormats?: Array | null, authMethod: OidcAuthMethod, domainKey?: string | null, subdomain?: boolean | null } | null, recipeSections?: Array<{ __typename?: 'RecipeSection', index?: number | null, repository?: { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, installation?: { __typename?: 'Installation', id: string, context?: Map | null, license?: string | null, licenseKey?: string | null, acmeKeyId?: string | null, acmeSecret?: string | null, autoUpgrade?: boolean | null, trackTag: string, pingedAt?: Date | null, repository?: { __typename?: 'Repository', id: string, name: string, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null } | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, oidcProvider?: { __typename?: 'OidcProvider', id: string, clientId: string, authMethod: OidcAuthMethod, clientSecret: string, redirectUris?: Array | null, bindings?: Array<{ __typename?: 'OidcProviderBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null, configuration?: { __typename?: 'OuathConfiguration', issuer?: string | null, authorizationEndpoint?: string | null, tokenEndpoint?: string | null, jwksUri?: string | null, userinfoEndpoint?: string | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null } | null } | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null } | null, recipeItems?: Array<{ __typename?: 'RecipeItem', id?: string | null, chart?: { __typename?: 'Chart', id?: string | null, name: string, description?: string | null, latestVersion?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, terraform?: { __typename?: 'Terraform', id?: string | null, name?: string | null, readme?: string | null, package?: string | null, description?: string | null, latestVersion?: string | null, valuesTemplate?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, configuration?: Array<{ __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null } | null> | null } | null> | null, configuration?: Array<{ __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null } | null> | null } | null> | null }; @@ -7166,6 +7166,12 @@ export const ConsoleInstanceFragmentDoc = gql` console { id pingedAt + owner { + ...User + impersonationPolicy { + ...ImpersonationPolicy + } + } } owner { name @@ -7174,7 +7180,8 @@ export const ConsoleInstanceFragmentDoc = gql` insertedAt updatedAt } - `; + ${UserFragmentDoc} +${ImpersonationPolicyFragmentDoc}`; export const TerraformFragmentDoc = gql` fragment Terraform on Terraform { id diff --git a/www/src/graph/pluralCloud.graphql b/www/src/graph/pluralCloud.graphql index d59b8c92b..40ad10eb2 100644 --- a/www/src/graph/pluralCloud.graphql +++ b/www/src/graph/pluralCloud.graphql @@ -11,6 +11,12 @@ fragment ConsoleInstance on ConsoleInstance { console { id pingedAt + owner { + ...User + impersonationPolicy { + ...ImpersonationPolicy + } + } } owner { name From 2397fba17956279f744b5a82bcf728238cd34f02 Mon Sep 17 00:00:00 2001 From: Jake Laderman Date: Thu, 5 Sep 2024 02:00:32 -0400 Subject: [PATCH 13/17] update self hosted table --- www/src/App.tsx | 2 +- .../overview/clusters/SelfHostedTableCols.tsx | 228 ++++++------------ .../self-hosted/SelfHostedClusters.tsx | 15 +- 3 files changed, 77 insertions(+), 168 deletions(-) diff --git a/www/src/App.tsx b/www/src/App.tsx index df93ebb26..62371c4a3 100644 --- a/www/src/App.tsx +++ b/www/src/App.tsx @@ -20,7 +20,7 @@ import { mergeDeep } from '@apollo/client/utilities' import mpRecipe from 'honorable-recipe-mp' import { GrowthBook, GrowthBookProvider } from '@growthbook/growthbook-react' -import { PluralErrorBoundary } from 'components/utils/PluralErrorBoundary' +import { PluralErrorBoundary } from './components/utils/PluralErrorBoundary' import { client } from './helpers/client' import { INTERCOM_APP_ID } from './constants' diff --git a/www/src/components/overview/clusters/SelfHostedTableCols.tsx b/www/src/components/overview/clusters/SelfHostedTableCols.tsx index 73189e365..87500ac23 100644 --- a/www/src/components/overview/clusters/SelfHostedTableCols.tsx +++ b/www/src/components/overview/clusters/SelfHostedTableCols.tsx @@ -1,22 +1,18 @@ import { AppIcon, + Button, CaretRightIcon, - CheckRoundedIcon, - Chip, ConsoleIcon, IconFrame, TerminalIcon, } from '@pluralsh/design-system' -import styled from 'styled-components' import { createColumnHelper } from '@tanstack/react-table' -import { Link } from 'react-router-dom' import { A, Div } from 'honorable' -import { ReactElement, useState } from 'react' +import { Link } from 'react-router-dom' +import styled, { useTheme } from 'styled-components' +import { Source } from '../../../generated/graphql' import { ProviderIcon } from '../../utils/ProviderIcon' -import { Cluster, Source } from '../../../generated/graphql' -import CopyButton from '../../utils/CopyButton' -import { ClusterPromoteModal } from '../../cluster/ClusterPromoteModal' import ClusterHealth from './ClusterHealth' import ClusterOwner from './ClusterOwner' @@ -46,6 +42,7 @@ const sourceDisplayNames = { export const ColCluster = columnHelper.accessor((row) => row.name, { id: 'cluster', + meta: { gridTemplate: '3fr' }, enableGlobalFilter: true, enableSorting: true, cell: ({ @@ -84,6 +81,7 @@ export const ColCluster = columnHelper.accessor((row) => row.name, { export const ColHealth = columnHelper.accessor((row) => row.pingedAt, { id: 'health', + meta: { gridTemplate: '1fr' }, enableGlobalFilter: true, enableSorting: true, cell: ({ @@ -99,59 +97,9 @@ export const ColHealth = columnHelper.accessor((row) => row.pingedAt, { header: 'Health', }) -export const ColGit = columnHelper.accessor((row) => row.gitUrl, { - id: 'git', - enableGlobalFilter: true, - enableSorting: true, - cell: ({ - row: { - original: { gitUrl }, - }, - }) => (gitUrl ? : undefined), - header: 'Git', -}) - -export const ColCloudShell = columnHelper.accessor( - (row) => row.owner?.hasShell, - { - id: 'cloudshell', - enableGlobalFilter: true, - enableSorting: true, - cell: ({ - row: { - original: { owner, accessible }, - }, - }) => - owner?.hasShell ? ( - accessible ? ( - } - as={Link} - to={`/shell?user=${owner?.id}`} - textValue="Go to cloudshell" - tooltip - type="floating" - style={{ - display: 'flex', - }} - /> - ) : ( - } - textValue="You aren't an administrator of this cluster" - tooltip - type="floating" - /> - ) - ) : null, - header: 'Cloudshell', - } -) - export const ColOwner = columnHelper.accessor((row) => row.owner?.name, { id: 'owner', + meta: { gridTemplate: '2fr' }, enableGlobalFilter: true, enableSorting: true, cell: ({ @@ -168,104 +116,78 @@ export const ColOwner = columnHelper.accessor((row) => row.owner?.name, { header: 'Owner', }) -type PromotionsProps = { cluster: Cluster } - -function Promotions({ cluster }: PromotionsProps): ReactElement { - const [promoteOpen, setPromoteOpen] = useState(false) - - return ( - <> - setPromoteOpen(true)} - icon={} - type="floating" - /> - - - ) -} - -export const ColPromotions = columnHelper.accessor((row) => row, { - id: 'promotions', - enableGlobalFilter: true, - enableSorting: true, - cell: ({ - row: { - original: { hasDependency, raw }, - }, - }) => hasDependency && , - header: 'Promotions', -}) - -export const ColUpgrades = columnHelper.accessor((row) => row, { - id: 'upgrades', - enableGlobalFilter: true, - enableSorting: true, - cell: ({ row: { original: row } }) => - clusterExists(row) && ( - - {row.delivered ? 'Delivered' : 'Pending'} - - ), - header: 'Upgrades', -}) - const ActionsWrap = styled(CellWrap)({ alignSelf: 'end' }) export const ColActions = columnHelper.accessor((row) => row.consoleUrl, { id: 'actions', + header: '', + meta: { gridTemplate: 'max-content' }, enableGlobalFilter: false, enableSorting: false, - cell: ({ row: { original: row } }) => ( - - {row.consoleUrl && ( - } - textValue="Launch Console" - tooltip - type="secondary" - onClick={() => window.open(row.consoleUrl!, '_blank')} - /> - )} - {row.accessible && clusterExists(row) ? ( - } - as={Link} - to={`/clusters/${row.id}`} - textValue="Go to cluster details" - tooltip - type="tertiary" - style={{ - display: 'flex', - }} - /> - ) : ( - } - textValue={ - !clusterExists(row) - ? '' - : "You aren't an administrator of this cluster" - } - tooltip - type="tertiary" - /> - )} - - ), - header: '', + cell: function Cell({ row: { original: row } }) { + const theme = useTheme() + + return ( + + {!row.owner?.hasShell && row.accessible && ( + + )} + {row.consoleUrl && ( + + )} + + {row.accessible && clusterExists(row) ? ( + } + as={Link} + to={`/clusters/${row.id}`} + textValue="Go to cluster details" + tooltip + type="tertiary" + style={{ + display: 'flex', + }} + /> + ) : ( + } + textValue={ + !clusterExists(row) + ? '' + : "You aren't an administrator of this cluster" + } + tooltip + type="tertiary" + /> + )} + + ) + }, }) diff --git a/www/src/components/overview/clusters/self-hosted/SelfHostedClusters.tsx b/www/src/components/overview/clusters/self-hosted/SelfHostedClusters.tsx index 4037b8a1a..dd942dd3b 100644 --- a/www/src/components/overview/clusters/self-hosted/SelfHostedClusters.tsx +++ b/www/src/components/overview/clusters/self-hosted/SelfHostedClusters.tsx @@ -4,13 +4,9 @@ import { ClusterList } from '../ClusterList' import { CLUSTERS_OVERVIEW_BREADCRUMBS } from '../Clusters' import { ColActions, - ColCloudShell, ColCluster, - ColGit, ColHealth, ColOwner, - ColPromotions, - ColUpgrades, } from '../SelfHostedTableCols' const breadcrumbs = [ @@ -31,13 +27,4 @@ export function SelfHostedClusters() { ) } -const columns = [ - ColCluster, - ColHealth, - ColGit, - ColCloudShell, - ColOwner, - ColUpgrades, - ColPromotions, - ColActions, -] +const columns = [ColCluster, ColHealth, ColOwner, ColActions] From 967686ffb37f6187e341c0e116233f3a0ae8c102 Mon Sep 17 00:00:00 2001 From: Jake Laderman Date: Thu, 5 Sep 2024 16:54:07 -0400 Subject: [PATCH 14/17] add progress persistence --- .../create-cluster/CreateCluster.tsx | 40 ++++++++++++++----- .../create-cluster/CreateClusterActions.tsx | 27 ++++++++----- .../create-cluster/CreateClusterWizard.tsx | 4 +- .../clusters/plural-cloud/DeleteInstance.tsx | 10 +++++ .../plural-cloud/PluralCloudInstances.tsx | 8 ++-- 5 files changed, 63 insertions(+), 26 deletions(-) diff --git a/www/src/components/create-cluster/CreateCluster.tsx b/www/src/components/create-cluster/CreateCluster.tsx index abdf277df..cceba5e0d 100644 --- a/www/src/components/create-cluster/CreateCluster.tsx +++ b/www/src/components/create-cluster/CreateCluster.tsx @@ -18,6 +18,8 @@ import { import { GqlError } from 'components/utils/Alert' +import usePersistedState from 'hooks/usePersistedState' + import { ConsoleCreationStatus } from './ConsoleCreationStatus' import { CreateClusterActions } from './CreateClusterActions' import { @@ -28,18 +30,25 @@ import { localSteps, } from './CreateClusterWizard' +export const CUR_CREATE_CLUSTER_STEP_KEY = 'cur-create-cluster-step' +export const HOSTING_OPTION_KEY = 'hosting-option' +export const CUR_CONSOLE_INSTANCE_KEY = 'cur-console-instance-id' + export function CreateCluster() { const theme = useTheme() const navigate = useNavigate() - const [curStep, setCurStep] = useState( + const [curStep, setCurStep] = usePersistedState( + CUR_CREATE_CLUSTER_STEP_KEY, CreateClusterStepKey.HostingOptions ) - const [hostingOption, setHostingOption] = useState<'local' | 'cloud'>('local') + const [hostingOption, setHostingOption] = usePersistedState< + 'local' | 'cloud' + >(HOSTING_OPTION_KEY, 'local') const [finishEnabled, setFinishEnabled] = useState(false) const [continueBtn, setContinueBtn] = useState() - const [consoleInstanceId, setConsoleInstanceId] = useState< - string | undefined - >() + const [consoleInstanceId, setConsoleInstanceId] = usePersistedState< + string | null + >(CUR_CONSOLE_INSTANCE_KEY, null) const steps = hostingOption === 'local' ? localSteps : cloudSteps const curStepIndex = steps.findIndex((step) => step.key === curStep) @@ -50,7 +59,7 @@ export function CreateCluster() { }, skip: !consoleInstanceId, fetchPolicy: 'cache-and-network', - pollInterval: 10000, + pollInterval: 10_000, }) const context: CreateClusterContextType = useMemo( @@ -66,17 +75,22 @@ export function CreateCluster() { consoleInstanceId, setConsoleInstanceId, consoleUrl: data?.consoleInstance?.url, - isCreatingInstance: !( - data?.consoleInstance?.console?.pingedAt && - data.consoleInstance.status === ConsoleInstanceStatus.Provisioned - ), + isCreatingInstance: + !!consoleInstanceId && + !( + data?.consoleInstance?.console?.pingedAt && + data.consoleInstance.status === ConsoleInstanceStatus.Provisioned + ), }), [ curStep, + setCurStep, hostingOption, + setHostingOption, finishEnabled, continueBtn, consoleInstanceId, + setConsoleInstanceId, data?.consoleInstance?.url, data?.consoleInstance?.console?.pingedAt, data?.consoleInstance?.status, @@ -132,6 +146,12 @@ export function CreateCluster() { ) } +export function clearCreateClusterState() { + localStorage.removeItem(`plural-${CUR_CREATE_CLUSTER_STEP_KEY}`) + localStorage.removeItem(`plural-${HOSTING_OPTION_KEY}`) + localStorage.removeItem(`plural-${CUR_CONSOLE_INSTANCE_KEY}`) +} + const MainWrapperSC = styled.div(({ theme }) => ({ display: 'flex', justifyContent: 'space-between', diff --git a/www/src/components/create-cluster/CreateClusterActions.tsx b/www/src/components/create-cluster/CreateClusterActions.tsx index 54428c0cd..ce078c660 100644 --- a/www/src/components/create-cluster/CreateClusterActions.tsx +++ b/www/src/components/create-cluster/CreateClusterActions.tsx @@ -4,12 +4,14 @@ import { useTheme } from 'styled-components' import { useNavigate } from 'react-router-dom' import { + CreateClusterStepKey, cloudSteps, localSteps, useCreateClusterContext, } from './CreateClusterWizard' +import { clearCreateClusterState } from './CreateCluster' -export const NEW_CONSOLE_INSTANCE_KEY = 'new-console-instance' +export const FINISHED_CONSOLE_INSTANCE_KEY = 'finished-console-instance' export function CreateClusterActions() { const theme = useTheme() @@ -30,8 +32,9 @@ export function CreateClusterActions() { const handleFinish = () => { if (consoleInstanceId) { - localStorage.setItem(NEW_CONSOLE_INSTANCE_KEY, consoleInstanceId) + localStorage.setItem(FINISHED_CONSOLE_INSTANCE_KEY, consoleInstanceId) } + clearCreateClusterState() navigate( `/overview/clusters/${ hostingOption === 'local' ? 'self-hosted' : 'plural-cloud' @@ -60,14 +63,18 @@ export function CreateClusterActions() { Read docs - {prevStep && ( - - )} + {prevStep && + !( + hostingOption === 'cloud' && + curStep === CreateClusterStepKey.InstallCli + ) && ( + + )} {nextStep ? ( continueBtn || ( diff --git a/www/src/components/create-cluster/CreateClusterWizard.tsx b/www/src/components/create-cluster/CreateClusterWizard.tsx index 6b6e5eb56..9bee76b62 100644 --- a/www/src/components/create-cluster/CreateClusterWizard.tsx +++ b/www/src/components/create-cluster/CreateClusterWizard.tsx @@ -39,8 +39,8 @@ export type CreateClusterContextType = { setFinishEnabled: (enabled: boolean) => void continueBtn?: ReactElement setContinueBtn: (continueBtn?: ReactElement) => void - consoleInstanceId?: string - setConsoleInstanceId: (consoleInstanceId?: string) => void + consoleInstanceId: string | null + setConsoleInstanceId: (consoleInstanceId: string | null) => void consoleUrl?: string isCreatingInstance: boolean } diff --git a/www/src/components/overview/clusters/plural-cloud/DeleteInstance.tsx b/www/src/components/overview/clusters/plural-cloud/DeleteInstance.tsx index 672b21c3c..622fa93d9 100644 --- a/www/src/components/overview/clusters/plural-cloud/DeleteInstance.tsx +++ b/www/src/components/overview/clusters/plural-cloud/DeleteInstance.tsx @@ -7,6 +7,10 @@ import { useDeleteConsoleInstanceMutation, } from 'generated/graphql' import { useState } from 'react' +import { + CUR_CONSOLE_INSTANCE_KEY, + clearCreateClusterState, +} from 'components/create-cluster/CreateCluster' export function DeleteInstanceModal({ open, @@ -47,6 +51,12 @@ function DeleteInstance({ const [mutation, { loading, error }] = useDeleteConsoleInstanceMutation({ variables: { id: instance.id }, onCompleted: () => { + if ( + `"${instance.id}"` === + localStorage.getItem(`plural-${CUR_CONSOLE_INSTANCE_KEY}`) + ) { + clearCreateClusterState() + } onClose() refetch() }, diff --git a/www/src/components/overview/clusters/plural-cloud/PluralCloudInstances.tsx b/www/src/components/overview/clusters/plural-cloud/PluralCloudInstances.tsx index b0ed56831..431e7f24f 100644 --- a/www/src/components/overview/clusters/plural-cloud/PluralCloudInstances.tsx +++ b/www/src/components/overview/clusters/plural-cloud/PluralCloudInstances.tsx @@ -4,10 +4,10 @@ import { useContext, useEffect, useState } from 'react' import ConsoleInstancesContext from 'contexts/ConsoleInstancesContext' -import { NEW_CONSOLE_INSTANCE_KEY } from 'components/create-cluster/CreateClusterActions' - import { useTheme } from 'styled-components' +import { FINISHED_CONSOLE_INSTANCE_KEY } from 'components/create-cluster/CreateClusterActions' + import { CLUSTERS_OVERVIEW_BREADCRUMBS } from '../Clusters' import { cloudInstanceCols } from './CloudInstanceTableCols' @@ -26,10 +26,10 @@ export function PluralCloudInstances() { const { instances } = useContext(ConsoleInstancesContext) useEffect(() => { - const id = localStorage.getItem(NEW_CONSOLE_INSTANCE_KEY) + const id = localStorage.getItem(FINISHED_CONSOLE_INSTANCE_KEY) if (id && instances.some((i) => i.id === id)) { - localStorage.removeItem(NEW_CONSOLE_INSTANCE_KEY) + localStorage.removeItem(FINISHED_CONSOLE_INSTANCE_KEY) setShowToast(true) } }, [instances]) From 0754b06a89b28cb481096a40686d295aef323e06 Mon Sep 17 00:00:00 2001 From: Jake Laderman Date: Fri, 6 Sep 2024 00:22:29 -0400 Subject: [PATCH 15/17] add fixes --- www/src/components/account/utils.ts | 16 +- .../steps/HostingOptionsStep.tsx | 72 +++- .../overview/CreateClusterAction.tsx | 24 -- .../overview/CreateClusterModal.tsx | 404 ------------------ .../components/overview/OverviewHeader.tsx | 13 +- .../components/overview/clusters/Clusters.tsx | 8 +- .../overview/clusters/ClustersHelpSection.tsx | 20 +- .../plural-cloud/CloudInstanceTableCols.tsx | 18 +- .../plural-cloud/ConsoleInstanceOIDC.tsx | 177 ++++++++ .../sections/cli/CLIInstallationStep.tsx | 106 ++--- .../utils/ImpersonateServiceAccount.tsx | 15 +- www/src/generated/graphql.ts | 43 ++ www/src/graph/pluralCloud.graphql | 6 + 13 files changed, 397 insertions(+), 525 deletions(-) delete mode 100644 www/src/components/overview/CreateClusterAction.tsx delete mode 100644 www/src/components/overview/CreateClusterModal.tsx create mode 100644 www/src/components/overview/clusters/plural-cloud/ConsoleInstanceOIDC.tsx diff --git a/www/src/components/account/utils.ts b/www/src/components/account/utils.ts index 2cc667e23..214fad1e4 100644 --- a/www/src/components/account/utils.ts +++ b/www/src/components/account/utils.ts @@ -1,15 +1,21 @@ import { apiHost } from '../../helpers/hostname' -import { Permission } from '../../generated/graphql' +import { Group, Permission, User } from '../../generated/graphql' import { notNil } from '../../utils/ts-notNil' import { CurrentUser } from '../../contexts/CurrentUserContext' export const inviteLink = (invite) => `https://${apiHost()}/invite/${invite.secureId}` -export const sanitize = ({ id, user, group }) => ({ - id, - userId: user && user.id, - groupId: group && group.id, +export type SanitizePropsType = Nullable<{ + id: Nullable + user: Nullable + group: Nullable +}> + +export const sanitize = (props: SanitizePropsType) => ({ + id: props?.id, + userId: props?.user?.id, + groupId: props?.group?.id, }) export function hasRbac(user: CurrentUser, permission: Permission) { diff --git a/www/src/components/create-cluster/steps/HostingOptionsStep.tsx b/www/src/components/create-cluster/steps/HostingOptionsStep.tsx index d32213177..42106e4ae 100644 --- a/www/src/components/create-cluster/steps/HostingOptionsStep.tsx +++ b/www/src/components/create-cluster/steps/HostingOptionsStep.tsx @@ -1,27 +1,67 @@ -import { CloudIcon, ConsoleIcon, Flex } from '@pluralsh/design-system' +import { Callout, CloudIcon, ConsoleIcon, Flex } from '@pluralsh/design-system' import { CloudOption } from 'components/shell/onboarding/sections/cloud/CloudOption' +import { useBillingSubscription } from 'components/account/billing/BillingSubscriptionProvider' + import { useCreateClusterContext } from '../CreateClusterWizard' export function HostingOptionsStep() { const { hostingOption, setHostingOption } = useCreateClusterContext() + const { isPaidPlan, isTrialPlan, daysUntilTrialExpires, isTrialExpired } = + useBillingSubscription() + const isFreePlan = !isPaidPlan && !isTrialPlan return ( - - setHostingOption('local')} - icon={} - header="Deploy Yourself" - description="Host your control plane in your own cloud." - /> - setHostingOption('cloud')} - icon={} - header="Use Plural Cloud" - description="Host your control plane in a Plural Cloud instance." - /> + + + setHostingOption('local')} + icon={} + header="Deploy Yourself" + description="Host your control plane in your own cloud." + /> + setHostingOption('cloud')} + icon={} + header="Use Plural Cloud" + description="Host your control plane in a Plural Cloud instance." + /> + + {hostingOption === 'cloud' && + (isFreePlan || (isTrialPlan && isTrialExpired) ? ( + + To use a Plural Cloud Instance for your cluster deployment, consider{' '} + + upgrading your plan. + + + ) : isTrialPlan ? ( + + Once your free trial ends, you can keep on using your Plural Cloud + instance by{' '} + + upgrading your plan. + + + ) : null)} ) } diff --git a/www/src/components/overview/CreateClusterAction.tsx b/www/src/components/overview/CreateClusterAction.tsx deleted file mode 100644 index 4fab2df58..000000000 --- a/www/src/components/overview/CreateClusterAction.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { Button } from '@pluralsh/design-system' -import { ReactElement, useState } from 'react' - -import CreateClusterModal from './CreateClusterModal' - -function CreateClusterButton(): ReactElement { - const [createClusterModalOpen, setCreateClusterModalOpen] = useState(false) - - return ( - <> - - {createClusterModalOpen && ( - setCreateClusterModalOpen(false)} - /> - )} - - ) -} - -export default CreateClusterButton diff --git a/www/src/components/overview/CreateClusterModal.tsx b/www/src/components/overview/CreateClusterModal.tsx deleted file mode 100644 index 97585da54..000000000 --- a/www/src/components/overview/CreateClusterModal.tsx +++ /dev/null @@ -1,404 +0,0 @@ -import { useMutation, useQuery } from '@apollo/client' -import { - AppIcon, - Button, - CaretLeftIcon, - FormField, - Input, - ListBoxFooter, - ListBoxItem, - Modal, - PlusIcon, - Select, -} from '@pluralsh/design-system' -import { - Key, - ReactElement, - useCallback, - useContext, - useEffect, - useMemo, - useState, -} from 'react' -import { useNavigate } from 'react-router-dom' -import styled from 'styled-components' - -import ClustersContext from '../../contexts/ClustersContext' -import { useCurrentUser } from '../../contexts/CurrentUserContext' -import subscriptionContext from '../../contexts/SubscriptionContext' -import { - Cluster, - RootMutationType, - RootMutationTypeCreateServiceAccountArgs, - RootQueryType, - RootQueryTypeUsersArgs, - User, -} from '../../generated/graphql' -import { CREATE_SERVICE_ACCOUNT, USERS_Q } from '../account/queries' -import UpgradeNeededModal from '../cluster/UpgradeNeededModal' -import { GqlError } from '../utils/Alert' -import LoadingIndicator from '../utils/LoadingIndicator' - -const toUserList = (connection: Pick): Array => - connection?.users?.edges?.map((u) => u!.node!) ?? [] - -function useGetUsersWithoutCluster(clusters: Array) { - const { - data, - fetchMore, - refetch: refetchUsers, - } = useQuery, RootQueryTypeUsersArgs>(USERS_Q, { - fetchPolicy: 'network-only', - variables: { serviceAccount: true }, - }) - const [users, setUsers] = useState>([]) - const [loaded, setLoaded] = useState(false) - const [loading, setLoading] = useState(false) - - const ownerSet = useMemo( - () => new Set(clusters.map((c) => c.owner?.id ?? '')), - [clusters] - ) - - const refetch = useCallback( - (onComplete: () => void) => { - refetchUsers().then(() => { - setUsers([]) - setLoading(false) - setLoaded(false) - onComplete() - }) - }, - [refetchUsers] - ) - - const reset = useCallback(() => { - setUsers([]) - setLoading(false) - setLoaded(false) - }, []) - - useEffect(() => { - if (!data || loaded || loading) return - - setLoading(true) - const fetch = async () => { - let hasNextPage = data?.users?.pageInfo.hasNextPage ?? false - let cursor = data?.users?.pageInfo.endCursor - - setUsers(toUserList(data)) - while (hasNextPage) { - const { data: connection } = await fetchMore({ - variables: { serviceAccount: true, cursor }, - }) - - hasNextPage = connection?.users?.pageInfo.hasNextPage ?? false - cursor = connection?.users?.pageInfo.endCursor - setUsers((users) => [...users, ...toUserList(connection)]) - } - - setUsers((users) => - users.filter((u) => !ownerSet.has(u.id) && !u.hasInstallations) - ) - setLoaded(true) - setLoading(false) - } - - fetch() - }, [data, fetchMore, loaded, loading, ownerSet]) - - return { users, loaded, refetch, reset } -} - -const Wrap = styled.div((_) => ({ - display: 'flex', - flexDirection: 'column', -})) - -const Message = styled.div(({ theme }) => ({ - ...theme.partials.text.body2, - marginBottom: theme.spacing.large, -})) - -const Header = styled.div(({ theme }) => ({ - ...theme.partials.text.overline, - display: 'flex', -})) - -const ActionContainer = styled.div((_) => ({ - display: 'flex', - justifyContent: 'space-between', -})) - -const Spacer = styled.div(({ theme }) => ({ - marginTop: theme.spacing.large, -})) - -const CreateNewServiceAccountButton = styled( - CreateNewServiceAccountButtonUnstyled -)(({ theme }) => ({ - ...theme.partials.text.body2, - color: theme.colors['text-primary-accent'], -})) - -function CreateNewServiceAccountButtonUnstyled({ onClick, ...props }) { - return ( - - } - {...props} - > - Create new Service Account - - ) -} - -enum UserSelectionMode { - Select, - Input, -} - -function ClusterOwnerSelect({ - setMode, - items, - selectedKey, - setSelectedKey, - onClose, -}): ReactElement { - const navigate = useNavigate() - const me = useCurrentUser() - const [selectOpen, setSelectOpen] = useState(false) - - return ( - <> - - Choose an owner for the cluster. Only users without existing cluster are - available for selection. - - - - - - - - - - ) -} - -function ClusterOwnerInput({ - setMode, - showBackButton, - refetch, - setSelectedKey, - onClose, -}): ReactElement { - const me = useCurrentUser() - const [name, setName] = useState() - const [mutation, { loading, error }] = useMutation< - Pick, - RootMutationTypeCreateServiceAccountArgs - >(CREATE_SERVICE_ACCOUNT, { - variables: { - attributes: { - name, - impersonationPolicy: { bindings: [{ userId: me.id }] }, - }, - }, - onCompleted: (result) => - refetch(() => { - setMode(UserSelectionMode.Select) - setSelectedKey(result.createServiceAccount?.id) - }), - }) - - return ( - <> - {error && ( - <> - - - - )} - - Create a new service account that will become an owner of the cluster. - - - setName(value)} - placeholder="Name" - /> - - {showBackButton ? ( - - - - - ) : ( - - - - - )} - - ) -} - -function CreateClusterModal({ open, onClose }): ReactElement { - const { isPaidPlan, isTrialPlan } = useContext(subscriptionContext) - const [mode, setMode] = useState(UserSelectionMode.Select) - const me = useCurrentUser() - const { clusters } = useContext(ClustersContext) - const { users, loaded, refetch, reset } = useGetUsersWithoutCluster(clusters) - - const hasCluster = useMemo( - () => clusters.some((c) => c.owner?.id === me.id), - [clusters, me.id] - ) - - const items = useMemo( - () => [...(hasCluster ? [...users] : [...users, me])], - [hasCluster, me, users] - ) - - const [selectedKey, setSelectedKey] = useState( - hasCluster ? undefined : me.id - ) - - useEffect( - () => - setMode( - items.length === 0 ? UserSelectionMode.Input : UserSelectionMode.Select - ), - [items.length] - ) - - if (!(isPaidPlan || isTrialPlan)) - return ( - - ) - - return ( - Create cluster} - open={open} - onClose={() => { - reset() - onClose() - }} - style={{ padding: 0 }} - > - {!loaded ? ( - - ) : ( - - {mode === UserSelectionMode.Select ? ( - - ) : ( - 0} - refetch={refetch} - setSelectedKey={setSelectedKey} - onClose={onClose} - /> - )} - - )} - - ) -} - -export default CreateClusterModal diff --git a/www/src/components/overview/OverviewHeader.tsx b/www/src/components/overview/OverviewHeader.tsx index a05b0d568..08096812d 100644 --- a/www/src/components/overview/OverviewHeader.tsx +++ b/www/src/components/overview/OverviewHeader.tsx @@ -3,6 +3,8 @@ import { Flex } from 'honorable' import { ReactElement, useRef } from 'react' import { useLocation, useNavigate } from 'react-router-dom' +import { CUR_CONSOLE_INSTANCE_KEY } from 'components/create-cluster/CreateCluster' + import { LinkTabWrap } from '../utils/Tabs' const DIRECTORY = [ @@ -15,6 +17,13 @@ export default function OverviewHeader(): ReactElement { const navigate = useNavigate() const { pathname } = useLocation() const currentTab = DIRECTORY.find((tab) => pathname?.startsWith(tab.path)) + const curConsoleInstanceId = localStorage.getItem( + `plural-${CUR_CONSOLE_INSTANCE_KEY}` + ) + const unfinishedCreation = + !!curConsoleInstanceId && + curConsoleInstanceId !== 'null' && + curConsoleInstanceId !== 'undefined' return ( @@ -36,7 +45,9 @@ export default function OverviewHeader(): ReactElement { ))} ) diff --git a/www/src/components/overview/clusters/Clusters.tsx b/www/src/components/overview/clusters/Clusters.tsx index e5ab851a7..8becb57fa 100644 --- a/www/src/components/overview/clusters/Clusters.tsx +++ b/www/src/components/overview/clusters/Clusters.tsx @@ -5,6 +5,8 @@ import { Flex } from '@pluralsh/design-system' import { Outlet } from 'react-router-dom' +import ConsoleInstancesContext from 'contexts/ConsoleInstancesContext' + import ClustersContext from '../../../contexts/ClustersContext' import OverviewHeader from '../OverviewHeader' @@ -24,15 +26,17 @@ export const CLUSTERS_OVERVIEW_BREADCRUMBS = [ export function Clusters(): ReactElement | null { const { clusters } = useContext(ClustersContext) + const { instances } = useContext(ConsoleInstancesContext) + const showEmpty = isEmpty(clusters) && isEmpty(instances) return ( - {isEmpty(clusters) ? ( + {showEmpty ? ( <> diff --git a/www/src/components/overview/clusters/ClustersHelpSection.tsx b/www/src/components/overview/clusters/ClustersHelpSection.tsx index 101a41f33..d8143fed7 100644 --- a/www/src/components/overview/clusters/ClustersHelpSection.tsx +++ b/www/src/components/overview/clusters/ClustersHelpSection.tsx @@ -7,19 +7,29 @@ import { SendMessageIcon, } from '@pluralsh/design-system' import { ReactElement } from 'react' -import ReactPlayer from 'react-player' import { useIntercom } from 'react-use-intercom' import styled from 'styled-components' export default function ClustersHelpSection(): ReactElement { const { show } = useIntercom() + // const [isVideoPlaying, setIsVideoPlaying] = useState(false) return ( + // taking out for the time being <> - + {/*
+ setIsVideoPlaying(true)} + /> +
*/}
Helpful resources
diff --git a/www/src/components/overview/clusters/plural-cloud/CloudInstanceTableCols.tsx b/www/src/components/overview/clusters/plural-cloud/CloudInstanceTableCols.tsx index c5942018a..e5f8e38cb 100644 --- a/www/src/components/overview/clusters/plural-cloud/CloudInstanceTableCols.tsx +++ b/www/src/components/overview/clusters/plural-cloud/CloudInstanceTableCols.tsx @@ -5,7 +5,6 @@ import { ConsoleIcon, Flex, ListBoxItem, - PeopleIcon, } from '@pluralsh/design-system' import { createColumnHelper } from '@tanstack/react-table' import { ProviderIcon } from 'components/utils/ProviderIcon' @@ -24,8 +23,9 @@ import { ClusterAdminsModal } from 'components/cluster/ClusterAdminsModal' import { CellCaption, CellWrap } from '../SelfHostedTableCols' -import { EditInstanceSizeModal } from './EditInstance' +import { ConsoleInstanceOIDC } from './ConsoleInstanceOIDC' import { DeleteInstanceModal } from './DeleteInstance' +import { EditInstanceSizeModal } from './EditInstance' const columnHelper = createColumnHelper() @@ -148,14 +148,10 @@ const ColActions = columnHelper.accessor((instance) => instance, { - + + e.preventDefault()} + open={open} + onClose={() => setOpen(false)} + > + + {errorMutation && } + + + + + + + + + ) +} + +function MiniProviderForm({ + provider, + bindings, + setBindings, +}: { + provider: Nullable + bindings: Omit[] + setBindings: (bindings: Omit[]) => void +}) { + return ( + <> + !!user) + .map(({ user }) => user?.email)} + customBindings={provider?.invites?.map((invite) => ( + + } + > + {invite?.email} + + + ))} + fetcher={fetchUsers} + add={(user) => setBindings([...bindings, { user }])} + remove={(email) => + setBindings( + bindings.filter(({ user }) => !user || user.email !== email) + ) + } + /> + !!group) + .map(({ group }) => group?.name)} + fetcher={fetchGroups} + add={(group) => setBindings([...bindings, { group }])} + remove={(name) => + setBindings( + bindings.filter(({ group }) => !group || group.name !== name) + ) + } + /> + + ) +} diff --git a/www/src/components/shell/onboarding/sections/cli/CLIInstallationStep.tsx b/www/src/components/shell/onboarding/sections/cli/CLIInstallationStep.tsx index 57969f371..d59b07004 100644 --- a/www/src/components/shell/onboarding/sections/cli/CLIInstallationStep.tsx +++ b/www/src/components/shell/onboarding/sections/cli/CLIInstallationStep.tsx @@ -3,6 +3,7 @@ import { A, Div, Flex, P } from 'honorable' import { Button, + Callout, Code, Codeline, Tab, @@ -97,25 +98,63 @@ export function CliInstallationBaseInfo() { -

+ <> {tab === TAB_MAC && 'Start by running this command in your local terminal:'} {tab === TAB_CURL && ( - <> - You can download the binaries attached to our   - + - GitHub releases - - . -
+ + ,{' '} + + Terraform + {' '} + and{' '} + + Kubectl + {' '} + are dependencies of the Plural CLI. + + + After downloading the dependencies above, you can download the + binaries attached to our{' '} + + GitHub releases + + . + For example, you can download the latest version for Darwin arm64 via: - + )} {tab === TAB_DOCKER && ( <> @@ -128,7 +167,7 @@ export function CliInstallationBaseInfo() { using, like (~/.aws), in the docker run command: )} -

+ {tab !== TAB_EC2 && ( <> @@ -150,11 +189,8 @@ export function CliInstallationBaseInfo() { {tab === TAB_MAC && ( <> The brew tap will install plural, alongside terraform, helm - and kubectl for you. -
- If you've already installed any of those dependencies, you can - add -
+ and kubectl for you. If you've already installed any of those + dependencies, you can add{' '} --without-helm @@ -169,38 +205,6 @@ export function CliInstallationBaseInfo() { . )} - {tab === TAB_CURL && ( - <> - You will still need to ensure   - - Helm - - ,   - - Terraform - -  and  - - Kubectl - -   are properly installed. - - )} {tab === TAB_DOCKER && ( <> Once you're in the container's zsh, you'll want to clone the diff --git a/www/src/components/utils/ImpersonateServiceAccount.tsx b/www/src/components/utils/ImpersonateServiceAccount.tsx index e00df7427..09a408c74 100644 --- a/www/src/components/utils/ImpersonateServiceAccount.tsx +++ b/www/src/components/utils/ImpersonateServiceAccount.tsx @@ -1,33 +1,36 @@ -import { ReactElement, useMemo } from 'react' import { ApolloProvider } from '@apollo/client' +import { ReactElement, useMemo } from 'react' -import { EmptyListMessage } from '../overview/clusters/misc' import { AuthTokenContext } from '../../contexts/AuthTokenContext' import useImpersonatedServiceAccount from '../../hooks/useImpersonatedServiceAccount' +import { EmptyListMessage } from '../overview/clusters/misc' import LoadingIndicator from './LoadingIndicator' type ImpersonateServiceAccountProps = { id?: string | null skip?: boolean + renderIndicators?: boolean children: ReactElement } export default function ImpersonateServiceAccount({ id, skip = false, + renderIndicators = true, children, -}: ImpersonateServiceAccountProps): ReactElement { +}: ImpersonateServiceAccountProps): ReactElement | null { const { token, client, error } = useImpersonatedServiceAccount(id, skip) const tokenCtxVal = useMemo(() => ({ token }), [token]) if (error) - return ( + return renderIndicators ? ( Error while impersonating service account: {error.message} - ) - if (!client) return + ) : null + + if (!client) return renderIndicators ? : null return ( diff --git a/www/src/generated/graphql.ts b/www/src/generated/graphql.ts index 75f1b33f0..8c2e03daa 100644 --- a/www/src/generated/graphql.ts +++ b/www/src/generated/graphql.ts @@ -5646,6 +5646,14 @@ export type DeleteConsoleInstanceMutationVariables = Exact<{ export type DeleteConsoleInstanceMutation = { __typename?: 'RootMutationType', deleteConsoleInstance?: { __typename?: 'ConsoleInstance', id: string, name: string, subdomain: string, url: string, cloud: CloudProvider, size: ConsoleSize, region: string, status: ConsoleInstanceStatus, deletedAt?: Date | null, insertedAt?: Date | null, updatedAt?: Date | null, console?: { __typename?: 'Cluster', id: string, pingedAt?: Date | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null } | null, owner?: { __typename?: 'User', name: string, email: string } | null } | null }; +export type UpdateOidcProviderMutationVariables = Exact<{ + id: Scalars['ID']['input']; + attributes: OidcAttributes; +}>; + + +export type UpdateOidcProviderMutation = { __typename?: 'RootMutationType', updateOidcProvider?: { __typename?: 'OidcProvider', id: string, clientId: string, authMethod: OidcAuthMethod, clientSecret: string, redirectUris?: Array | null, bindings?: Array<{ __typename?: 'OidcProviderBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null, configuration?: { __typename?: 'OuathConfiguration', issuer?: string | null, authorizationEndpoint?: string | null, tokenEndpoint?: string | null, jwksUri?: string | null, userinfoEndpoint?: string | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null } | null }; + export type RecipeFragment = { __typename?: 'Recipe', id: string, name: string, description?: string | null, restricted?: boolean | null, provider?: Provider | null, tests?: Array<{ __typename?: 'RecipeTest', type: TestType, name: string, message?: string | null, args?: Array<{ __typename?: 'TestArgument', name: string, repo: string, key: string } | null> | null } | null> | null, repository?: { __typename?: 'Repository', id: string, name: string } | null, oidcSettings?: { __typename?: 'OidcSettings', uriFormat?: string | null, uriFormats?: Array | null, authMethod: OidcAuthMethod, domainKey?: string | null, subdomain?: boolean | null } | null, recipeSections?: Array<{ __typename?: 'RecipeSection', index?: number | null, repository?: { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, installation?: { __typename?: 'Installation', id: string, context?: Map | null, license?: string | null, licenseKey?: string | null, acmeKeyId?: string | null, acmeSecret?: string | null, autoUpgrade?: boolean | null, trackTag: string, pingedAt?: Date | null, repository?: { __typename?: 'Repository', id: string, name: string, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null } | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, oidcProvider?: { __typename?: 'OidcProvider', id: string, clientId: string, authMethod: OidcAuthMethod, clientSecret: string, redirectUris?: Array | null, bindings?: Array<{ __typename?: 'OidcProviderBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null, configuration?: { __typename?: 'OuathConfiguration', issuer?: string | null, authorizationEndpoint?: string | null, tokenEndpoint?: string | null, jwksUri?: string | null, userinfoEndpoint?: string | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null } | null } | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null } | null, recipeItems?: Array<{ __typename?: 'RecipeItem', id?: string | null, chart?: { __typename?: 'Chart', id?: string | null, name: string, description?: string | null, latestVersion?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, terraform?: { __typename?: 'Terraform', id?: string | null, name?: string | null, readme?: string | null, package?: string | null, description?: string | null, latestVersion?: string | null, valuesTemplate?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, configuration?: Array<{ __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null } | null> | null } | null> | null, configuration?: Array<{ __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null } | null> | null } | null> | null }; export type RecipeItemFragment = { __typename?: 'RecipeItem', id?: string | null, chart?: { __typename?: 'Chart', id?: string | null, name: string, description?: string | null, latestVersion?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, terraform?: { __typename?: 'Terraform', id?: string | null, name?: string | null, readme?: string | null, package?: string | null, description?: string | null, latestVersion?: string | null, valuesTemplate?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, configuration?: Array<{ __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null } | null> | null }; @@ -9247,6 +9255,40 @@ export function useDeleteConsoleInstanceMutation(baseOptions?: Apollo.MutationHo export type DeleteConsoleInstanceMutationHookResult = ReturnType; export type DeleteConsoleInstanceMutationResult = Apollo.MutationResult; export type DeleteConsoleInstanceMutationOptions = Apollo.BaseMutationOptions; +export const UpdateOidcProviderDocument = gql` + mutation UpdateOidcProvider($id: ID!, $attributes: OidcAttributes!) { + updateOidcProvider(installationId: $id, attributes: $attributes) { + ...OIDCProvider + } +} + ${OidcProviderFragmentDoc}`; +export type UpdateOidcProviderMutationFn = Apollo.MutationFunction; + +/** + * __useUpdateOidcProviderMutation__ + * + * To run a mutation, you first call `useUpdateOidcProviderMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useUpdateOidcProviderMutation` returns a tuple that includes: + * - A mutate function that you can call at any time to execute the mutation + * - An object with fields that represent the current status of the mutation's execution + * + * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * + * @example + * const [updateOidcProviderMutation, { data, loading, error }] = useUpdateOidcProviderMutation({ + * variables: { + * id: // value for 'id' + * attributes: // value for 'attributes' + * }, + * }); + */ +export function useUpdateOidcProviderMutation(baseOptions?: Apollo.MutationHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useMutation(UpdateOidcProviderDocument, options); + } +export type UpdateOidcProviderMutationHookResult = ReturnType; +export type UpdateOidcProviderMutationResult = Apollo.MutationResult; +export type UpdateOidcProviderMutationOptions = Apollo.BaseMutationOptions; export const GetRecipeDocument = gql` query GetRecipe($repo: String, $name: String) { recipe(repo: $repo, name: $name) { @@ -11511,6 +11553,7 @@ export const namedOperations = { CreateConsoleInstance: 'CreateConsoleInstance', UpdateConsoleInstance: 'UpdateConsoleInstance', DeleteConsoleInstance: 'DeleteConsoleInstance', + UpdateOidcProvider: 'UpdateOidcProvider', CreateRecipe: 'CreateRecipe', InstallRecipe: 'InstallRecipe', CreateStack: 'CreateStack', diff --git a/www/src/graph/pluralCloud.graphql b/www/src/graph/pluralCloud.graphql index 40ad10eb2..737673df0 100644 --- a/www/src/graph/pluralCloud.graphql +++ b/www/src/graph/pluralCloud.graphql @@ -69,3 +69,9 @@ mutation DeleteConsoleInstance($id: ID!) { ...ConsoleInstance } } + +mutation UpdateOidcProvider($id: ID!, $attributes: OidcAttributes!) { + updateOidcProvider(installationId: $id, attributes: $attributes) { + ...OIDCProvider + } +} From ee1e2528d21085f8b828fe345444151106559773 Mon Sep 17 00:00:00 2001 From: Jake Laderman Date: Fri, 6 Sep 2024 13:16:07 -0400 Subject: [PATCH 16/17] oidc fixes --- www/src/components/app/oidc/OIDC.tsx | 2 +- .../components/cluster/ClusterAdminsModal.tsx | 22 ++- .../create-cluster/ConsoleCreationStatus.tsx | 10 +- .../create-cluster/CreateCluster.tsx | 15 +- .../create-cluster/CreateClusterActions.tsx | 20 +- .../create-cluster/CreateClusterWizard.tsx | 4 +- .../components/overview/OverviewHeader.tsx | 13 +- .../overview/clusters/ClusterList.tsx | 4 +- .../clusters/ClusterListEmptyState.tsx | 5 +- .../components/overview/clusters/Clusters.tsx | 66 ++++++- .../overview/clusters/ClustersHelpSection.tsx | 2 +- .../plural-cloud/ConsoleInstanceOIDC.tsx | 176 +++++++++++------- .../plural-cloud/PluralCloudInstances.tsx | 14 +- www/src/generated/graphql.ts | 136 +++++++------- www/src/graph/users.graphql | 3 + 15 files changed, 322 insertions(+), 170 deletions(-) diff --git a/www/src/components/app/oidc/OIDC.tsx b/www/src/components/app/oidc/OIDC.tsx index 85258ef9a..36c5dc183 100644 --- a/www/src/components/app/oidc/OIDC.tsx +++ b/www/src/components/app/oidc/OIDC.tsx @@ -41,7 +41,7 @@ import CreateGroupModal from '../../utils/group/CreateGroupModal' import ImpersonateServiceAccount from '../../utils/ImpersonateServiceAccount' import { AppHeaderActions } from '../AppHeaderActions' -function UrlsInput({ uriFormat = '', urls, setUrls }: any) { +export function UrlsInput({ uriFormat = '', urls, setUrls }: any) { const [baseScheme, basePath] = ['https://', '/oauth2/callback'] const [value, setValue] = useState('') const [scheme = baseScheme, path = basePath] = uriFormat diff --git a/www/src/components/cluster/ClusterAdminsModal.tsx b/www/src/components/cluster/ClusterAdminsModal.tsx index e4148a2da..9b6c84830 100644 --- a/www/src/components/cluster/ClusterAdminsModal.tsx +++ b/www/src/components/cluster/ClusterAdminsModal.tsx @@ -20,7 +20,7 @@ import { import ClustersContext from '../../contexts/ClustersContext' import subscriptionContext from '../../contexts/SubscriptionContext' -import { Group } from '../../generated/graphql' +import { Group, UserFragment } from '../../generated/graphql' import InviteUser from '../account/invite/InviteUser' import { UPDATE_SERVICE_ACCOUNT } from '../account/queries' import { BindingInput } from '../account/Typeaheads' @@ -43,6 +43,13 @@ function ClusterAdmins({ onGroupCreate, selected, showHeading = true, +}: { + serviceAccount: Nullable + onClose: () => void + onInvite: () => void + onGroupCreate: () => void + selected: any + showHeading?: boolean }): ReactElement { const [bindings, setBindings] = useState([ ...(serviceAccount?.impersonationPolicy?.bindings ?? []), @@ -51,7 +58,7 @@ function ClusterAdmins({ const [mutation, { loading, error }] = useMutation(UPDATE_SERVICE_ACCOUNT, { variables: { - id: serviceAccount.id, + id: serviceAccount?.id, attributes: { impersonationPolicy: { bindings: bindings.map(sanitize) } }, }, onCompleted: onClose, @@ -80,14 +87,14 @@ function ClusterAdmins({ bindings={bindings .filter(({ user }) => !!user) .map(({ user: { email } }) => email)} - customBindings={serviceAccount.invites?.map((invite) => ( + customBindings={serviceAccount?.invites?.map((invite) => ( } > - {invite.email} + {invite?.email} ))} @@ -151,6 +158,11 @@ export function ClusterAdminsModal({ onClose, serviceAccount, showHeading = true, +}: { + open?: boolean + onClose: () => void + serviceAccount: Nullable + showHeading?: boolean }) { const { refetchClusters } = useContext(ClustersContext) const { isPaidPlan, isTrialPlan } = useContext(subscriptionContext) @@ -220,7 +232,7 @@ export function ClusterAdminsModal({ onBack={() => setView(View.Managers)} bindings={groups} refetch={setOnCreateGroup} - serviceAccountId={serviceAccount.id} + serviceAccountId={serviceAccount?.id} /> )} {view === View.CreateGroup && ( diff --git a/www/src/components/create-cluster/ConsoleCreationStatus.tsx b/www/src/components/create-cluster/ConsoleCreationStatus.tsx index 11f0b6fbe..2f86f3685 100644 --- a/www/src/components/create-cluster/ConsoleCreationStatus.tsx +++ b/www/src/components/create-cluster/ConsoleCreationStatus.tsx @@ -25,10 +25,12 @@ export function ConsoleCreationStatus({ ? 'Creating console instance...' : 'Console successfully provisioned'} - + {!isCreatingInstance && ( + + )}
() const [consoleInstanceId, setConsoleInstanceId] = usePersistedState< - string | null + Nullable >(CUR_CONSOLE_INSTANCE_KEY, null) const steps = hostingOption === 'local' ? localSteps : cloudSteps @@ -129,7 +129,7 @@ export function CreateCluster() { secondary startIcon={} as="a" - href="mailto:sales@plural.sh" + href="https://plural.sh/contact-sales" target="_blank" rel="noopener noreferrer" > @@ -151,6 +151,17 @@ export function clearCreateClusterState() { localStorage.removeItem(`plural-${HOSTING_OPTION_KEY}`) localStorage.removeItem(`plural-${CUR_CONSOLE_INSTANCE_KEY}`) } +export function hasUnfinishedCreation() { + const curConsoleInstanceId = localStorage.getItem( + `plural-${CUR_CONSOLE_INSTANCE_KEY}` + ) + + return ( + !!curConsoleInstanceId && + curConsoleInstanceId !== 'null' && + curConsoleInstanceId !== 'undefined' + ) +} const MainWrapperSC = styled.div(({ theme }) => ({ display: 'flex', diff --git a/www/src/components/create-cluster/CreateClusterActions.tsx b/www/src/components/create-cluster/CreateClusterActions.tsx index ce078c660..8d25de53a 100644 --- a/www/src/components/create-cluster/CreateClusterActions.tsx +++ b/www/src/components/create-cluster/CreateClusterActions.tsx @@ -3,6 +3,8 @@ import { useTheme } from 'styled-components' import { useNavigate } from 'react-router-dom' +import { useBillingSubscription } from 'components/account/billing/BillingSubscriptionProvider' + import { CreateClusterStepKey, cloudSteps, @@ -11,7 +13,8 @@ import { } from './CreateClusterWizard' import { clearCreateClusterState } from './CreateCluster' -export const FINISHED_CONSOLE_INSTANCE_KEY = 'finished-console-instance' +export const FINISHED_CONSOLE_INSTANCE_KEY = 'plural-finished-console-instance' +export const FINISHED_LOCAL_CREATE_KEY = 'plural-finished-local-create' export function CreateClusterActions() { const theme = useTheme() @@ -25,6 +28,11 @@ export function CreateClusterActions() { consoleInstanceId, } = useCreateClusterContext() + const { isPaidPlan, isTrialPlan, isTrialExpired } = useBillingSubscription() + const disableContinue = + hostingOption === 'cloud' && + ((!isPaidPlan && !isTrialPlan) || (isTrialPlan && isTrialExpired)) + const steps = hostingOption === 'local' ? localSteps : cloudSteps const curStepIndex = steps.findIndex((step) => step.key === curStep) const prevStep = steps[curStepIndex - 1]?.key @@ -34,6 +42,9 @@ export function CreateClusterActions() { if (consoleInstanceId) { localStorage.setItem(FINISHED_CONSOLE_INSTANCE_KEY, consoleInstanceId) } + if (hostingOption === 'local') { + localStorage.setItem(FINISHED_LOCAL_CREATE_KEY, 'true') + } clearCreateClusterState() navigate( `/overview/clusters/${ @@ -77,7 +88,12 @@ export function CreateClusterActions() { )} {nextStep ? ( continueBtn || ( - + ) ) : (
) diff --git a/www/src/components/overview/clusters/ClusterList.tsx b/www/src/components/overview/clusters/ClusterList.tsx index aaeb8c25c..cd69ca83a 100644 --- a/www/src/components/overview/clusters/ClusterList.tsx +++ b/www/src/components/overview/clusters/ClusterList.tsx @@ -1,5 +1,4 @@ import { Table } from '@pluralsh/design-system' -import isEmpty from 'lodash/isEmpty' import { ComponentProps, memo, useContext, useMemo } from 'react' import ClustersContext from '../../../contexts/ClustersContext' @@ -64,12 +63,11 @@ export const ClusterList = memo(({ columns, ...props }: ClustersListProps) => { [clusters, me] ) - if (isEmpty(clusters)) return null - return ( ) diff --git a/www/src/components/overview/clusters/ClusterListEmptyState.tsx b/www/src/components/overview/clusters/ClusterListEmptyState.tsx index bc782fa5f..e1d74fb52 100644 --- a/www/src/components/overview/clusters/ClusterListEmptyState.tsx +++ b/www/src/components/overview/clusters/ClusterListEmptyState.tsx @@ -1,4 +1,5 @@ import { Button, Card, ClusterIcon, Flex } from '@pluralsh/design-system' +import { hasUnfinishedCreation } from 'components/create-cluster/CreateCluster' import { useNavigate } from 'react-router-dom' import styled, { useTheme } from 'styled-components' @@ -33,7 +34,9 @@ export default function ClusterListEmptyState() { css={{ maxWidth: 300, width: '100%' }} onClick={() => navigate('/create-cluster')} > - Create Cluster + {hasUnfinishedCreation() + ? 'Resume cluster creation' + : 'Create cluster'} diff --git a/www/src/components/overview/clusters/Clusters.tsx b/www/src/components/overview/clusters/Clusters.tsx index 8becb57fa..fa822a4a0 100644 --- a/www/src/components/overview/clusters/Clusters.tsx +++ b/www/src/components/overview/clusters/Clusters.tsx @@ -1,12 +1,20 @@ import { isEmpty } from 'lodash' -import { ReactElement, useContext } from 'react' +import { ReactElement, useContext, useEffect, useState } from 'react' -import { Flex } from '@pluralsh/design-system' +import { Button, Flex, Toast } from '@pluralsh/design-system' import { Outlet } from 'react-router-dom' import ConsoleInstancesContext from 'contexts/ConsoleInstancesContext' +import { FINISHED_LOCAL_CREATE_KEY } from 'components/create-cluster/CreateClusterActions' + +import { useTheme } from 'styled-components' + +import { ToastSeverity } from '@pluralsh/design-system/dist/components/Toast' + +import { useIntercom } from 'react-use-intercom' + import ClustersContext from '../../../contexts/ClustersContext' import OverviewHeader from '../OverviewHeader' @@ -25,10 +33,18 @@ export const CLUSTERS_OVERVIEW_BREADCRUMBS = [ ] export function Clusters(): ReactElement | null { + const [showToast, setShowToast] = useState(false) const { clusters } = useContext(ClustersContext) const { instances } = useContext(ConsoleInstancesContext) const showEmpty = isEmpty(clusters) && isEmpty(instances) + useEffect(() => { + if (localStorage.getItem(FINISHED_LOCAL_CREATE_KEY) === 'true') { + if (isEmpty(clusters)) setShowToast(true) + localStorage.removeItem(FINISHED_LOCAL_CREATE_KEY) + } + }, [clusters]) + return ( )} + setShowToast(false)} + /> ) } + +function ContactSupportToast({ + open, + onClose, +}: { + open: boolean + onClose: () => void +}) { + const theme = useTheme() + const intercom = useIntercom() + + return ( + + + + It looks like you still have no clusters deployed. + + + If you had trouble completing the steps to create a cluster, reach out + to us for support. + + + + + ) +} diff --git a/www/src/components/overview/clusters/ClustersHelpSection.tsx b/www/src/components/overview/clusters/ClustersHelpSection.tsx index d8143fed7..3d2b4a434 100644 --- a/www/src/components/overview/clusters/ClustersHelpSection.tsx +++ b/www/src/components/overview/clusters/ClustersHelpSection.tsx @@ -47,7 +47,7 @@ export default function ClustersHelpSection(): ReactElement { floating startIcon={} forwardedAs="a" - href="mailto:sales@plural.sh" + href="https://plural.sh/contact-sales" target="_blank" rel="noopener noreferrer" > diff --git a/www/src/components/overview/clusters/plural-cloud/ConsoleInstanceOIDC.tsx b/www/src/components/overview/clusters/plural-cloud/ConsoleInstanceOIDC.tsx index 264a8acc4..10908476b 100644 --- a/www/src/components/overview/clusters/plural-cloud/ConsoleInstanceOIDC.tsx +++ b/www/src/components/overview/clusters/plural-cloud/ConsoleInstanceOIDC.tsx @@ -1,11 +1,11 @@ import { + Accordion, + AccordionItem, Button, - Chip, Flex, - InfoOutlineIcon, + FormField, Modal, PeopleIcon, - Tooltip, } from '@pluralsh/design-system' import { BindingInput, @@ -13,36 +13,66 @@ import { fetchUsers, } from 'components/account/Typeaheads' import { SanitizePropsType, sanitize } from 'components/account/utils' +import { UrlsInput } from 'components/app/oidc/OIDC' import { GqlError } from 'components/utils/Alert' import ImpersonateServiceAccount from 'components/utils/ImpersonateServiceAccount' import { ConsoleInstanceFragment, + InputMaybe, OidcAuthMethod, OidcProviderBinding, - OidcProviderFragment, useRepositoryQuery, useUpdateOidcProviderMutation, } from 'generated/graphql' -import { Span } from 'honorable' +import { isEmpty } from 'lodash' import { useState } from 'react' +import { useTheme } from 'styled-components' export function ConsoleInstanceOIDC({ instance, }: { instance: ConsoleInstanceFragment }) { + const [open, setOpen] = useState(false) + return ( - + <> + + e.preventDefault()} + open={open} + onClose={() => setOpen(false)} + size="large" + > + setOpen(false)} + /> + + ) } -function ConsoleInstanceOIDCInner() { - const [open, setOpen] = useState(false) +function ConsoleInstanceOIDCInner({ + instance, + onClose, +}: { + instance: ConsoleInstanceFragment + onClose: () => void +}) { + const [bindings, setBindings] = useState([]) + const [redirectUris, setRedirectUris] = useState[]>([]) const { data, @@ -50,11 +80,17 @@ function ConsoleInstanceOIDCInner() { error: errorRepo, } = useRepositoryQuery({ variables: { name: 'console' }, + fetchPolicy: 'cache-and-network', + onCompleted: (data) => { + setBindings(data?.repository?.installation?.oidcProvider?.bindings) + setRedirectUris( + data?.repository?.installation?.oidcProvider?.redirectUris ?? [] + ) + }, }) const installation = data?.repository?.installation const provider = installation?.oidcProvider - const [bindings, setBindings] = useState(provider?.bindings ?? []) const [mutation, { loading: loadingMutation, error: errorMutation }] = useUpdateOidcProviderMutation({ @@ -62,75 +98,70 @@ function ConsoleInstanceOIDCInner() { id: installation?.id ?? '', attributes: { authMethod: provider?.authMethod ?? OidcAuthMethod.Post, + redirectUris: isEmpty(redirectUris) + ? [`https://${instance.url}/oauth/callback`] + : redirectUris, bindings: bindings.map((value) => sanitize(value as SanitizePropsType) ), }, }, - onCompleted: () => setOpen(false), + onCompleted: onClose, }) - if (!installation || loadingRepo || errorRepo) return null + if (!provider?.bindings || loadingRepo || errorRepo) return null return ( - <> - - e.preventDefault()} - open={open} - onClose={() => setOpen(false)} + + {errorMutation && } + + - - {errorMutation && } - - - - - - - - + Cancel + + + + ) } function MiniProviderForm({ - provider, bindings, setBindings, + redirectUris, + setRedirectUris, + uriFormat, }: { - provider: Nullable bindings: Omit[] setBindings: (bindings: Omit[]) => void + redirectUris: InputMaybe[] + setRedirectUris: (redirectUris: InputMaybe[]) => void + uriFormat?: string }) { + const theme = useTheme() + return ( <> !!user) .map(({ user }) => user?.email)} - customBindings={provider?.invites?.map((invite) => ( - - } - > - {invite?.email} - - - ))} fetcher={fetchUsers} add={(user) => setBindings([...bindings, { user }])} remove={(email) => @@ -172,6 +192,26 @@ function MiniProviderForm({ ) } /> + + advanced} + padding="compact" + > + + + + + ) } diff --git a/www/src/components/overview/clusters/plural-cloud/PluralCloudInstances.tsx b/www/src/components/overview/clusters/plural-cloud/PluralCloudInstances.tsx index 431e7f24f..53edb25da 100644 --- a/www/src/components/overview/clusters/plural-cloud/PluralCloudInstances.tsx +++ b/www/src/components/overview/clusters/plural-cloud/PluralCloudInstances.tsx @@ -1,6 +1,6 @@ import { Table, Toast, useSetBreadcrumbs } from '@pluralsh/design-system' -import { useContext, useEffect, useState } from 'react' +import { useContext, useEffect, useMemo, useState } from 'react' import ConsoleInstancesContext from 'contexts/ConsoleInstancesContext' @@ -8,6 +8,8 @@ import { useTheme } from 'styled-components' import { FINISHED_CONSOLE_INSTANCE_KEY } from 'components/create-cluster/CreateClusterActions' +import { ConsoleInstanceStatus } from 'generated/graphql' + import { CLUSTERS_OVERVIEW_BREADCRUMBS } from '../Clusters' import { cloudInstanceCols } from './CloudInstanceTableCols' @@ -23,7 +25,14 @@ export function PluralCloudInstances() { useSetBreadcrumbs(breadcrumbs) const [showToast, setShowToast] = useState(false) - const { instances } = useContext(ConsoleInstancesContext) + const { instances: instancesBase } = useContext(ConsoleInstancesContext) + const instances = useMemo( + () => + instancesBase.filter( + (i) => i.status !== ConsoleInstanceStatus.DeploymentDeleted + ), + [instancesBase] + ) useEffect(() => { const id = localStorage.getItem(FINISHED_CONSOLE_INSTANCE_KEY) @@ -39,6 +48,7 @@ export function PluralCloudInstances() {
; }; -export type AuditFragment = { __typename?: 'Audit', id: string, action: string, ip?: string | null, country?: string | null, city?: string | null, latitude?: string | null, longitude?: string | null, insertedAt?: Date | null, actor?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, repository?: { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null, integrationWebhook?: { __typename?: 'IntegrationWebhook', id: string, name: string, url: string, secret: string, actions?: Array | null } | null, role?: { __typename?: 'Role', id: string, name: string, description?: string | null, repositories?: Array | null, permissions?: Array | null, roleBindings?: Array<{ __typename?: 'RoleBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null } | null, version?: { __typename?: 'Version', id: string, helm?: Map | null, readme?: string | null, valuesTemplate?: string | null, version: string, insertedAt?: Date | null, package?: string | null, crds?: Array<{ __typename?: 'Crd', id: string, name: string, blob?: string | null } | null> | null, chart?: { __typename?: 'Chart', id?: string | null, name: string, description?: string | null, latestVersion?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, terraform?: { __typename?: 'Terraform', id?: string | null, name?: string | null } | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, image?: { __typename?: 'DockerImage', id: string, tag?: string | null, dockerRepository?: { __typename?: 'DockerRepository', name: string } | null } | null }; +export type AuditFragment = { __typename?: 'Audit', id: string, action: string, ip?: string | null, country?: string | null, city?: string | null, latitude?: string | null, longitude?: string | null, insertedAt?: Date | null, actor?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, repository?: { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null, integrationWebhook?: { __typename?: 'IntegrationWebhook', id: string, name: string, url: string, secret: string, actions?: Array | null } | null, role?: { __typename?: 'Role', id: string, name: string, description?: string | null, repositories?: Array | null, permissions?: Array | null, roleBindings?: Array<{ __typename?: 'RoleBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null } | null, version?: { __typename?: 'Version', id: string, helm?: Map | null, readme?: string | null, valuesTemplate?: string | null, version: string, insertedAt?: Date | null, package?: string | null, crds?: Array<{ __typename?: 'Crd', id: string, name: string, blob?: string | null } | null> | null, chart?: { __typename?: 'Chart', id?: string | null, name: string, description?: string | null, latestVersion?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, terraform?: { __typename?: 'Terraform', id?: string | null, name?: string | null } | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, image?: { __typename?: 'DockerImage', id: string, tag?: string | null, dockerRepository?: { __typename?: 'DockerRepository', name: string } | null } | null }; export type PolicyBindingFragment = { __typename?: 'PolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null }; -export type DnsDomainFragment = { __typename?: 'DnsDomain', id: string, name: string, insertedAt?: Date | null, creator?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, accessPolicy?: { __typename?: 'DnsAccessPolicy', id: string, bindings?: Array<{ __typename?: 'PolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null }; +export type DnsDomainFragment = { __typename?: 'DnsDomain', id: string, name: string, insertedAt?: Date | null, creator?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, accessPolicy?: { __typename?: 'DnsAccessPolicy', id: string, bindings?: Array<{ __typename?: 'PolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null }; -export type InviteFragment = { __typename?: 'Invite', id: string, secureId?: string | null, email?: string | null, insertedAt?: Date | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null }; +export type InviteFragment = { __typename?: 'Invite', id: string, secureId?: string | null, email?: string | null, insertedAt?: Date | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null }; -export type OidcLoginFragment = { __typename?: 'OidcLogin', ip?: string | null, country?: string | null, city?: string | null, latitude?: string | null, longitude?: string | null, insertedAt?: Date | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, repository?: { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null } | null }; +export type OidcLoginFragment = { __typename?: 'OidcLogin', ip?: string | null, country?: string | null, city?: string | null, latitude?: string | null, longitude?: string | null, insertedAt?: Date | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, repository?: { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null } | null }; export type UpdateAccountMutationVariables = Exact<{ attributes: AccountAttributes; @@ -5318,16 +5318,16 @@ export type UninstallChartMutationVariables = Exact<{ export type UninstallChartMutation = { __typename?: 'RootMutationType', deleteChartInstallation?: { __typename?: 'ChartInstallation', id?: string | null } | null }; -export type ClusterFragment = { __typename?: 'Cluster', id: string, name: string, provider: Provider, source?: Source | null, pingedAt?: Date | null, gitUrl?: string | null, consoleUrl?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, queue?: { __typename?: 'UpgradeQueue', id: string, acked?: string | null, upgrades?: { __typename?: 'UpgradeConnection', edges?: Array<{ __typename?: 'UpgradeEdge', node?: { __typename?: 'Upgrade', id: string } | null } | null> | null } | null } | null, upgradeInfo?: Array<{ __typename?: 'UpgradeInfo', count?: number | null, installation?: { __typename?: 'Installation', id: string, context?: Map | null, license?: string | null, licenseKey?: string | null, acmeKeyId?: string | null, acmeSecret?: string | null, autoUpgrade?: boolean | null, trackTag: string, pingedAt?: Date | null, repository?: { __typename?: 'Repository', id: string, name: string, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null } | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, oidcProvider?: { __typename?: 'OidcProvider', id: string, clientId: string, authMethod: OidcAuthMethod, clientSecret: string, redirectUris?: Array | null, bindings?: Array<{ __typename?: 'OidcProviderBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null, configuration?: { __typename?: 'OuathConfiguration', issuer?: string | null, authorizationEndpoint?: string | null, tokenEndpoint?: string | null, jwksUri?: string | null, userinfoEndpoint?: string | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null } | null } | null } | null> | null, dependency?: { __typename?: 'ClusterDependency', dependency?: { __typename?: 'Cluster', id: string, name: string, provider: Provider } | null } | null }; +export type ClusterFragment = { __typename?: 'Cluster', id: string, name: string, provider: Provider, source?: Source | null, pingedAt?: Date | null, gitUrl?: string | null, consoleUrl?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, queue?: { __typename?: 'UpgradeQueue', id: string, acked?: string | null, upgrades?: { __typename?: 'UpgradeConnection', edges?: Array<{ __typename?: 'UpgradeEdge', node?: { __typename?: 'Upgrade', id: string } | null } | null> | null } | null } | null, upgradeInfo?: Array<{ __typename?: 'UpgradeInfo', count?: number | null, installation?: { __typename?: 'Installation', id: string, context?: Map | null, license?: string | null, licenseKey?: string | null, acmeKeyId?: string | null, acmeSecret?: string | null, autoUpgrade?: boolean | null, trackTag: string, pingedAt?: Date | null, repository?: { __typename?: 'Repository', id: string, name: string, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null } | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, oidcProvider?: { __typename?: 'OidcProvider', id: string, clientId: string, authMethod: OidcAuthMethod, clientSecret: string, redirectUris?: Array | null, bindings?: Array<{ __typename?: 'OidcProviderBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null, configuration?: { __typename?: 'OuathConfiguration', issuer?: string | null, authorizationEndpoint?: string | null, tokenEndpoint?: string | null, jwksUri?: string | null, userinfoEndpoint?: string | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null } | null } | null } | null> | null, dependency?: { __typename?: 'ClusterDependency', dependency?: { __typename?: 'Cluster', id: string, name: string, provider: Provider } | null } | null }; export type ClustersQueryVariables = Exact<{ first?: InputMaybe; }>; -export type ClustersQuery = { __typename?: 'RootQueryType', clusters?: { __typename?: 'ClusterConnection', pageInfo: { __typename?: 'PageInfo', endCursor?: string | null, hasNextPage: boolean }, edges?: Array<{ __typename?: 'ClusterEdge', node?: { __typename?: 'Cluster', id: string, name: string, provider: Provider, source?: Source | null, pingedAt?: Date | null, gitUrl?: string | null, consoleUrl?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, queue?: { __typename?: 'UpgradeQueue', id: string, acked?: string | null, upgrades?: { __typename?: 'UpgradeConnection', edges?: Array<{ __typename?: 'UpgradeEdge', node?: { __typename?: 'Upgrade', id: string } | null } | null> | null } | null } | null, upgradeInfo?: Array<{ __typename?: 'UpgradeInfo', count?: number | null, installation?: { __typename?: 'Installation', id: string, context?: Map | null, license?: string | null, licenseKey?: string | null, acmeKeyId?: string | null, acmeSecret?: string | null, autoUpgrade?: boolean | null, trackTag: string, pingedAt?: Date | null, repository?: { __typename?: 'Repository', id: string, name: string, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null } | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, oidcProvider?: { __typename?: 'OidcProvider', id: string, clientId: string, authMethod: OidcAuthMethod, clientSecret: string, redirectUris?: Array | null, bindings?: Array<{ __typename?: 'OidcProviderBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null, configuration?: { __typename?: 'OuathConfiguration', issuer?: string | null, authorizationEndpoint?: string | null, tokenEndpoint?: string | null, jwksUri?: string | null, userinfoEndpoint?: string | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null } | null } | null } | null> | null, dependency?: { __typename?: 'ClusterDependency', dependency?: { __typename?: 'Cluster', id: string, name: string, provider: Provider } | null } | null } | null } | null> | null } | null }; +export type ClustersQuery = { __typename?: 'RootQueryType', clusters?: { __typename?: 'ClusterConnection', pageInfo: { __typename?: 'PageInfo', endCursor?: string | null, hasNextPage: boolean }, edges?: Array<{ __typename?: 'ClusterEdge', node?: { __typename?: 'Cluster', id: string, name: string, provider: Provider, source?: Source | null, pingedAt?: Date | null, gitUrl?: string | null, consoleUrl?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, queue?: { __typename?: 'UpgradeQueue', id: string, acked?: string | null, upgrades?: { __typename?: 'UpgradeConnection', edges?: Array<{ __typename?: 'UpgradeEdge', node?: { __typename?: 'Upgrade', id: string } | null } | null> | null } | null } | null, upgradeInfo?: Array<{ __typename?: 'UpgradeInfo', count?: number | null, installation?: { __typename?: 'Installation', id: string, context?: Map | null, license?: string | null, licenseKey?: string | null, acmeKeyId?: string | null, acmeSecret?: string | null, autoUpgrade?: boolean | null, trackTag: string, pingedAt?: Date | null, repository?: { __typename?: 'Repository', id: string, name: string, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null } | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, oidcProvider?: { __typename?: 'OidcProvider', id: string, clientId: string, authMethod: OidcAuthMethod, clientSecret: string, redirectUris?: Array | null, bindings?: Array<{ __typename?: 'OidcProviderBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null, configuration?: { __typename?: 'OuathConfiguration', issuer?: string | null, authorizationEndpoint?: string | null, tokenEndpoint?: string | null, jwksUri?: string | null, userinfoEndpoint?: string | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null } | null } | null } | null> | null, dependency?: { __typename?: 'ClusterDependency', dependency?: { __typename?: 'Cluster', id: string, name: string, provider: Provider } | null } | null } | null } | null> | null } | null }; -export type DnsRecordFragment = { __typename?: 'DnsRecord', id: string, name: string, type: DnsRecordType, records?: Array | null, cluster: string, provider: Provider, insertedAt?: Date | null, creator?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null }; +export type DnsRecordFragment = { __typename?: 'DnsRecord', id: string, name: string, type: DnsRecordType, records?: Array | null, cluster: string, provider: Provider, insertedAt?: Date | null, creator?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null }; export type GetDnsRecordsQueryVariables = Exact<{ cluster: Scalars['String']['input']; @@ -5335,7 +5335,7 @@ export type GetDnsRecordsQueryVariables = Exact<{ }>; -export type GetDnsRecordsQuery = { __typename?: 'RootQueryType', dnsRecords?: { __typename?: 'DnsRecordConnection', edges?: Array<{ __typename?: 'DnsRecordEdge', node?: { __typename?: 'DnsRecord', id: string, name: string, type: DnsRecordType, records?: Array | null, cluster: string, provider: Provider, insertedAt?: Date | null, creator?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null } | null } | null> | null } | null }; +export type GetDnsRecordsQuery = { __typename?: 'RootQueryType', dnsRecords?: { __typename?: 'DnsRecordConnection', edges?: Array<{ __typename?: 'DnsRecordEdge', node?: { __typename?: 'DnsRecord', id: string, name: string, type: DnsRecordType, records?: Array | null, cluster: string, provider: Provider, insertedAt?: Date | null, creator?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null } | null } | null> | null } | null }; export type CreateDnsRecordMutationVariables = Exact<{ cluster: Scalars['String']['input']; @@ -5344,7 +5344,7 @@ export type CreateDnsRecordMutationVariables = Exact<{ }>; -export type CreateDnsRecordMutation = { __typename?: 'RootMutationType', createDnsRecord?: { __typename?: 'DnsRecord', id: string, name: string, type: DnsRecordType, records?: Array | null, cluster: string, provider: Provider, insertedAt?: Date | null, creator?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null } | null }; +export type CreateDnsRecordMutation = { __typename?: 'RootMutationType', createDnsRecord?: { __typename?: 'DnsRecord', id: string, name: string, type: DnsRecordType, records?: Array | null, cluster: string, provider: Provider, insertedAt?: Date | null, creator?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null } | null }; export type DeleteDnsRecordMutationVariables = Exact<{ name: Scalars['String']['input']; @@ -5352,7 +5352,7 @@ export type DeleteDnsRecordMutationVariables = Exact<{ }>; -export type DeleteDnsRecordMutation = { __typename?: 'RootMutationType', deleteDnsRecord?: { __typename?: 'DnsRecord', id: string, name: string, type: DnsRecordType, records?: Array | null, cluster: string, provider: Provider, insertedAt?: Date | null, creator?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null } | null }; +export type DeleteDnsRecordMutation = { __typename?: 'RootMutationType', deleteDnsRecord?: { __typename?: 'DnsRecord', id: string, name: string, type: DnsRecordType, records?: Array | null, cluster: string, provider: Provider, insertedAt?: Date | null, creator?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null } | null }; export type DockerRepoFragment = { __typename?: 'DockerRepository', id: string, name: string, public?: boolean | null, insertedAt?: Date | null, updatedAt?: Date | null, repository?: { __typename?: 'Repository', id: string, name: string } | null }; @@ -5367,7 +5367,7 @@ export type CreateDomainMutationVariables = Exact<{ }>; -export type CreateDomainMutation = { __typename?: 'RootMutationType', provisionDomain?: { __typename?: 'DnsDomain', id: string, name: string, insertedAt?: Date | null, creator?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, accessPolicy?: { __typename?: 'DnsAccessPolicy', id: string, bindings?: Array<{ __typename?: 'PolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null }; +export type CreateDomainMutation = { __typename?: 'RootMutationType', provisionDomain?: { __typename?: 'DnsDomain', id: string, name: string, insertedAt?: Date | null, creator?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, accessPolicy?: { __typename?: 'DnsAccessPolicy', id: string, bindings?: Array<{ __typename?: 'PolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null }; export type GroupMembersQueryVariables = Exact<{ cursor?: InputMaybe; @@ -5375,7 +5375,7 @@ export type GroupMembersQueryVariables = Exact<{ }>; -export type GroupMembersQuery = { __typename?: 'RootQueryType', groupMembers?: { __typename?: 'GroupMemberConnection', pageInfo: { __typename?: 'PageInfo', endCursor?: string | null, hasNextPage: boolean }, edges?: Array<{ __typename?: 'GroupMemberEdge', node?: { __typename?: 'GroupMember', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null } | null } | null> | null } | null }; +export type GroupMembersQuery = { __typename?: 'RootQueryType', groupMembers?: { __typename?: 'GroupMemberConnection', pageInfo: { __typename?: 'PageInfo', endCursor?: string | null, hasNextPage: boolean }, edges?: Array<{ __typename?: 'GroupMemberEdge', node?: { __typename?: 'GroupMember', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null } | null } | null> | null } | null }; export type CreateGroupMemberMutationVariables = Exact<{ groupId: Scalars['ID']['input']; @@ -5383,7 +5383,7 @@ export type CreateGroupMemberMutationVariables = Exact<{ }>; -export type CreateGroupMemberMutation = { __typename?: 'RootMutationType', createGroupMember?: { __typename?: 'GroupMember', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null } | null }; +export type CreateGroupMemberMutation = { __typename?: 'RootMutationType', createGroupMember?: { __typename?: 'GroupMember', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null } | null }; export type DeleteGroupMemberMutationVariables = Exact<{ groupId: Scalars['ID']['input']; @@ -5391,7 +5391,7 @@ export type DeleteGroupMemberMutationVariables = Exact<{ }>; -export type DeleteGroupMemberMutation = { __typename?: 'RootMutationType', deleteGroupMember?: { __typename?: 'GroupMember', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null } | null }; +export type DeleteGroupMemberMutation = { __typename?: 'RootMutationType', deleteGroupMember?: { __typename?: 'GroupMember', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null } | null }; export type CreateGroupMutationVariables = Exact<{ attributes: GroupAttributes; @@ -5425,25 +5425,25 @@ export type GroupsQuery = { __typename?: 'RootQueryType', groups?: { __typename? export type PostmortemFragment = { __typename?: 'Postmortem', id: string, content: string, actionItems?: Array<{ __typename?: 'ActionItem', type: ActionItemType, link: string } | null> | null }; -export type FollowerFragment = { __typename?: 'Follower', id: string, incident?: { __typename?: 'Incident', id: string } | null, user: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null }, preferences?: { __typename?: 'NotificationPreferences', message?: boolean | null, incidentUpdate?: boolean | null, mention?: boolean | null } | null }; +export type FollowerFragment = { __typename?: 'Follower', id: string, incident?: { __typename?: 'Incident', id: string } | null, user: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null }, preferences?: { __typename?: 'NotificationPreferences', message?: boolean | null, incidentUpdate?: boolean | null, mention?: boolean | null } | null }; export type SlimSubscriptionFragment = { __typename?: 'SlimSubscription', id: string, lineItems?: { __typename?: 'SubscriptionLineItems', items?: Array<{ __typename?: 'Limit', dimension: string, quantity: number } | null> | null } | null, plan?: { __typename?: 'Plan', id: string, name: string, cost: number, period?: string | null, serviceLevels?: Array<{ __typename?: 'ServiceLevel', minSeverity?: number | null, maxSeverity?: number | null, responseTime?: number | null } | null> | null, lineItems?: { __typename?: 'PlanLineItems', included?: Array<{ __typename?: 'Limit', dimension: string, quantity: number } | null> | null, items?: Array<{ __typename?: 'LineItem', name: string, dimension: string, cost: number, period?: string | null, type?: PlanType | null } | null> | null } | null, metadata?: { __typename?: 'PlanMetadata', features?: Array<{ __typename?: 'PlanFeature', name: string, description: string } | null> | null } | null } | null }; export type ClusterInformationFragment = { __typename?: 'ClusterInformation', version?: string | null, gitCommit?: string | null, platform?: string | null }; -export type IncidentFragment = { __typename?: 'Incident', id: string, title: string, description?: string | null, severity: number, status: IncidentStatus, notificationCount?: number | null, nextResponseAt?: Date | null, insertedAt?: Date | null, creator: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null }, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, repository: { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null }, subscription?: { __typename?: 'SlimSubscription', id: string, lineItems?: { __typename?: 'SubscriptionLineItems', items?: Array<{ __typename?: 'Limit', dimension: string, quantity: number } | null> | null } | null, plan?: { __typename?: 'Plan', id: string, name: string, cost: number, period?: string | null, serviceLevels?: Array<{ __typename?: 'ServiceLevel', minSeverity?: number | null, maxSeverity?: number | null, responseTime?: number | null } | null> | null, lineItems?: { __typename?: 'PlanLineItems', included?: Array<{ __typename?: 'Limit', dimension: string, quantity: number } | null> | null, items?: Array<{ __typename?: 'LineItem', name: string, dimension: string, cost: number, period?: string | null, type?: PlanType | null } | null> | null } | null, metadata?: { __typename?: 'PlanMetadata', features?: Array<{ __typename?: 'PlanFeature', name: string, description: string } | null> | null } | null } | null } | null, clusterInformation?: { __typename?: 'ClusterInformation', version?: string | null, gitCommit?: string | null, platform?: string | null } | null, tags?: Array<{ __typename?: 'Tag', tag: string } | null> | null }; +export type IncidentFragment = { __typename?: 'Incident', id: string, title: string, description?: string | null, severity: number, status: IncidentStatus, notificationCount?: number | null, nextResponseAt?: Date | null, insertedAt?: Date | null, creator: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null }, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, repository: { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null }, subscription?: { __typename?: 'SlimSubscription', id: string, lineItems?: { __typename?: 'SubscriptionLineItems', items?: Array<{ __typename?: 'Limit', dimension: string, quantity: number } | null> | null } | null, plan?: { __typename?: 'Plan', id: string, name: string, cost: number, period?: string | null, serviceLevels?: Array<{ __typename?: 'ServiceLevel', minSeverity?: number | null, maxSeverity?: number | null, responseTime?: number | null } | null> | null, lineItems?: { __typename?: 'PlanLineItems', included?: Array<{ __typename?: 'Limit', dimension: string, quantity: number } | null> | null, items?: Array<{ __typename?: 'LineItem', name: string, dimension: string, cost: number, period?: string | null, type?: PlanType | null } | null> | null } | null, metadata?: { __typename?: 'PlanMetadata', features?: Array<{ __typename?: 'PlanFeature', name: string, description: string } | null> | null } | null } | null } | null, clusterInformation?: { __typename?: 'ClusterInformation', version?: string | null, gitCommit?: string | null, platform?: string | null } | null, tags?: Array<{ __typename?: 'Tag', tag: string } | null> | null }; -export type IncidentHistoryFragment = { __typename?: 'IncidentHistory', id: string, action: IncidentAction, insertedAt?: Date | null, changes?: Array<{ __typename?: 'IncidentChange', key: string, prev?: string | null, next?: string | null } | null> | null, actor: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } }; +export type IncidentHistoryFragment = { __typename?: 'IncidentHistory', id: string, action: IncidentAction, insertedAt?: Date | null, changes?: Array<{ __typename?: 'IncidentChange', key: string, prev?: string | null, next?: string | null } | null> | null, actor: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } }; export type FileFragment = { __typename?: 'File', id: string, blob: string, mediaType?: MediaType | null, contentType?: string | null, filesize?: number | null, filename?: string | null }; -export type IncidentMessageFragment = { __typename?: 'IncidentMessage', id: string, text: string, insertedAt?: Date | null, creator: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null }, reactions?: Array<{ __typename?: 'Reaction', name: string, creator: { __typename?: 'User', id: string, email: string } } | null> | null, file?: { __typename?: 'File', id: string, blob: string, mediaType?: MediaType | null, contentType?: string | null, filesize?: number | null, filename?: string | null } | null, entities?: Array<{ __typename?: 'MessageEntity', type: MessageEntityType, text?: string | null, startIndex?: number | null, endIndex?: number | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null } | null> | null }; +export type IncidentMessageFragment = { __typename?: 'IncidentMessage', id: string, text: string, insertedAt?: Date | null, creator: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null }, reactions?: Array<{ __typename?: 'Reaction', name: string, creator: { __typename?: 'User', id: string, email: string } } | null> | null, file?: { __typename?: 'File', id: string, blob: string, mediaType?: MediaType | null, contentType?: string | null, filesize?: number | null, filename?: string | null } | null, entities?: Array<{ __typename?: 'MessageEntity', type: MessageEntityType, text?: string | null, startIndex?: number | null, endIndex?: number | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null } | null> | null }; -export type NotificationFragment = { __typename?: 'Notification', id: string, type: NotificationType, msg?: string | null, insertedAt?: Date | null, actor: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null }, incident?: { __typename?: 'Incident', id: string, title: string, repository: { __typename?: 'Repository', id: string, name: string, icon?: string | null, darkIcon?: string | null } } | null, message?: { __typename?: 'IncidentMessage', text: string } | null, repository?: { __typename?: 'Repository', id: string, name: string, icon?: string | null, darkIcon?: string | null } | null }; +export type NotificationFragment = { __typename?: 'Notification', id: string, type: NotificationType, msg?: string | null, insertedAt?: Date | null, actor: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null }, incident?: { __typename?: 'Incident', id: string, title: string, repository: { __typename?: 'Repository', id: string, name: string, icon?: string | null, darkIcon?: string | null } } | null, message?: { __typename?: 'IncidentMessage', text: string } | null, repository?: { __typename?: 'Repository', id: string, name: string, icon?: string | null, darkIcon?: string | null } | null }; export type InstallationRepoFragment = { __typename?: 'Repository', id: string, name: string, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null }; -export type InstallationFragment = { __typename?: 'Installation', id: string, context?: Map | null, license?: string | null, licenseKey?: string | null, acmeKeyId?: string | null, acmeSecret?: string | null, autoUpgrade?: boolean | null, trackTag: string, pingedAt?: Date | null, repository?: { __typename?: 'Repository', id: string, name: string, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null } | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, oidcProvider?: { __typename?: 'OidcProvider', id: string, clientId: string, authMethod: OidcAuthMethod, clientSecret: string, redirectUris?: Array | null, bindings?: Array<{ __typename?: 'OidcProviderBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null, configuration?: { __typename?: 'OuathConfiguration', issuer?: string | null, authorizationEndpoint?: string | null, tokenEndpoint?: string | null, jwksUri?: string | null, userinfoEndpoint?: string | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null } | null }; +export type InstallationFragment = { __typename?: 'Installation', id: string, context?: Map | null, license?: string | null, licenseKey?: string | null, acmeKeyId?: string | null, acmeSecret?: string | null, autoUpgrade?: boolean | null, trackTag: string, pingedAt?: Date | null, repository?: { __typename?: 'Repository', id: string, name: string, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null } | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, oidcProvider?: { __typename?: 'OidcProvider', id: string, clientId: string, authMethod: OidcAuthMethod, clientSecret: string, redirectUris?: Array | null, bindings?: Array<{ __typename?: 'OidcProviderBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null, configuration?: { __typename?: 'OuathConfiguration', issuer?: string | null, authorizationEndpoint?: string | null, tokenEndpoint?: string | null, jwksUri?: string | null, userinfoEndpoint?: string | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null } | null }; export type IntegrationWebhookFragment = { __typename?: 'IntegrationWebhook', id: string, name: string, url: string, secret: string, actions?: Array | null }; @@ -5473,14 +5473,14 @@ export type InviteQueryVariables = Exact<{ }>; -export type InviteQuery = { __typename?: 'RootQueryType', invite?: { __typename?: 'Invite', id: string, email?: string | null, existing: boolean, account?: { __typename?: 'Account', id: string, name?: string | null, billingCustomerId?: string | null, backgroundColor?: string | null, userCount?: string | null, trialed?: boolean | null } | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, account: { __typename?: 'Account', id: string, name?: string | null, billingCustomerId?: string | null, backgroundColor?: string | null, userCount?: string | null, trialed?: boolean | null }, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null } | null }; +export type InviteQuery = { __typename?: 'RootQueryType', invite?: { __typename?: 'Invite', id: string, email?: string | null, existing: boolean, account?: { __typename?: 'Account', id: string, name?: string | null, billingCustomerId?: string | null, backgroundColor?: string | null, userCount?: string | null, trialed?: boolean | null } | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, account: { __typename?: 'Account', id: string, name?: string | null, billingCustomerId?: string | null, backgroundColor?: string | null, userCount?: string | null, trialed?: boolean | null }, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null } | null }; export type CreateInviteMutationVariables = Exact<{ attributes: InviteAttributes; }>; -export type CreateInviteMutation = { __typename?: 'RootMutationType', createInvite?: { __typename?: 'Invite', id: string, secureId?: string | null, email?: string | null, insertedAt?: Date | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null } | null }; +export type CreateInviteMutation = { __typename?: 'RootMutationType', createInvite?: { __typename?: 'Invite', id: string, secureId?: string | null, email?: string | null, insertedAt?: Date | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null } | null }; export type KeyBackupUserFragment = { __typename?: 'User', email: string }; @@ -5516,7 +5516,7 @@ export type MetricFragment = { __typename?: 'Metric', name: string, tags?: Array export type PageInfoFragment = { __typename?: 'PageInfo', endCursor?: string | null, hasNextPage: boolean }; -export type OidcProviderFragment = { __typename?: 'OidcProvider', id: string, clientId: string, authMethod: OidcAuthMethod, clientSecret: string, redirectUris?: Array | null, bindings?: Array<{ __typename?: 'OidcProviderBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null, configuration?: { __typename?: 'OuathConfiguration', issuer?: string | null, authorizationEndpoint?: string | null, tokenEndpoint?: string | null, jwksUri?: string | null, userinfoEndpoint?: string | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null }; +export type OidcProviderFragment = { __typename?: 'OidcProvider', id: string, clientId: string, authMethod: OidcAuthMethod, clientSecret: string, redirectUris?: Array | null, bindings?: Array<{ __typename?: 'OidcProviderBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null, configuration?: { __typename?: 'OuathConfiguration', issuer?: string | null, authorizationEndpoint?: string | null, tokenEndpoint?: string | null, jwksUri?: string | null, userinfoEndpoint?: string | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null }; export type OAuthInfoFragment = { __typename?: 'OauthInfo', provider: OauthProvider, authorizeUrl: string }; @@ -5652,17 +5652,17 @@ export type UpdateOidcProviderMutationVariables = Exact<{ }>; -export type UpdateOidcProviderMutation = { __typename?: 'RootMutationType', updateOidcProvider?: { __typename?: 'OidcProvider', id: string, clientId: string, authMethod: OidcAuthMethod, clientSecret: string, redirectUris?: Array | null, bindings?: Array<{ __typename?: 'OidcProviderBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null, configuration?: { __typename?: 'OuathConfiguration', issuer?: string | null, authorizationEndpoint?: string | null, tokenEndpoint?: string | null, jwksUri?: string | null, userinfoEndpoint?: string | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null } | null }; +export type UpdateOidcProviderMutation = { __typename?: 'RootMutationType', updateOidcProvider?: { __typename?: 'OidcProvider', id: string, clientId: string, authMethod: OidcAuthMethod, clientSecret: string, redirectUris?: Array | null, bindings?: Array<{ __typename?: 'OidcProviderBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null, configuration?: { __typename?: 'OuathConfiguration', issuer?: string | null, authorizationEndpoint?: string | null, tokenEndpoint?: string | null, jwksUri?: string | null, userinfoEndpoint?: string | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null } | null }; -export type RecipeFragment = { __typename?: 'Recipe', id: string, name: string, description?: string | null, restricted?: boolean | null, provider?: Provider | null, tests?: Array<{ __typename?: 'RecipeTest', type: TestType, name: string, message?: string | null, args?: Array<{ __typename?: 'TestArgument', name: string, repo: string, key: string } | null> | null } | null> | null, repository?: { __typename?: 'Repository', id: string, name: string } | null, oidcSettings?: { __typename?: 'OidcSettings', uriFormat?: string | null, uriFormats?: Array | null, authMethod: OidcAuthMethod, domainKey?: string | null, subdomain?: boolean | null } | null, recipeSections?: Array<{ __typename?: 'RecipeSection', index?: number | null, repository?: { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, installation?: { __typename?: 'Installation', id: string, context?: Map | null, license?: string | null, licenseKey?: string | null, acmeKeyId?: string | null, acmeSecret?: string | null, autoUpgrade?: boolean | null, trackTag: string, pingedAt?: Date | null, repository?: { __typename?: 'Repository', id: string, name: string, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null } | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, oidcProvider?: { __typename?: 'OidcProvider', id: string, clientId: string, authMethod: OidcAuthMethod, clientSecret: string, redirectUris?: Array | null, bindings?: Array<{ __typename?: 'OidcProviderBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null, configuration?: { __typename?: 'OuathConfiguration', issuer?: string | null, authorizationEndpoint?: string | null, tokenEndpoint?: string | null, jwksUri?: string | null, userinfoEndpoint?: string | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null } | null } | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null } | null, recipeItems?: Array<{ __typename?: 'RecipeItem', id?: string | null, chart?: { __typename?: 'Chart', id?: string | null, name: string, description?: string | null, latestVersion?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, terraform?: { __typename?: 'Terraform', id?: string | null, name?: string | null, readme?: string | null, package?: string | null, description?: string | null, latestVersion?: string | null, valuesTemplate?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, configuration?: Array<{ __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null } | null> | null } | null> | null, configuration?: Array<{ __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null } | null> | null } | null> | null }; +export type RecipeFragment = { __typename?: 'Recipe', id: string, name: string, description?: string | null, restricted?: boolean | null, provider?: Provider | null, tests?: Array<{ __typename?: 'RecipeTest', type: TestType, name: string, message?: string | null, args?: Array<{ __typename?: 'TestArgument', name: string, repo: string, key: string } | null> | null } | null> | null, repository?: { __typename?: 'Repository', id: string, name: string } | null, oidcSettings?: { __typename?: 'OidcSettings', uriFormat?: string | null, uriFormats?: Array | null, authMethod: OidcAuthMethod, domainKey?: string | null, subdomain?: boolean | null } | null, recipeSections?: Array<{ __typename?: 'RecipeSection', index?: number | null, repository?: { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, installation?: { __typename?: 'Installation', id: string, context?: Map | null, license?: string | null, licenseKey?: string | null, acmeKeyId?: string | null, acmeSecret?: string | null, autoUpgrade?: boolean | null, trackTag: string, pingedAt?: Date | null, repository?: { __typename?: 'Repository', id: string, name: string, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null } | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, oidcProvider?: { __typename?: 'OidcProvider', id: string, clientId: string, authMethod: OidcAuthMethod, clientSecret: string, redirectUris?: Array | null, bindings?: Array<{ __typename?: 'OidcProviderBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null, configuration?: { __typename?: 'OuathConfiguration', issuer?: string | null, authorizationEndpoint?: string | null, tokenEndpoint?: string | null, jwksUri?: string | null, userinfoEndpoint?: string | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null } | null } | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null } | null, recipeItems?: Array<{ __typename?: 'RecipeItem', id?: string | null, chart?: { __typename?: 'Chart', id?: string | null, name: string, description?: string | null, latestVersion?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, terraform?: { __typename?: 'Terraform', id?: string | null, name?: string | null, readme?: string | null, package?: string | null, description?: string | null, latestVersion?: string | null, valuesTemplate?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, configuration?: Array<{ __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null } | null> | null } | null> | null, configuration?: Array<{ __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null } | null> | null } | null> | null }; export type RecipeItemFragment = { __typename?: 'RecipeItem', id?: string | null, chart?: { __typename?: 'Chart', id?: string | null, name: string, description?: string | null, latestVersion?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, terraform?: { __typename?: 'Terraform', id?: string | null, name?: string | null, readme?: string | null, package?: string | null, description?: string | null, latestVersion?: string | null, valuesTemplate?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, configuration?: Array<{ __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null } | null> | null }; -export type RecipeSectionFragment = { __typename?: 'RecipeSection', index?: number | null, repository?: { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, installation?: { __typename?: 'Installation', id: string, context?: Map | null, license?: string | null, licenseKey?: string | null, acmeKeyId?: string | null, acmeSecret?: string | null, autoUpgrade?: boolean | null, trackTag: string, pingedAt?: Date | null, repository?: { __typename?: 'Repository', id: string, name: string, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null } | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, oidcProvider?: { __typename?: 'OidcProvider', id: string, clientId: string, authMethod: OidcAuthMethod, clientSecret: string, redirectUris?: Array | null, bindings?: Array<{ __typename?: 'OidcProviderBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null, configuration?: { __typename?: 'OuathConfiguration', issuer?: string | null, authorizationEndpoint?: string | null, tokenEndpoint?: string | null, jwksUri?: string | null, userinfoEndpoint?: string | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null } | null } | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null } | null, recipeItems?: Array<{ __typename?: 'RecipeItem', id?: string | null, chart?: { __typename?: 'Chart', id?: string | null, name: string, description?: string | null, latestVersion?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, terraform?: { __typename?: 'Terraform', id?: string | null, name?: string | null, readme?: string | null, package?: string | null, description?: string | null, latestVersion?: string | null, valuesTemplate?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, configuration?: Array<{ __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null } | null> | null } | null> | null, configuration?: Array<{ __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null } | null> | null }; +export type RecipeSectionFragment = { __typename?: 'RecipeSection', index?: number | null, repository?: { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, installation?: { __typename?: 'Installation', id: string, context?: Map | null, license?: string | null, licenseKey?: string | null, acmeKeyId?: string | null, acmeSecret?: string | null, autoUpgrade?: boolean | null, trackTag: string, pingedAt?: Date | null, repository?: { __typename?: 'Repository', id: string, name: string, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null } | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, oidcProvider?: { __typename?: 'OidcProvider', id: string, clientId: string, authMethod: OidcAuthMethod, clientSecret: string, redirectUris?: Array | null, bindings?: Array<{ __typename?: 'OidcProviderBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null, configuration?: { __typename?: 'OuathConfiguration', issuer?: string | null, authorizationEndpoint?: string | null, tokenEndpoint?: string | null, jwksUri?: string | null, userinfoEndpoint?: string | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null } | null } | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null } | null, recipeItems?: Array<{ __typename?: 'RecipeItem', id?: string | null, chart?: { __typename?: 'Chart', id?: string | null, name: string, description?: string | null, latestVersion?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, terraform?: { __typename?: 'Terraform', id?: string | null, name?: string | null, readme?: string | null, package?: string | null, description?: string | null, latestVersion?: string | null, valuesTemplate?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, configuration?: Array<{ __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null } | null> | null } | null> | null, configuration?: Array<{ __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null } | null> | null }; export type RecipeConfigurationFragment = { __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null }; -export type StackFragment = { __typename?: 'Stack', id: string, name: string, displayName?: string | null, description?: string | null, featured?: boolean | null, creator?: { __typename?: 'User', id: string, name: string } | null, collections?: Array<{ __typename?: 'StackCollection', id: string, provider: Provider, bundles?: Array<{ __typename?: 'StackRecipe', recipe: { __typename?: 'Recipe', repository?: { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, tags?: Array<{ __typename?: 'Tag', tag: string } | null> | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null } | null } } | null> | null } | null> | null }; +export type StackFragment = { __typename?: 'Stack', id: string, name: string, displayName?: string | null, description?: string | null, featured?: boolean | null, creator?: { __typename?: 'User', id: string, name: string } | null, collections?: Array<{ __typename?: 'StackCollection', id: string, provider: Provider, bundles?: Array<{ __typename?: 'StackRecipe', recipe: { __typename?: 'Recipe', repository?: { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, tags?: Array<{ __typename?: 'Tag', tag: string } | null> | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null } | null } } | null> | null } | null> | null }; export type GetRecipeQueryVariables = Exact<{ repo?: InputMaybe; @@ -5670,7 +5670,7 @@ export type GetRecipeQueryVariables = Exact<{ }>; -export type GetRecipeQuery = { __typename?: 'RootQueryType', recipe?: { __typename?: 'Recipe', id: string, name: string, description?: string | null, restricted?: boolean | null, provider?: Provider | null, recipeDependencies?: Array<{ __typename?: 'Recipe', id: string, name: string, description?: string | null, restricted?: boolean | null, provider?: Provider | null, tests?: Array<{ __typename?: 'RecipeTest', type: TestType, name: string, message?: string | null, args?: Array<{ __typename?: 'TestArgument', name: string, repo: string, key: string } | null> | null } | null> | null, repository?: { __typename?: 'Repository', id: string, name: string } | null, oidcSettings?: { __typename?: 'OidcSettings', uriFormat?: string | null, uriFormats?: Array | null, authMethod: OidcAuthMethod, domainKey?: string | null, subdomain?: boolean | null } | null, recipeSections?: Array<{ __typename?: 'RecipeSection', index?: number | null, repository?: { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, installation?: { __typename?: 'Installation', id: string, context?: Map | null, license?: string | null, licenseKey?: string | null, acmeKeyId?: string | null, acmeSecret?: string | null, autoUpgrade?: boolean | null, trackTag: string, pingedAt?: Date | null, repository?: { __typename?: 'Repository', id: string, name: string, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null } | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, oidcProvider?: { __typename?: 'OidcProvider', id: string, clientId: string, authMethod: OidcAuthMethod, clientSecret: string, redirectUris?: Array | null, bindings?: Array<{ __typename?: 'OidcProviderBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null, configuration?: { __typename?: 'OuathConfiguration', issuer?: string | null, authorizationEndpoint?: string | null, tokenEndpoint?: string | null, jwksUri?: string | null, userinfoEndpoint?: string | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null } | null } | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null } | null, recipeItems?: Array<{ __typename?: 'RecipeItem', id?: string | null, chart?: { __typename?: 'Chart', id?: string | null, name: string, description?: string | null, latestVersion?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, terraform?: { __typename?: 'Terraform', id?: string | null, name?: string | null, readme?: string | null, package?: string | null, description?: string | null, latestVersion?: string | null, valuesTemplate?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, configuration?: Array<{ __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null } | null> | null } | null> | null, configuration?: Array<{ __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null } | null> | null } | null> | null } | null> | null, tests?: Array<{ __typename?: 'RecipeTest', type: TestType, name: string, message?: string | null, args?: Array<{ __typename?: 'TestArgument', name: string, repo: string, key: string } | null> | null } | null> | null, repository?: { __typename?: 'Repository', id: string, name: string } | null, oidcSettings?: { __typename?: 'OidcSettings', uriFormat?: string | null, uriFormats?: Array | null, authMethod: OidcAuthMethod, domainKey?: string | null, subdomain?: boolean | null } | null, recipeSections?: Array<{ __typename?: 'RecipeSection', index?: number | null, repository?: { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, installation?: { __typename?: 'Installation', id: string, context?: Map | null, license?: string | null, licenseKey?: string | null, acmeKeyId?: string | null, acmeSecret?: string | null, autoUpgrade?: boolean | null, trackTag: string, pingedAt?: Date | null, repository?: { __typename?: 'Repository', id: string, name: string, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null } | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, oidcProvider?: { __typename?: 'OidcProvider', id: string, clientId: string, authMethod: OidcAuthMethod, clientSecret: string, redirectUris?: Array | null, bindings?: Array<{ __typename?: 'OidcProviderBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null, configuration?: { __typename?: 'OuathConfiguration', issuer?: string | null, authorizationEndpoint?: string | null, tokenEndpoint?: string | null, jwksUri?: string | null, userinfoEndpoint?: string | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null } | null } | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null } | null, recipeItems?: Array<{ __typename?: 'RecipeItem', id?: string | null, chart?: { __typename?: 'Chart', id?: string | null, name: string, description?: string | null, latestVersion?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, terraform?: { __typename?: 'Terraform', id?: string | null, name?: string | null, readme?: string | null, package?: string | null, description?: string | null, latestVersion?: string | null, valuesTemplate?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, configuration?: Array<{ __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null } | null> | null } | null> | null, configuration?: Array<{ __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null } | null> | null } | null> | null } | null }; +export type GetRecipeQuery = { __typename?: 'RootQueryType', recipe?: { __typename?: 'Recipe', id: string, name: string, description?: string | null, restricted?: boolean | null, provider?: Provider | null, recipeDependencies?: Array<{ __typename?: 'Recipe', id: string, name: string, description?: string | null, restricted?: boolean | null, provider?: Provider | null, tests?: Array<{ __typename?: 'RecipeTest', type: TestType, name: string, message?: string | null, args?: Array<{ __typename?: 'TestArgument', name: string, repo: string, key: string } | null> | null } | null> | null, repository?: { __typename?: 'Repository', id: string, name: string } | null, oidcSettings?: { __typename?: 'OidcSettings', uriFormat?: string | null, uriFormats?: Array | null, authMethod: OidcAuthMethod, domainKey?: string | null, subdomain?: boolean | null } | null, recipeSections?: Array<{ __typename?: 'RecipeSection', index?: number | null, repository?: { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, installation?: { __typename?: 'Installation', id: string, context?: Map | null, license?: string | null, licenseKey?: string | null, acmeKeyId?: string | null, acmeSecret?: string | null, autoUpgrade?: boolean | null, trackTag: string, pingedAt?: Date | null, repository?: { __typename?: 'Repository', id: string, name: string, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null } | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, oidcProvider?: { __typename?: 'OidcProvider', id: string, clientId: string, authMethod: OidcAuthMethod, clientSecret: string, redirectUris?: Array | null, bindings?: Array<{ __typename?: 'OidcProviderBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null, configuration?: { __typename?: 'OuathConfiguration', issuer?: string | null, authorizationEndpoint?: string | null, tokenEndpoint?: string | null, jwksUri?: string | null, userinfoEndpoint?: string | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null } | null } | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null } | null, recipeItems?: Array<{ __typename?: 'RecipeItem', id?: string | null, chart?: { __typename?: 'Chart', id?: string | null, name: string, description?: string | null, latestVersion?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, terraform?: { __typename?: 'Terraform', id?: string | null, name?: string | null, readme?: string | null, package?: string | null, description?: string | null, latestVersion?: string | null, valuesTemplate?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, configuration?: Array<{ __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null } | null> | null } | null> | null, configuration?: Array<{ __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null } | null> | null } | null> | null } | null> | null, tests?: Array<{ __typename?: 'RecipeTest', type: TestType, name: string, message?: string | null, args?: Array<{ __typename?: 'TestArgument', name: string, repo: string, key: string } | null> | null } | null> | null, repository?: { __typename?: 'Repository', id: string, name: string } | null, oidcSettings?: { __typename?: 'OidcSettings', uriFormat?: string | null, uriFormats?: Array | null, authMethod: OidcAuthMethod, domainKey?: string | null, subdomain?: boolean | null } | null, recipeSections?: Array<{ __typename?: 'RecipeSection', index?: number | null, repository?: { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, installation?: { __typename?: 'Installation', id: string, context?: Map | null, license?: string | null, licenseKey?: string | null, acmeKeyId?: string | null, acmeSecret?: string | null, autoUpgrade?: boolean | null, trackTag: string, pingedAt?: Date | null, repository?: { __typename?: 'Repository', id: string, name: string, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null } | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, oidcProvider?: { __typename?: 'OidcProvider', id: string, clientId: string, authMethod: OidcAuthMethod, clientSecret: string, redirectUris?: Array | null, bindings?: Array<{ __typename?: 'OidcProviderBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null, configuration?: { __typename?: 'OuathConfiguration', issuer?: string | null, authorizationEndpoint?: string | null, tokenEndpoint?: string | null, jwksUri?: string | null, userinfoEndpoint?: string | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null } | null } | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null } | null, recipeItems?: Array<{ __typename?: 'RecipeItem', id?: string | null, chart?: { __typename?: 'Chart', id?: string | null, name: string, description?: string | null, latestVersion?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, terraform?: { __typename?: 'Terraform', id?: string | null, name?: string | null, readme?: string | null, package?: string | null, description?: string | null, latestVersion?: string | null, valuesTemplate?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, configuration?: Array<{ __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null } | null> | null } | null> | null, configuration?: Array<{ __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null } | null> | null } | null> | null } | null }; export type ListRecipesQueryVariables = Exact<{ repositoryName?: InputMaybe; @@ -5678,7 +5678,7 @@ export type ListRecipesQueryVariables = Exact<{ }>; -export type ListRecipesQuery = { __typename?: 'RootQueryType', recipes?: { __typename?: 'RecipeConnection', edges?: Array<{ __typename?: 'RecipeEdge', node?: { __typename?: 'Recipe', id: string, name: string, description?: string | null, restricted?: boolean | null, provider?: Provider | null, tests?: Array<{ __typename?: 'RecipeTest', type: TestType, name: string, message?: string | null, args?: Array<{ __typename?: 'TestArgument', name: string, repo: string, key: string } | null> | null } | null> | null, repository?: { __typename?: 'Repository', id: string, name: string } | null, oidcSettings?: { __typename?: 'OidcSettings', uriFormat?: string | null, uriFormats?: Array | null, authMethod: OidcAuthMethod, domainKey?: string | null, subdomain?: boolean | null } | null, recipeSections?: Array<{ __typename?: 'RecipeSection', index?: number | null, repository?: { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, installation?: { __typename?: 'Installation', id: string, context?: Map | null, license?: string | null, licenseKey?: string | null, acmeKeyId?: string | null, acmeSecret?: string | null, autoUpgrade?: boolean | null, trackTag: string, pingedAt?: Date | null, repository?: { __typename?: 'Repository', id: string, name: string, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null } | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, oidcProvider?: { __typename?: 'OidcProvider', id: string, clientId: string, authMethod: OidcAuthMethod, clientSecret: string, redirectUris?: Array | null, bindings?: Array<{ __typename?: 'OidcProviderBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null, configuration?: { __typename?: 'OuathConfiguration', issuer?: string | null, authorizationEndpoint?: string | null, tokenEndpoint?: string | null, jwksUri?: string | null, userinfoEndpoint?: string | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null } | null } | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null } | null, recipeItems?: Array<{ __typename?: 'RecipeItem', id?: string | null, chart?: { __typename?: 'Chart', id?: string | null, name: string, description?: string | null, latestVersion?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, terraform?: { __typename?: 'Terraform', id?: string | null, name?: string | null, readme?: string | null, package?: string | null, description?: string | null, latestVersion?: string | null, valuesTemplate?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, configuration?: Array<{ __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null } | null> | null } | null> | null, configuration?: Array<{ __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null } | null> | null } | null> | null } | null } | null> | null } | null }; +export type ListRecipesQuery = { __typename?: 'RootQueryType', recipes?: { __typename?: 'RecipeConnection', edges?: Array<{ __typename?: 'RecipeEdge', node?: { __typename?: 'Recipe', id: string, name: string, description?: string | null, restricted?: boolean | null, provider?: Provider | null, tests?: Array<{ __typename?: 'RecipeTest', type: TestType, name: string, message?: string | null, args?: Array<{ __typename?: 'TestArgument', name: string, repo: string, key: string } | null> | null } | null> | null, repository?: { __typename?: 'Repository', id: string, name: string } | null, oidcSettings?: { __typename?: 'OidcSettings', uriFormat?: string | null, uriFormats?: Array | null, authMethod: OidcAuthMethod, domainKey?: string | null, subdomain?: boolean | null } | null, recipeSections?: Array<{ __typename?: 'RecipeSection', index?: number | null, repository?: { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, installation?: { __typename?: 'Installation', id: string, context?: Map | null, license?: string | null, licenseKey?: string | null, acmeKeyId?: string | null, acmeSecret?: string | null, autoUpgrade?: boolean | null, trackTag: string, pingedAt?: Date | null, repository?: { __typename?: 'Repository', id: string, name: string, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null } | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, oidcProvider?: { __typename?: 'OidcProvider', id: string, clientId: string, authMethod: OidcAuthMethod, clientSecret: string, redirectUris?: Array | null, bindings?: Array<{ __typename?: 'OidcProviderBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null, configuration?: { __typename?: 'OuathConfiguration', issuer?: string | null, authorizationEndpoint?: string | null, tokenEndpoint?: string | null, jwksUri?: string | null, userinfoEndpoint?: string | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null } | null } | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null } | null, recipeItems?: Array<{ __typename?: 'RecipeItem', id?: string | null, chart?: { __typename?: 'Chart', id?: string | null, name: string, description?: string | null, latestVersion?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, terraform?: { __typename?: 'Terraform', id?: string | null, name?: string | null, readme?: string | null, package?: string | null, description?: string | null, latestVersion?: string | null, valuesTemplate?: string | null, insertedAt?: Date | null, dependencies?: { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null } | null } | null, configuration?: Array<{ __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null } | null> | null } | null> | null, configuration?: Array<{ __typename?: 'RecipeConfiguration', name?: string | null, type?: Datatype | null, default?: string | null, documentation?: string | null, optional?: boolean | null, placeholder?: string | null, functionName?: string | null, condition?: { __typename?: 'RecipeCondition', field: string, operation: Operation, value?: string | null } | null, validation?: { __typename?: 'RecipeValidation', type: ValidationType, regex?: string | null, message: string } | null } | null> | null } | null> | null } | null } | null> | null } | null }; export type CreateRecipeMutationVariables = Exact<{ name: Scalars['String']['input']; @@ -5708,7 +5708,7 @@ export type GetStackQueryVariables = Exact<{ }>; -export type GetStackQuery = { __typename?: 'RootQueryType', stack?: { __typename?: 'Stack', id: string, name: string, displayName?: string | null, description?: string | null, featured?: boolean | null, creator?: { __typename?: 'User', id: string, name: string } | null, collections?: Array<{ __typename?: 'StackCollection', id: string, provider: Provider, bundles?: Array<{ __typename?: 'StackRecipe', recipe: { __typename?: 'Recipe', repository?: { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, tags?: Array<{ __typename?: 'Tag', tag: string } | null> | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null } | null } } | null> | null } | null> | null } | null }; +export type GetStackQuery = { __typename?: 'RootQueryType', stack?: { __typename?: 'Stack', id: string, name: string, displayName?: string | null, description?: string | null, featured?: boolean | null, creator?: { __typename?: 'User', id: string, name: string } | null, collections?: Array<{ __typename?: 'StackCollection', id: string, provider: Provider, bundles?: Array<{ __typename?: 'StackRecipe', recipe: { __typename?: 'Recipe', repository?: { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, tags?: Array<{ __typename?: 'Tag', tag: string } | null> | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null } | null } } | null> | null } | null> | null } | null }; export type ListStacksQueryVariables = Exact<{ featured?: InputMaybe; @@ -5716,7 +5716,7 @@ export type ListStacksQueryVariables = Exact<{ }>; -export type ListStacksQuery = { __typename?: 'RootQueryType', stacks?: { __typename?: 'StackConnection', edges?: Array<{ __typename?: 'StackEdge', node?: { __typename?: 'Stack', id: string, name: string, displayName?: string | null, description?: string | null, featured?: boolean | null, creator?: { __typename?: 'User', id: string, name: string } | null, collections?: Array<{ __typename?: 'StackCollection', id: string, provider: Provider, bundles?: Array<{ __typename?: 'StackRecipe', recipe: { __typename?: 'Recipe', repository?: { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, tags?: Array<{ __typename?: 'Tag', tag: string } | null> | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null } | null } } | null> | null } | null> | null } | null } | null> | null } | null }; +export type ListStacksQuery = { __typename?: 'RootQueryType', stacks?: { __typename?: 'StackConnection', edges?: Array<{ __typename?: 'StackEdge', node?: { __typename?: 'Stack', id: string, name: string, displayName?: string | null, description?: string | null, featured?: boolean | null, creator?: { __typename?: 'User', id: string, name: string } | null, collections?: Array<{ __typename?: 'StackCollection', id: string, provider: Provider, bundles?: Array<{ __typename?: 'StackRecipe', recipe: { __typename?: 'Recipe', repository?: { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, tags?: Array<{ __typename?: 'Tag', tag: string } | null> | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null } | null } } | null> | null } | null> | null } | null } | null> | null } | null }; export type ApplyLockFragment = { __typename?: 'ApplyLock', id: string, lock?: string | null }; @@ -5724,13 +5724,13 @@ export type CategoryFragment = { __typename?: 'CategoryInfo', category?: Categor export type FileContentFragment = { __typename?: 'FileContent', content: string, path: string }; -export type RepoFragment = { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null }; +export type RepoFragment = { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null }; -export type MarketplaceRepositoryFragment = { __typename?: 'Repository', id: string, name: string, description?: string | null, releaseStatus?: ReleaseStatus | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, installation?: { __typename?: 'Installation', id: string } | null, tags?: Array<{ __typename?: 'Tag', tag: string } | null> | null }; +export type MarketplaceRepositoryFragment = { __typename?: 'Repository', id: string, name: string, description?: string | null, releaseStatus?: ReleaseStatus | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, installation?: { __typename?: 'Installation', id: string } | null, tags?: Array<{ __typename?: 'Tag', tag: string } | null> | null }; export type DependenciesFragment = { __typename?: 'Dependencies', wait?: boolean | null, application?: boolean | null, providers?: Array | null, secrets?: Array | null, providerWirings?: Map | null, outputs?: Map | null, dependencies?: Array<{ __typename?: 'Dependency', name?: string | null, repo?: string | null, type?: DependencyType | null, version?: string | null, optional?: boolean | null } | null> | null, wirings?: { __typename?: 'Wirings', terraform?: Map | null, helm?: Map | null } | null }; -export type IntegrationFragment = { __typename?: 'Integration', id: string, name: string, icon?: string | null, sourceUrl?: string | null, description?: string | null, tags?: Array<{ __typename?: 'Tag', tag: string } | null> | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null }; +export type IntegrationFragment = { __typename?: 'Integration', id: string, name: string, icon?: string | null, sourceUrl?: string | null, description?: string | null, tags?: Array<{ __typename?: 'Tag', tag: string } | null> | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null }; export type RepositoryQueryVariables = Exact<{ id?: InputMaybe; @@ -5738,7 +5738,7 @@ export type RepositoryQueryVariables = Exact<{ }>; -export type RepositoryQuery = { __typename?: 'RootQueryType', repository?: { __typename?: 'Repository', editable?: boolean | null, publicKey?: string | null, secrets?: Map | null, upgradeChannels?: Array | null, readme?: string | null, mainBranch?: string | null, gitUrl?: string | null, homepage?: string | null, documentation?: string | null, id: string, name: string, notes?: string | null, description?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, artifacts?: Array<{ __typename?: 'Artifact', id?: string | null, name?: string | null, blob?: string | null, type?: ArtifactType | null, platform?: ArtifactPlatform | null, arch?: string | null, filesize?: number | null, sha?: string | null, readme?: string | null, insertedAt?: Date | null, updatedAt?: Date | null } | null> | null, installation?: { __typename?: 'Installation', id: string, context?: Map | null, license?: string | null, licenseKey?: string | null, acmeKeyId?: string | null, acmeSecret?: string | null, autoUpgrade?: boolean | null, trackTag: string, pingedAt?: Date | null, oidcProvider?: { __typename?: 'OidcProvider', id: string, clientId: string, authMethod: OidcAuthMethod, clientSecret: string, redirectUris?: Array | null, bindings?: Array<{ __typename?: 'OidcProviderBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null, configuration?: { __typename?: 'OuathConfiguration', issuer?: string | null, authorizationEndpoint?: string | null, tokenEndpoint?: string | null, jwksUri?: string | null, userinfoEndpoint?: string | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null } | null, repository?: { __typename?: 'Repository', id: string, name: string, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null } | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null } | null, tags?: Array<{ __typename?: 'Tag', tag: string } | null> | null, license?: { __typename?: 'License', name?: string | null, url?: string | null } | null, community?: { __typename?: 'Community', discord?: string | null, slack?: string | null, homepage?: string | null, gitUrl?: string | null, twitter?: string | null } | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null } | null }; +export type RepositoryQuery = { __typename?: 'RootQueryType', repository?: { __typename?: 'Repository', editable?: boolean | null, publicKey?: string | null, secrets?: Map | null, upgradeChannels?: Array | null, readme?: string | null, mainBranch?: string | null, gitUrl?: string | null, homepage?: string | null, documentation?: string | null, id: string, name: string, notes?: string | null, description?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, artifacts?: Array<{ __typename?: 'Artifact', id?: string | null, name?: string | null, blob?: string | null, type?: ArtifactType | null, platform?: ArtifactPlatform | null, arch?: string | null, filesize?: number | null, sha?: string | null, readme?: string | null, insertedAt?: Date | null, updatedAt?: Date | null } | null> | null, installation?: { __typename?: 'Installation', id: string, context?: Map | null, license?: string | null, licenseKey?: string | null, acmeKeyId?: string | null, acmeSecret?: string | null, autoUpgrade?: boolean | null, trackTag: string, pingedAt?: Date | null, oidcProvider?: { __typename?: 'OidcProvider', id: string, clientId: string, authMethod: OidcAuthMethod, clientSecret: string, redirectUris?: Array | null, bindings?: Array<{ __typename?: 'OidcProviderBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null, configuration?: { __typename?: 'OuathConfiguration', issuer?: string | null, authorizationEndpoint?: string | null, tokenEndpoint?: string | null, jwksUri?: string | null, userinfoEndpoint?: string | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null } | null, repository?: { __typename?: 'Repository', id: string, name: string, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null } | null, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null } | null, tags?: Array<{ __typename?: 'Tag', tag: string } | null> | null, license?: { __typename?: 'License', name?: string | null, url?: string | null } | null, community?: { __typename?: 'Community', discord?: string | null, slack?: string | null, homepage?: string | null, gitUrl?: string | null, twitter?: string | null } | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null } | null }; export type CreateResourceDefinitionMutationVariables = Exact<{ name: Scalars['String']['input']; @@ -5802,7 +5802,7 @@ export type MarketplaceRepositoriesQueryVariables = Exact<{ }>; -export type MarketplaceRepositoriesQuery = { __typename?: 'RootQueryType', repositories?: { __typename?: 'RepositoryConnection', pageInfo: { __typename?: 'PageInfo', endCursor?: string | null, hasNextPage: boolean }, edges?: Array<{ __typename?: 'RepositoryEdge', node?: { __typename?: 'Repository', id: string, name: string, description?: string | null, releaseStatus?: ReleaseStatus | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, installation?: { __typename?: 'Installation', id: string } | null, tags?: Array<{ __typename?: 'Tag', tag: string } | null> | null } | null } | null> | null } | null }; +export type MarketplaceRepositoriesQuery = { __typename?: 'RootQueryType', repositories?: { __typename?: 'RepositoryConnection', pageInfo: { __typename?: 'PageInfo', endCursor?: string | null, hasNextPage: boolean }, edges?: Array<{ __typename?: 'RepositoryEdge', node?: { __typename?: 'Repository', id: string, name: string, description?: string | null, releaseStatus?: ReleaseStatus | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, installation?: { __typename?: 'Installation', id: string } | null, tags?: Array<{ __typename?: 'Tag', tag: string } | null> | null } | null } | null> | null } | null }; export type ScaffoldsQueryVariables = Exact<{ app: Scalars['String']['input']; @@ -5931,7 +5931,7 @@ export type UpgradeQueueFragment = { __typename?: 'UpgradeQueue', id: string, ac export type RolloutFragment = { __typename?: 'Rollout', id: string, event?: string | null, cursor?: string | null, count?: number | null, status: RolloutStatus, heartbeat?: Date | null }; -export type UpgradeFragment = { __typename?: 'Upgrade', id: string, message?: string | null, insertedAt?: Date | null, repository?: { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null } | null }; +export type UpgradeFragment = { __typename?: 'Upgrade', id: string, message?: string | null, insertedAt?: Date | null, repository?: { __typename?: 'Repository', id: string, name: string, notes?: string | null, description?: string | null, documentation?: string | null, icon?: string | null, darkIcon?: string | null, private?: boolean | null, trending?: boolean | null, verified?: boolean | null, category?: Category | null, docs?: Array<{ __typename?: 'FileContent', content: string, path: string } | null> | null, oauthSettings?: { __typename?: 'OauthSettings', uriFormat: string, authMethod: OidcAuthMethod } | null, publisher?: { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, recipes?: Array<{ __typename?: 'Recipe', name: string, provider?: Provider | null, description?: string | null } | null> | null } | null }; export type DeferredUpdateFragment = { __typename?: 'DeferredUpdate', id: string, dequeueAt?: Date | null, attempts?: number | null, insertedAt?: Date | null, version?: { __typename?: 'Version', version: string } | null }; @@ -5939,11 +5939,11 @@ export type AccountFragment = { __typename?: 'Account', id: string, name?: strin export type GroupFragment = { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null }; -export type UserFragment = { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null }; +export type UserFragment = { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null }; export type ImpersonationPolicyFragment = { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null }; -export type GroupMemberFragment = { __typename?: 'GroupMember', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null }; +export type GroupMemberFragment = { __typename?: 'GroupMember', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null }; export type TokenFragment = { __typename?: 'PersistedToken', id?: string | null, token?: string | null, insertedAt?: Date | null }; @@ -5951,22 +5951,22 @@ export type TokenAuditFragment = { __typename?: 'PersistedTokenAudit', ip?: stri export type AddressFragment = { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null }; -export type PublisherFragment = { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null }; +export type PublisherFragment = { __typename?: 'Publisher', id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null }; export type WebhookFragment = { __typename?: 'Webhook', id?: string | null, url?: string | null, secret?: string | null, insertedAt?: Date | null }; -export type RoleBindingFragment = { __typename?: 'RoleBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null }; +export type RoleBindingFragment = { __typename?: 'RoleBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null }; -export type RoleFragment = { __typename?: 'Role', id: string, name: string, description?: string | null, repositories?: Array | null, permissions?: Array | null, roleBindings?: Array<{ __typename?: 'RoleBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null }; +export type RoleFragment = { __typename?: 'Role', id: string, name: string, description?: string | null, repositories?: Array | null, permissions?: Array | null, roleBindings?: Array<{ __typename?: 'RoleBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null }; -export type PublicKeyFragment = { __typename?: 'PublicKey', id: string, name: string, digest: string, insertedAt?: Date | null, content: string, user: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } }; +export type PublicKeyFragment = { __typename?: 'PublicKey', id: string, name: string, digest: string, insertedAt?: Date | null, content: string, user: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } }; export type EabCredentialFragment = { __typename?: 'EabCredential', id: string, keyId: string, hmacKey: string, cluster: string, provider: Provider, insertedAt?: Date | null }; export type MeQueryVariables = Exact<{ [key: string]: never; }>; -export type MeQuery = { __typename?: 'RootQueryType', me?: { __typename?: 'User', demoing?: boolean | null, loginMethod?: LoginMethod | null, hasInstallations?: boolean | null, hasShell?: boolean | null, id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, account: { __typename?: 'Account', id: string, name?: string | null, billingCustomerId?: string | null, backgroundColor?: string | null, userCount?: string | null, trialed?: boolean | null, rootUser?: { __typename?: 'User', id: string, name: string, email: string } | null, domainMappings?: Array<{ __typename?: 'DomainMapping', id: string, domain: string, enableSso?: boolean | null } | null> | null }, publisher?: { __typename?: 'Publisher', billingAccountId?: string | null, id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, boundRoles?: Array<{ __typename?: 'Role', id: string, name: string, description?: string | null, repositories?: Array | null, permissions?: Array | null, roleBindings?: Array<{ __typename?: 'RoleBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null } | null> | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null, configuration?: { __typename?: 'PluralConfiguration', stripeConnectId?: string | null, stripePublishableKey?: string | null, registry?: string | null, gitCommit?: string | null } | null }; +export type MeQuery = { __typename?: 'RootQueryType', me?: { __typename?: 'User', demoing?: boolean | null, loginMethod?: LoginMethod | null, hasInstallations?: boolean | null, hasShell?: boolean | null, id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, account: { __typename?: 'Account', id: string, name?: string | null, billingCustomerId?: string | null, backgroundColor?: string | null, userCount?: string | null, trialed?: boolean | null, rootUser?: { __typename?: 'User', id: string, name: string, email: string } | null, domainMappings?: Array<{ __typename?: 'DomainMapping', id: string, domain: string, enableSso?: boolean | null } | null> | null }, publisher?: { __typename?: 'Publisher', billingAccountId?: string | null, id?: string | null, name: string, phone?: string | null, avatar?: string | null, description?: string | null, backgroundColor?: string | null, owner?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, address?: { __typename?: 'Address', line1?: string | null, line2?: string | null, city?: string | null, country?: string | null, state?: string | null, zip?: string | null } | null } | null, boundRoles?: Array<{ __typename?: 'Role', id: string, name: string, description?: string | null, repositories?: Array | null, permissions?: Array | null, roleBindings?: Array<{ __typename?: 'RoleBinding', id: string, user?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, group?: { __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null } | null> | null } | null> | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null, configuration?: { __typename?: 'PluralConfiguration', stripeConnectId?: string | null, stripePublishableKey?: string | null, registry?: string | null, gitCommit?: string | null } | null }; export type GetLoginMethodQueryVariables = Exact<{ email: Scalars['String']['input']; @@ -5985,7 +5985,7 @@ export type ListKeysQueryVariables = Exact<{ }>; -export type ListKeysQuery = { __typename?: 'RootQueryType', publicKeys?: { __typename?: 'PublicKeyConnection', edges?: Array<{ __typename?: 'PublicKeyEdge', node?: { __typename?: 'PublicKey', id: string, name: string, digest: string, insertedAt?: Date | null, content: string, user: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } } | null } | null> | null } | null }; +export type ListKeysQuery = { __typename?: 'RootQueryType', publicKeys?: { __typename?: 'PublicKeyConnection', edges?: Array<{ __typename?: 'PublicKeyEdge', node?: { __typename?: 'PublicKey', id: string, name: string, digest: string, insertedAt?: Date | null, content: string, user: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } } | null } | null> | null } | null }; export type GetEabCredentialQueryVariables = Exact<{ cluster: Scalars['String']['input']; @@ -6110,7 +6110,7 @@ export type ResetTokenQueryVariables = Exact<{ }>; -export type ResetTokenQuery = { __typename?: 'RootQueryType', resetToken?: { __typename?: 'ResetToken', type: ResetTokenType, user: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } } | null }; +export type ResetTokenQuery = { __typename?: 'RootQueryType', resetToken?: { __typename?: 'ResetToken', type: ResetTokenType, user: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } } | null }; export type UsersQueryVariables = Exact<{ q?: InputMaybe; @@ -6135,7 +6135,7 @@ export type DeleteUserMutationVariables = Exact<{ }>; -export type DeleteUserMutation = { __typename?: 'RootMutationType', deleteUser?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null }; +export type DeleteUserMutation = { __typename?: 'RootMutationType', deleteUser?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null }; export type UpdateUserMutationVariables = Exact<{ id?: InputMaybe; @@ -6143,7 +6143,7 @@ export type UpdateUserMutationVariables = Exact<{ }>; -export type UpdateUserMutation = { __typename?: 'RootMutationType', updateUser?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null } | null }; +export type UpdateUserMutation = { __typename?: 'RootMutationType', updateUser?: { __typename?: 'User', id: string, name: string, email: string, avatar?: string | null, provider?: Provider | null, demoed?: boolean | null, onboarding?: OnboardingState | null, emailConfirmed?: boolean | null, emailConfirmBy?: Date | null, backgroundColor?: string | null, serviceAccount?: boolean | null, hasInstallations?: boolean | null, hasShell?: boolean | null, onboardingChecklist?: { __typename?: 'OnboardingChecklist', dismissed?: boolean | null, status?: OnboardingChecklistState | null } | null, invites?: Array<{ __typename?: 'Invite', id: string, email?: string | null } | null> | null, roles?: { __typename?: 'Roles', admin?: boolean | null } | null, groups?: Array<{ __typename?: 'Group', id: string, name: string, global?: boolean | null, description?: string | null } | null> | null, impersonationPolicy?: { __typename?: 'ImpersonationPolicy', id: string, bindings?: Array<{ __typename?: 'ImpersonationPolicyBinding', id: string, group?: { __typename?: 'Group', id: string, name: string } | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null } | null> | null } | null } | null }; export type VersionTagFragment = { __typename?: 'VersionTag', id: string, tag: string, version?: { __typename?: 'Version', id: string } | null }; @@ -6165,6 +6165,23 @@ export const GroupFragmentDoc = gql` description } `; +export const ImpersonationPolicyFragmentDoc = gql` + fragment ImpersonationPolicy on ImpersonationPolicy { + id + bindings { + id + group { + id + name + } + user { + id + name + email + } + } +} + `; export const UserFragmentDoc = gql` fragment User on User { id @@ -6194,8 +6211,12 @@ export const UserFragmentDoc = gql` groups { ...Group } + impersonationPolicy { + ...ImpersonationPolicy + } } - ${GroupFragmentDoc}`; + ${GroupFragmentDoc} +${ImpersonationPolicyFragmentDoc}`; export const FileContentFragmentDoc = gql` fragment FileContent on FileContent { content @@ -6525,23 +6546,6 @@ export const PackageScanFragmentDoc = gql` } ${ScanViolationFragmentDoc} ${ScanErrorFragmentDoc}`; -export const ImpersonationPolicyFragmentDoc = gql` - fragment ImpersonationPolicy on ImpersonationPolicy { - id - bindings { - id - group { - id - name - } - user { - id - name - email - } - } -} - `; export const InstallationRepoFragmentDoc = gql` fragment InstallationRepo on Repository { id diff --git a/www/src/graph/users.graphql b/www/src/graph/users.graphql index e6258286f..e824b3032 100644 --- a/www/src/graph/users.graphql +++ b/www/src/graph/users.graphql @@ -42,6 +42,9 @@ fragment User on User { groups { ...Group } + impersonationPolicy { + ...ImpersonationPolicy + } } fragment ImpersonationPolicy on ImpersonationPolicy { From e5cbd422252dc3218317fec8deadf9c34a051f0f Mon Sep 17 00:00:00 2001 From: Jake Laderman Date: Mon, 9 Sep 2024 17:03:10 -0400 Subject: [PATCH 17/17] add oidc loading suspense --- .../plural-cloud/ConsoleInstanceOIDC.tsx | 82 ++++++++++--------- 1 file changed, 42 insertions(+), 40 deletions(-) diff --git a/www/src/components/overview/clusters/plural-cloud/ConsoleInstanceOIDC.tsx b/www/src/components/overview/clusters/plural-cloud/ConsoleInstanceOIDC.tsx index 10908476b..a7587b96d 100644 --- a/www/src/components/overview/clusters/plural-cloud/ConsoleInstanceOIDC.tsx +++ b/www/src/components/overview/clusters/plural-cloud/ConsoleInstanceOIDC.tsx @@ -6,6 +6,7 @@ import { FormField, Modal, PeopleIcon, + Spinner, } from '@pluralsh/design-system' import { BindingInput, @@ -21,11 +22,11 @@ import { InputMaybe, OidcAuthMethod, OidcProviderBinding, - useRepositoryQuery, + useRepositorySuspenseQuery, useUpdateOidcProviderMutation, } from 'generated/graphql' import { isEmpty } from 'lodash' -import { useState } from 'react' +import { Suspense, useState } from 'react' import { useTheme } from 'styled-components' export function ConsoleInstanceOIDC({ @@ -36,31 +37,40 @@ export function ConsoleInstanceOIDC({ const [open, setOpen] = useState(false) return ( - + } > - <> - - e.preventDefault()} - open={open} - onClose={() => setOpen(false)} - size="large" - > - + <> + + e.preventDefault()} + open={open} onClose={() => setOpen(false)} - /> - - - + size="large" + > + setOpen(false)} + /> + + + + ) } @@ -71,27 +81,19 @@ function ConsoleInstanceOIDCInner({ instance: ConsoleInstanceFragment onClose: () => void }) { - const [bindings, setBindings] = useState([]) - const [redirectUris, setRedirectUris] = useState[]>([]) - - const { - data, - loading: loadingRepo, - error: errorRepo, - } = useRepositoryQuery({ + const { data, error: errorRepo } = useRepositorySuspenseQuery({ variables: { name: 'console' }, fetchPolicy: 'cache-and-network', - onCompleted: (data) => { - setBindings(data?.repository?.installation?.oidcProvider?.bindings) - setRedirectUris( - data?.repository?.installation?.oidcProvider?.redirectUris ?? [] - ) - }, }) const installation = data?.repository?.installation const provider = installation?.oidcProvider + const [bindings, setBindings] = useState(provider?.bindings ?? []) + const [redirectUris, setRedirectUris] = useState[]>( + provider?.redirectUris ?? [] + ) + const [mutation, { loading: loadingMutation, error: errorMutation }] = useUpdateOidcProviderMutation({ variables: { @@ -109,7 +111,7 @@ function ConsoleInstanceOIDCInner({ onCompleted: onClose, }) - if (!provider?.bindings || loadingRepo || errorRepo) return null + if (!installation || errorRepo) return

Something went wrong.

return (