Skip to content

Commit 1199271

Browse files
authored
feat(ecommerce): Add Cloud Provider Filters (#4649)
* ✨ Add Cloud Provider Filters * ♻️ Code review feedback * 🔧 Update `OpenAPI` SHA
1 parent 782325e commit 1199271

File tree

5 files changed

+152
-6
lines changed

5 files changed

+152
-6
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import {
2+
ComponentColor,
3+
DropdownMenuTheme,
4+
MultiSelectDropdown,
5+
} from '@influxdata/clockface'
6+
import React, {FC, useContext} from 'react'
7+
import {OperatorContext} from './context/operator'
8+
import {getRegions} from './utils'
9+
10+
const ResourcesCloudCluster: FC = () => {
11+
const {
12+
providerInfo,
13+
providers,
14+
regions,
15+
setProviders,
16+
setRegions,
17+
} = useContext(OperatorContext)
18+
19+
const hasSelectedProvider = providers.length > 0
20+
21+
const providerOptions = providerInfo.providers.map(p => p.provider)
22+
const regionOptions: string[] = providers
23+
.flatMap(p => getRegions(p, providerInfo.regions))
24+
.map(r => r.region)
25+
26+
const handleSelectProvider = (selectedOption: string): void => {
27+
setRegions([])
28+
providers.includes(selectedOption)
29+
? setProviders(prev =>
30+
prev.filter(provider => provider !== selectedOption)
31+
)
32+
: setProviders(prev => [selectedOption, ...prev])
33+
}
34+
35+
const handleSelectRegion = (selectedOption: string): void =>
36+
regions.includes(selectedOption)
37+
? setRegions(prev => prev.filter(region => region !== selectedOption))
38+
: setRegions(prev => [selectedOption, ...prev])
39+
40+
return (
41+
<>
42+
<MultiSelectDropdown
43+
style={providersStyle}
44+
options={providerOptions}
45+
selectedOptions={providers}
46+
onSelect={handleSelectProvider}
47+
menuTheme={DropdownMenuTheme.Onyx}
48+
emptyText="Cloud Provider"
49+
buttonColor={ComponentColor.Primary}
50+
/>
51+
{hasSelectedProvider && (
52+
<MultiSelectDropdown
53+
style={regionsStyle}
54+
options={regionOptions}
55+
selectedOptions={regions}
56+
onSelect={handleSelectRegion}
57+
menuTheme={DropdownMenuTheme.Onyx}
58+
emptyText="Cloud Region"
59+
buttonColor={ComponentColor.Primary}
60+
/>
61+
)}
62+
</>
63+
)
64+
}
65+
66+
const providersStyle = {width: '220px', marginRight: '10px'}
67+
const regionsStyle = {width: '220px', marginRight: '20px'}
68+
69+
export default ResourcesCloudCluster

src/operator/ResourcesTable.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@ import {OperatorRoutes} from 'src/operator/constants'
2929
// Types
3030
import {OperatorOrg, OperatorAccount} from 'src/types'
3131
import ResourcesAccountType from './ResourcesAccountType'
32+
import ResourcesCloudCluster from './ResourcesCloudCluster'
3233

3334
const ResourcesTable: FC = () => {
34-
const {pathname, accounts, organizations, status} = useContext(
35+
const {accounts, organizations, pathname, status} = useContext(
3536
OperatorContext
3637
)
3738

@@ -51,6 +52,7 @@ const ResourcesTable: FC = () => {
5152
<Tabs.TabContents>
5253
<FlexBox direction={FlexDirection.Row}>
5354
<ResourcesAccountType />
55+
{isOrgsTab && <ResourcesCloudCluster />}
5456
<ResourcesSearchbar />
5557
</FlexBox>
5658
<PageSpinner loading={status}>

src/operator/context/operator.tsx

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@ import {useLocation} from 'react-router-dom'
55

66
// Utils
77
import {notify} from 'src/shared/actions/notifications'
8-
import {getOperatorAccounts, getOperatorOrgs} from 'src/client/unityRoutes'
8+
import {
9+
getOperatorAccounts,
10+
getOperatorOrgs,
11+
getOperatorProviders,
12+
OperatorProvidersResponse,
13+
} from 'src/client/unityRoutes'
914
import {getAccountsError, getOrgsError} from 'src/shared/copy/notifications'
1015
import {getQuartzMe} from 'src/me/selectors'
1116

@@ -32,9 +37,17 @@ export interface OperatorContextType {
3237
) => void
3338
handleGetAccounts: () => void
3439
handleGetOrgs: () => void
40+
handleGetProviders: () => void
3541
organizations: OperatorOrg[]
3642
pathname: string
43+
providerInfo: OperatorProvidersResponse
3744
searchTerm: string
45+
providers: string[]
46+
setProviders: (
47+
providers: string[] | ((prevState: string[]) => string[])
48+
) => void
49+
regions: string[]
50+
setRegions: (regions: string[] | ((prevState: string[]) => string[])) => void
3851
setSearchTerm: (searchTerm?: string) => void
3952
status: RemoteDataState
4053
hasWritePermissions: boolean
@@ -46,9 +59,18 @@ export const DEFAULT_CONTEXT: OperatorContextType = {
4659
setAccountTypes: () => {},
4760
handleGetAccounts: () => {},
4861
handleGetOrgs: () => {},
62+
handleGetProviders: () => {},
4963
organizations: [],
5064
pathname: OperatorRoutes.default,
65+
providerInfo: {
66+
providers: [],
67+
regions: {},
68+
},
5169
searchTerm: '',
70+
providers: [],
71+
setProviders: () => {},
72+
regions: [],
73+
setRegions: () => {},
5274
setSearchTerm: () => {},
5375
status: RemoteDataState.NotStarted,
5476
hasWritePermissions: false,
@@ -64,6 +86,11 @@ export const OperatorProvider: FC<Props> = React.memo(({children}) => {
6486
const [orgsStatus, setOrgsStatus] = useState(RemoteDataState.NotStarted)
6587
const [searchTerm, setSearchTerm] = useState('')
6688
const [accountTypes, setAccountTypes] = useState<AccountType[]>([])
89+
const [providers, setProviders] = useState<string[]>([])
90+
const [regions, setRegions] = useState<string[]>([])
91+
const [providerInfo, setProviderInfo] = useState<OperatorProvidersResponse>(
92+
DEFAULT_CONTEXT.providerInfo
93+
)
6794
const dispatch = useDispatch()
6895
const quartzMe = useSelector(getQuartzMe)
6996

@@ -96,7 +123,12 @@ export const OperatorProvider: FC<Props> = React.memo(({children}) => {
96123
try {
97124
setOrgsStatus(RemoteDataState.Loading)
98125
const resp = await getOperatorOrgs({
99-
query: {query: searchTerm, accountTypes},
126+
query: {
127+
query: searchTerm,
128+
accountTypes,
129+
providers,
130+
regions,
131+
},
100132
})
101133

102134
if (resp.status !== 200) {
@@ -110,7 +142,21 @@ export const OperatorProvider: FC<Props> = React.memo(({children}) => {
110142
setOrgsStatus(RemoteDataState.Error)
111143
dispatch(notify(getOrgsError()))
112144
}
113-
}, [accountTypes, searchTerm, dispatch])
145+
}, [accountTypes, searchTerm, providers, regions, dispatch])
146+
147+
const handleGetProviders = useCallback(async () => {
148+
try {
149+
const resp = await getOperatorProviders({})
150+
151+
if (resp.status !== 200) {
152+
throw new Error(resp.data.message)
153+
}
154+
155+
setProviderInfo(resp.data)
156+
} catch (error) {
157+
console.error({error})
158+
}
159+
}, [])
114160

115161
const {pathname} = useLocation()
116162

@@ -123,12 +169,13 @@ export const OperatorProvider: FC<Props> = React.memo(({children}) => {
123169
handleGetAccounts()
124170
break
125171
case OperatorRoutes.organizations:
172+
handleGetProviders()
126173
handleGetOrgs()
127174
break
128175
default:
129176
return
130177
}
131-
}, [pathname, handleGetAccounts, handleGetOrgs])
178+
}, [pathname, handleGetAccounts, handleGetOrgs, handleGetProviders])
132179

133180
let status = RemoteDataState.Done
134181

@@ -153,10 +200,16 @@ export const OperatorProvider: FC<Props> = React.memo(({children}) => {
153200
setAccountTypes,
154201
handleGetAccounts,
155202
handleGetOrgs,
203+
handleGetProviders,
156204
organizations,
157205
pathname,
206+
providerInfo,
158207
searchTerm,
159208
setSearchTerm,
209+
providers,
210+
setProviders,
211+
regions,
212+
setRegions,
160213
status,
161214
hasWritePermissions,
162215
}}

src/operator/utils.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
} from 'src/billing/utils/timeHelpers'
77

88
// Types
9-
import {OperatorOrgLimits} from 'src/types'
9+
import {OperatorOrgLimits, OperatorRegions} from 'src/types'
1010

1111
const updateMaxRetentionWithCallback = (
1212
limits: OperatorOrgLimits,
@@ -43,3 +43,23 @@ export const fromDisplayLimits = (
4343
const newLimits = updateMaxRetentionWithCallback(displayLimits, hoursToNs)
4444
return updateQueryTimeWithCallback(newLimits, secondsToNs)
4545
}
46+
47+
export const getRegions = (
48+
provider: string,
49+
regions: {
50+
Azure?: OperatorRegions
51+
AWS?: OperatorRegions
52+
GCP?: OperatorRegions
53+
}
54+
) => {
55+
switch (provider) {
56+
case 'Azure':
57+
return regions.Azure
58+
case 'AWS':
59+
return regions.AWS
60+
case 'GCP':
61+
return regions.GCP
62+
default:
63+
return []
64+
}
65+
}

src/types/operator.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ export {
44
OperatorOrgLimits,
55
OperatorOrganization as OperatorOrg,
66
OperatorOrganizations as OperatorOrgs,
7+
OperatorProviders,
8+
OperatorRegions,
79
OrgLimits,
810
User as OperatorUser,
911
} from 'src/client/unityRoutes'

0 commit comments

Comments
 (0)