Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cloud setup flow #1351

Merged
merged 17 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions www/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
html,
body {
background-color: #171a21;
overflow: auto hidden;
}
html[data-theme-mode='light'],
html[data-theme-mode='light'] body {
Expand Down
1 change: 1 addition & 0 deletions www/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
12 changes: 8 additions & 4 deletions www/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -79,10 +81,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',
Expand Down Expand Up @@ -184,7 +186,9 @@ function App() {
theme={mergedStyledTheme as any as ThemeType}
themeMode="dark"
>
<RootBoxSC>{routes}</RootBoxSC>
<PluralErrorBoundary>
<RootBoxSC>{routes}</RootBoxSC>
</PluralErrorBoundary>
</Grommet>
</BreadcrumbsProvider>
</OverlayContextProvider>
Expand Down
51 changes: 44 additions & 7 deletions www/src/components/Plural.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,26 @@ const Clusters = lazy(() =>
default: module.Clusters,
}))
)
const Apps = lazy(() =>
import('./overview/apps/Apps').then((module) => ({ default: module.Apps }))
const SelfHostedClusters = lazy(() =>
import('./overview/clusters/self-hosted/SelfHostedClusters').then(
(module) => ({
default: module.SelfHostedClusters,
})
)
)
const PluralCloudInstances = lazy(() =>
import('./overview/clusters/plural-cloud/PluralCloudInstances').then(
(module) => ({
default: module.PluralCloudInstances,
})
)
)

// Create cluster.
const CreateCluster = lazy(() =>
import('./create-cluster/CreateCluster').then((module) => ({
default: module.CreateCluster,
}))
)

// Cluster and app.
Expand Down Expand Up @@ -637,12 +655,31 @@ export function PluralInner() {
<Route
path="clusters"
element={<Clusters />}
/>
<Route
path="apps"
element={<Apps />}
/>
>
<Route
index
element={
<Navigate
replace
to="self-hosted"
/>
}
/>
<Route
path="self-hosted"
element={<SelfHostedClusters />}
/>
<Route
path="plural-cloud"
element={<PluralCloudInstances />}
/>
</Route>
</Route>
{/* CREATE CLUSTER */}
<Route
path="/create-cluster"
element={<CreateCluster />}
/>
{/* CLUSTERS */}
<Route
path="/clusters/:clusterId/"
Expand Down
16 changes: 11 additions & 5 deletions www/src/components/account/utils.ts
Original file line number Diff line number Diff line change
@@ -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<string>
user: Nullable<User>
group: Nullable<Group>
}>

export const sanitize = (props: SanitizePropsType) => ({
id: props?.id,
userId: props?.user?.id,
groupId: props?.group?.id,
})

export function hasRbac(user: CurrentUser, permission: Permission) {
Expand Down
3 changes: 2 additions & 1 deletion www/src/components/app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import { Flex, P } from 'honorable'
import { useContext, useMemo } from 'react'
import { Link, Outlet, useParams } from 'react-router-dom'

import { CLUSTERS_ROOT_CRUMB } from 'components/overview/clusters/Clusters'

import { AppContextProvider } from '../../contexts/AppContext'
import ClustersContext from '../../contexts/ClustersContext'
import { Repository, useRepositoryQuery } from '../../generated/graphql'
import { config } from '../../markdoc/mdSchema'
import { CLUSTERS_ROOT_CRUMB } from '../overview/Overview'
import ImpersonateServiceAccount from '../utils/ImpersonateServiceAccount'
import { ResponsiveLayoutContentContainer } from '../utils/layout/ResponsiveLayoutContentContainer'
import { ResponsiveLayoutPage } from '../utils/layout/ResponsiveLayoutPage'
Expand Down
2 changes: 1 addition & 1 deletion www/src/components/app/oidc/OIDC.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
25 changes: 11 additions & 14 deletions www/src/components/cluster/Cluster.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { useContext, useEffect, useMemo, useState } from 'react'
import { useNavigate, useParams } from 'react-router-dom'
import {
Button,
ClusterIcon,
Expand All @@ -10,23 +8,25 @@ import {
useSetBreadcrumbs,
} from '@pluralsh/design-system'
import { Div, Flex } from 'honorable'
import { useContext, useEffect, useMemo, useState } from 'react'
import { useNavigate, useParams } from 'react-router-dom'

import { CLUSTERS_ROOT_CRUMB } from 'components/overview/clusters/Clusters'

import ClustersContext from '../../contexts/ClustersContext'
import ImpersonateServiceAccount from '../utils/ImpersonateServiceAccount'
import { CLUSTERS_ROOT_CRUMB } from '../overview/Overview'
import CurrentUserContext from '../../contexts/CurrentUserContext'
import { ensureURLValidity } from '../../utils/url'
import { ClusterPicker } from '../utils/ClusterPicker'
import ImpersonateServiceAccount from '../utils/ImpersonateServiceAccount'
import { ResponsiveLayoutPage } from '../utils/layout/ResponsiveLayoutPage'
import CurrentUserContext from '../../contexts/CurrentUserContext'

import { ClusterDependencyModal } from './ClusterDependencyModal'
import { ClusterSidecar } from './ClusterSidecar'
import { ClusterApps } from './ClusterApps'
import { ClusterUpgrades } from './ClusterUpgrades'
import { ClusterAdminsModal } from './ClusterAdminsModal'
import { ClusterApps } from './ClusterApps'
import { ClusterDependencyModal } from './ClusterDependencyModal'
import ClusterMetadataPanel from './ClusterMetadataPanel'
import { CollapsibleButton } from './misc'
import { ClusterPromoteModal } from './ClusterPromoteModal'
import { ClusterSidecar } from './ClusterSidecar'
import { CollapsibleButton } from './misc'

export function Cluster() {
const [dependencyOpen, setDependencyOpen] = useState(false)
Expand Down Expand Up @@ -177,10 +177,7 @@ export function Cluster() {
id={cluster?.owner?.id}
skip={!cluster.owner?.serviceAccount}
>
<>
<ClusterApps cluster={cluster} />
<ClusterUpgrades cluster={cluster} />
</>
<ClusterApps cluster={cluster} />
</ImpersonateServiceAccount>
</Flex>
</Flex>
Expand Down
52 changes: 37 additions & 15 deletions www/src/components/cluster/ClusterAdminsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -42,6 +42,14 @@ function ClusterAdmins({
onInvite,
onGroupCreate,
selected,
showHeading = true,
}: {
serviceAccount: Nullable<UserFragment>
onClose: () => void
onInvite: () => void
onGroupCreate: () => void
selected: any
showHeading?: boolean
}): ReactElement {
const [bindings, setBindings] = useState([
...(serviceAccount?.impersonationPolicy?.bindings ?? []),
Expand All @@ -50,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,
Expand All @@ -64,27 +72,29 @@ function ClusterAdmins({
error={error}
/>
)}
<Div
body2
color="text-light"
>
Bind users to the service account owning this cluster. This will allow
users to do low level git operations to this cluster.
</Div>
{showHeading && (
<Div
body2
color="text-light"
>
Bind users to the service account owning this cluster. This will allow
users to do low level git operations to this cluster.
</Div>
)}
<BindingInput
type="user"
hint="Users that can administer this cluster"
bindings={bindings
.filter(({ user }) => !!user)
.map(({ user: { email } }) => email)}
customBindings={serviceAccount.invites?.map((invite) => (
customBindings={serviceAccount?.invites?.map((invite) => (
<Tooltip label="Pending invitation">
<Chip
fillLevel={2}
size="small"
icon={<InfoOutlineIcon color="icon-xlight" />}
>
<Span color="text-primary-disabled">{invite.email}</Span>
<Span color="text-primary-disabled">{invite?.email}</Span>
</Chip>
</Tooltip>
))}
Expand Down Expand Up @@ -143,7 +153,17 @@ function ClusterAdmins({
)
}

export function ClusterAdminsModal({ onClose, serviceAccount }) {
export function ClusterAdminsModal({
open = true,
onClose,
serviceAccount,
showHeading = true,
}: {
open?: boolean
onClose: () => void
serviceAccount: Nullable<UserFragment>
showHeading?: boolean
}) {
const { refetchClusters } = useContext(ClustersContext)
const { isPaidPlan, isTrialPlan } = useContext(subscriptionContext)

Expand All @@ -167,15 +187,16 @@ export function ClusterAdminsModal({ onClose, serviceAccount }) {
if (!(isPaidPlan || isTrialPlan))
return (
<UpgradeNeededModal
open
open={open}
onClose={onClose}
/>
)

return (
<Modal
onOpenAutoFocus={(e) => e.preventDefault()}
header={header}
open
open={open}
onClose={onClose}
style={{ padding: 0 }}
size="large"
Expand All @@ -194,6 +215,7 @@ export function ClusterAdminsModal({ onClose, serviceAccount }) {
setLastView(View.Managers)
}}
selected={bindings}
showHeading={showHeading}
/>
)}
{view === View.InviteUser && (
Expand All @@ -210,7 +232,7 @@ export function ClusterAdminsModal({ onClose, serviceAccount }) {
onBack={() => setView(View.Managers)}
bindings={groups}
refetch={setOnCreateGroup}
serviceAccountId={serviceAccount.id}
serviceAccountId={serviceAccount?.id}
/>
)}
{view === View.CreateGroup && (
Expand Down
54 changes: 0 additions & 54 deletions www/src/components/cluster/ClusterUpgrades.tsx

This file was deleted.

Loading
Loading