Skip to content

Commit 819fc44

Browse files
committed
Implement federated gateway publisher UI
1 parent 3c2c369 commit 819fc44

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+2002
-1673
lines changed

portals/publisher/src/main/webapp/source/src/app/components/Apis/Apis.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
* under the License.
1717
*/
1818

19-
import React, { Suspense, lazy } from 'react';
19+
import React, { Suspense, lazy} from 'react';
2020
import { Route, Switch, Redirect } from 'react-router-dom';
2121
import Progress from 'AppComponents/Shared/Progress';
2222
import AuthManager from 'AppData/AuthManager';
@@ -73,7 +73,7 @@ const Apis = () => {
7373
}
7474
}}
7575
/>
76-
<Route path='/apis/:apiUUID/' render={(props) => <DeferredDetails {...props} isAPIProduct={false} />} />
76+
<Route path='/apis/:apiUUID/' render={(props) =><DeferredDetails {...props} isAPIProduct={false} />} />
7777
<Route
7878
path='/api-products/:apiProdUUID/'
7979
render={(props) => {

portals/publisher/src/main/webapp/source/src/app/components/Apis/Create/AIAPI/APICreateAIAPI.jsx

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import Typography from '@mui/material/Typography';
2121
import Box from '@mui/material/Box';
2222
import Grid from '@mui/material/Grid';
2323
import { FormattedMessage, useIntl } from 'react-intl';
24-
import { usePublisherSettings } from 'AppComponents/Shared/AppContext';
2524
import Stepper from '@mui/material/Stepper';
2625
import Step from '@mui/material/Step';
2726
import StepLabel from '@mui/material/StepLabel';
@@ -80,7 +79,6 @@ function apiInputsReducer(currentState, inputAction) {
8079
export default function ApiCreateAIAPI(props) {
8180
const [wizardStep, setWizardStep] = useState(0);
8281
const { history, multiGateway } = props;
83-
const { data: settings } = usePublisherSettings();
8482

8583
const [apiInputs, inputsDispatcher] = useReducer(apiInputsReducer, {
8684
type: 'ApiCreateAIAPI',
@@ -124,20 +122,12 @@ export default function ApiCreateAIAPI(props) {
124122
const {
125123
name, version, context, endpoint, gatewayType, policies = ["Unlimited"], inputValue, llmProviderId,
126124
} = apiInputs;
127-
let defaultGatewayType;
128-
if (settings && settings.gatewayTypes.length === 1 && settings.gatewayTypes.includes('Regular')) {
129-
defaultGatewayType = 'wso2/synapse';
130-
} else if (settings && settings.gatewayTypes.length === 1 && settings.gatewayTypes.includes('APK')) {
131-
defaultGatewayType = 'wso2/apk';
132-
} else {
133-
defaultGatewayType = 'default';
134-
}
135125

136126
const additionalProperties = {
137127
name,
138128
version,
139129
context,
140-
gatewayType: defaultGatewayType === 'default' ? gatewayType : defaultGatewayType,
130+
gatewayType,
141131
policies,
142132
subtypeConfiguration: {
143133
subtype: 'AIAPI',

portals/publisher/src/main/webapp/source/src/app/components/Apis/Create/APICreateRoutes.jsx

Lines changed: 68 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@
1515
* specific language governing permissions and limitations
1616
* under the License.
1717
*/
18-
import React, { useState, useEffect } from 'react';
18+
import React, { useEffect, useState } from 'react';
1919
import { styled } from '@mui/material/styles';
2020
import { Route, Switch } from 'react-router-dom';
2121
import ResourceNotFound from 'AppComponents/Base/Errors/ResourceNotFound';
2222
import { usePublisherSettings } from 'AppComponents/Shared/AppContext';
23+
import { Progress } from 'AppComponents/Shared';
2324
import APICreateDefault from './Default/APICreateDefault';
2425
import APIProductCreateWrapper from './APIProduct/APIProductCreateWrapper';
2526
import ApiCreateSwagger from './OpenAPI/ApiCreateOpenAPI';
@@ -42,6 +43,27 @@ const Root = styled('div')({
4243
},
4344
});
4445

46+
const gatewayDetsils = {
47+
'wso2/synapse': {
48+
value: 'wso2/synapse',
49+
name: 'Regular Gateway',
50+
description: 'API gateway embedded in APIM runtime. Connect directly to API Manager.',
51+
isNew: false
52+
},
53+
'wso2/apk': {
54+
value: 'wso2/apk',
55+
name: 'APK Gateway',
56+
description: 'Fast API gateway on Kubernetes. Manages and secures APIs.',
57+
isNew: false
58+
},
59+
'AWS': {
60+
value: 'AWS',
61+
name: 'AWS Gateway',
62+
description: 'API gateway offering from AWS cloud to secures APIs efficiently.',
63+
isNew: true
64+
}
65+
};
66+
4567
// Wrapper component to pass additional props
4668
const WithSomeValue = (Component, additionalProps) => (routeProps) => (
4769
<Component {...routeProps} {...additionalProps} />
@@ -54,41 +76,64 @@ const WithSomeValue = (Component, additionalProps) => (routeProps) => (
5476
* @returns @inheritdoc
5577
*/
5678
function APICreateRoutes() {
57-
const { data: settings } = usePublisherSettings();
58-
const [gateway, setGatewayType] = useState(false);
59-
60-
const getGatewayType = () => {
61-
if (settings != null) {
62-
if (settings.gatewayTypes && settings.gatewayTypes.length === 2 ) {
63-
setGatewayType(true);
64-
} else {
65-
setGatewayType(false);
66-
}
67-
}
68-
};
79+
const { data: publisherSettings, isLoading } = usePublisherSettings();
80+
const [apiTypes, setApiTypes] = useState(null);
81+
const [gatewayTypes, setGatewayTypes] = useState(null);
6982

7083
useEffect(() => {
71-
getGatewayType();
72-
}, [settings]);
84+
if (!isLoading) {
85+
setApiTypes(publisherSettings.gatewayFeatureCatalog.apiTypes);
86+
const data = publisherSettings.gatewayTypes;
87+
const updatedData = data.map(item => {
88+
if (item === "Regular") return "wso2/synapse";
89+
if (item === "APK") return "wso2/apk";
90+
return item;
91+
});
92+
setGatewayTypes(updatedData);
93+
}
94+
}, [isLoading]);
95+
96+
if (isLoading) {
97+
return <Progress per={80} message='Loading app settings ...' />;
98+
}
7399

74100
return (
75101
<Root className={classes.content}>
76102
<Switch>
77-
<Route path='/apis/create/rest' component={WithSomeValue(APICreateDefault, { multiGateway: gateway })}/>
103+
<Route path='/apis/create/rest' component={WithSomeValue(APICreateDefault,
104+
{ multiGateway: apiTypes?.rest
105+
.filter(t=>gatewayTypes.includes(t)).map(type => gatewayDetsils[type]) })}
106+
/>
78107
<Route path='/api-products/create' component={APIProductCreateWrapper} />
79108
<Route path='/apis/create/graphQL' component={WithSomeValue(ApiCreateGraphQL,
80-
{ multiGateway: gateway })}
109+
{ multiGateway: apiTypes?.graphql
110+
.filter(t=>gatewayTypes.includes(t)).map(type => gatewayDetsils[type]) })}
81111
/>
82112
<Route path='/apis/create/openapi' component={WithSomeValue(ApiCreateSwagger,
83-
{ multiGateway: gateway })}
113+
{ multiGateway: apiTypes?.rest
114+
.filter(t=>gatewayTypes.includes(t)).map(type => gatewayDetsils[type]) })}
115+
/>
116+
<Route path='/apis/create/wsdl' component={WithSomeValue(ApiCreateWSDL,
117+
{ multiGateway: apiTypes?.soap
118+
.filter(t=>gatewayTypes.includes(t)).map(type => gatewayDetsils[type]) })}
84119
/>
85-
<Route path='/apis/create/wsdl' component={ApiCreateWSDL} />
86120
{/* TODO: Remove ApiCreateWebSocket components and associated routes */}
87-
<Route path='/apis/create/ws' component={ApiCreateWebSocket} />
88-
<Route path='/apis/create/streamingapi/:apiType' component={APICreateStreamingAPI} />
89-
<Route path='/apis/create/asyncapi' component={APICreateAsyncAPI} />
121+
<Route path='/apis/create/ws' component={WithSomeValue(ApiCreateWebSocket,
122+
{ multiGateway: apiTypes?.ws
123+
.filter(t=>gatewayTypes.includes(t)).map(type => gatewayDetsils[type]) })}
124+
/>
125+
<Route path='/apis/create/streamingapi/:apiType' component={WithSomeValue(APICreateStreamingAPI,
126+
{ multiGateway: apiTypes?.ws
127+
.filter(t=>gatewayTypes.includes(t)).map(type => gatewayDetsils[type]) })}
128+
/>
129+
<Route path='/apis/create/asyncapi' component={WithSomeValue(APICreateAsyncAPI,
130+
{ multiGateway: apiTypes?.ws
131+
.filter(t=>gatewayTypes.includes(t)).map(type => gatewayDetsils[type]) })}
132+
/>
90133
<Route path='/apis/create/ai-api' component={WithSomeValue(ApiCreateAIAPI,
91-
{ multiGateway: gateway })}/>
134+
{ multiGateway: apiTypes?.ai
135+
.filter(t=>gatewayTypes.includes(t)).map(type => gatewayDetsils[type]) })}
136+
/>
92137
<Route component={ResourceNotFound} />
93138
</Switch>
94139
</Root>

portals/publisher/src/main/webapp/source/src/app/components/Apis/Create/AsyncAPI/ApiCreateAsyncAPI.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ const StyledAPICreateBase = styled(APICreateBase)((
8181
*/
8282
export default function ApiCreateAsyncAPI(props) {
8383
const [wizardStep, setWizardStep] = useState(0);
84-
const { history } = props;
84+
const { history, multiGateway } = props;
8585
// eslint-disable-next-line no-use-before-define
8686

8787
const [hideEndpoint, setHideEndpoint] = useState(true);
@@ -355,6 +355,7 @@ export default function ApiCreateAsyncAPI(props) {
355355
hideEndpoint={hideEndpoint}
356356
endpointPlaceholderText='Streaming Provider'
357357
appendChildrenBeforeEndpoint
358+
multiGateway={multiGateway}
358359
>
359360
<Grid container spacing={2}>
360361
{apiInputs.gatewayVendor === 'solace'

portals/publisher/src/main/webapp/source/src/app/components/Apis/Create/Components/DefaultAPIForm.jsx

Lines changed: 28 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { styled } from '@mui/material/styles';
2020
import PropTypes from 'prop-types';
2121
import TextField from '@mui/material/TextField';
2222
import Grid from '@mui/material/Grid';
23-
import { InputAdornment, IconButton, Icon } from '@mui/material';
23+
import { InputAdornment, IconButton, Icon, RadioGroup, FormControlLabel, Radio } from '@mui/material';
2424
import CircularProgress from '@mui/material/CircularProgress';
2525
import Chip from '@mui/material/Chip';
2626
import Typography from '@mui/material/Typography';
@@ -29,9 +29,6 @@ import APIValidation from 'AppData/APIValidation';
2929
import FormControl from '@mui/material/FormControl';
3030
import FormHelperText from '@mui/material/FormHelperText';
3131
import FormLabel from '@mui/material/FormLabel';
32-
import Radio from '@mui/material/Radio';
33-
import RadioGroup from '@mui/material/RadioGroup';
34-
import FormControlLabel from '@mui/material/FormControlLabel';
3532
import API from 'AppData/api';
3633
import { green } from '@mui/material/colors';
3734

@@ -655,7 +652,7 @@ export default function DefaultAPIForm(props) {
655652
}}
656653
/>
657654
)}
658-
{multiGateway &&
655+
{multiGateway && multiGateway.length > 1 &&
659656
<Grid container spacing={2}>
660657
<FormControl component='fieldset'>
661658
<FormLabel sx={{ marginLeft: '15px', marginTop: '20px' }}>
@@ -671,61 +668,30 @@ export default function DefaultAPIForm(props) {
671668
value={api.gatewayType}
672669
onChange={onChange}
673670
>
674-
<Grid item xs={6}>
675-
<FormControlLabel
676-
value='wso2/synapse'
677-
className={classes.radioOutline}
678-
control={<Radio />}
679-
label={(
680-
<div>
681-
<span>
682-
<FormattedMessage
683-
id={'Apis.Create.Components.DefaultAPIForm.'
684-
+ 'regular.gateway.type'}
685-
defaultMessage='Regular Gateway'
686-
/>
687-
</span>
688-
<Typography variant='body2' color='textSecondary'>
689-
<FormattedMessage
690-
id={'Apis.Create.Components.DefaultAPIForm.'
691-
+ 'regular.gateway.type.text'}
692-
defaultMessage={'API gateway embedded in APIM '
693-
+ 'runtime. Connect directly APIManager.'}
694-
/>
695-
</Typography>
696-
</div>
697-
)}
698-
sx={{ border: getBorderColor('wso2/synapse') }}
699-
/>
700-
</Grid>
701-
<Grid item xs={6}>
702-
<FormControlLabel
703-
value='wso2/apk'
704-
className={classes.radioOutline}
705-
control={<Radio />}
706-
label={(
707-
<div>
708-
<span>
709-
<FormattedMessage
710-
id={'Apis.Create.Components.DefaultAPIForm.'
711-
+ 'apk.gateway.type'}
712-
defaultMessage='APK Gateway'
713-
/>
714-
</span>
715-
<span className={`${classes.label} ${classes.newLabel}`}>New</span>
716-
<Typography variant='body2' color='textSecondary'>
717-
<FormattedMessage
718-
id={'Apis.Create.Components.DefaultAPIForm.'
719-
+ 'apk.gateway.type.text'}
720-
defaultMessage={'Fast API gateway running on kubernetes'
721-
+ ' designed to manage and secure APIs.'}
722-
/>
723-
</Typography>
724-
</div>
725-
)}
726-
sx={{ border: getBorderColor('wso2/apk') }}
727-
/>
728-
</Grid>
671+
{multiGateway.map((gateway) =>
672+
<Grid item xs={Math.floor(12 / multiGateway.length)} key={gateway.value} >
673+
<FormControlLabel
674+
value={gateway.value}
675+
className={classes.radioOutline}
676+
control={<Radio />}
677+
label={(
678+
<div>
679+
<span>
680+
{gateway.name}
681+
</span>
682+
{gateway.isNew && (
683+
<span className={`${classes.label}
684+
${classes.newLabel}`}>New</span>
685+
)}
686+
<Typography variant='body2' color='textSecondary'>
687+
{gateway.description}
688+
</Typography>
689+
</div>
690+
)}
691+
sx={{ border: getBorderColor(gateway.value) }}
692+
/>
693+
</Grid>
694+
)}
729695
</RadioGroup>
730696
<FormHelperText sx={{ marginLeft: '15px' }}><FormattedMessage
731697
id={'Apis.Create.Components.DefaultAPIForm.'
@@ -735,7 +701,7 @@ export default function DefaultAPIForm(props) {
735701
</FormHelperText>
736702
</FormControl>
737703
</Grid>
738-
}
704+
}
739705
{!appendChildrenBeforeEndpoint && !!children && children}
740706
</form>
741707
<Grid container direction='row' justifyContent='flex-end' alignItems='center'>
@@ -762,7 +728,7 @@ DefaultAPIForm.defaultProps = {
762728
};
763729
DefaultAPIForm.propTypes = {
764730
api: PropTypes.shape({}),
765-
multiGateway: PropTypes.string.isRequired,
731+
multiGateway: PropTypes.isRequired,
766732
isAPIProduct: PropTypes.shape({}).isRequired,
767733
isWebSocket: PropTypes.shape({}),
768734
onChange: PropTypes.func.isRequired,

0 commit comments

Comments
 (0)