diff --git a/otoroshi/app/next/models/Api.scala b/otoroshi/app/next/models/Api.scala index a703f9cd7..daa6b080f 100644 --- a/otoroshi/app/next/models/Api.scala +++ b/otoroshi/app/next/models/Api.scala @@ -297,7 +297,7 @@ case class ApiConsumer( name: String, description: Option[String], autoValidation: Boolean, - kind: ApiConsumerKind, + consumerKind: ApiConsumerKind, settings: ApiConsumerSettings, status: ApiConsumerStatus, subscriptions: Seq[ApiConsumerSubscriptionRef] @@ -311,13 +311,13 @@ object ApiConsumer { name = json.select("name").asString, description = json.select("description").asOptString, autoValidation = json.select("autoValidation").asOpt[Boolean].getOrElse(false), - kind = json.select("kind").asString.toLowerCase match { + consumerKind = json.select("consumer_kind").asOptString.map(_.toLowerCase match { case "apikey" => ApiConsumerKind.Apikey case "mtls" => ApiConsumerKind.Mtls case "keyless" => ApiConsumerKind.Keyless case "oauth2" => ApiConsumerKind.OAuth2 case "jwt" => ApiConsumerKind.JWT - }, + }).getOrElse(ApiConsumerKind.Apikey), settings = (json \ "settings" \ "name").asString match { case "apikey" => { ApiConsumerSettings.Apikey( @@ -362,7 +362,7 @@ object ApiConsumer { "name" -> o.name, "description" -> o.description, "autoValidation" -> o.autoValidation, - "kind" -> o.kind.name, + "consumer_kind" -> o.consumerKind.name, "settings" -> o.settings.json, "status" -> o.status.name, "subscriptions" -> o.subscriptions.map(_.ref) diff --git a/otoroshi/javascript/src/pages/ApiEditor/index.js b/otoroshi/javascript/src/pages/ApiEditor/index.js index 190c7e34e..ab2c3f3c4 100644 --- a/otoroshi/javascript/src/pages/ApiEditor/index.js +++ b/otoroshi/javascript/src/pages/ApiEditor/index.js @@ -409,7 +409,7 @@ function Consumers(props) { fetchTemplate={() => Promise.resolve({ id: v4(), name: "New consumer", - kind: "apikey", + consumer_kind: "apikey", config: {} })} fetchItems={() => Promise.resolve(rawAPI.data?.consumers || [])} @@ -443,8 +443,8 @@ const TEMPLATES = { monthlyQuota: 1000 } }, - cert: { - name: 'cert', + mtls: { + name: 'mtls', config: {} }, keyless: { @@ -488,7 +488,7 @@ function NewConsumer(props) { const [consumer, setConsumer] = useState({ id: v4(), name: "New consumer", - kind: "apikey", + consumer_kind: "apikey", settings: TEMPLATES.apikey, status: "staging", subscriptions: [] @@ -499,7 +499,7 @@ function NewConsumer(props) { type: 'string', label: 'Name' }, - kind: { + consumer_kind: { renderer: props => { return
@@ -510,14 +510,14 @@ function NewConsumer(props) { props.rootOnChange({ ...props.rootValue, settings: TEMPLATES[newType], - kind: newType + consumer_kind: newType }) }} label="Plan Type" ngOptions={{ spread: true }} margin={0} style={{ flex: 1 }} - options={['apikey', 'cert', 'keyless', 'oauth2', 'jwt']} + options={['apikey', 'mtls', 'keyless', 'oauth2', 'jwt']} />
@@ -539,7 +539,7 @@ function NewConsumer(props) { ...rawAPI.data, consumers: [...rawAPI.data.consumers, consumer] }) - .then(() => history.push(`/apis/${params.apiId}/consumers`)) + .then(() => history.push(`/apis/${params.apiId}`)) } return @@ -576,7 +576,7 @@ function ConsumerDesigner(props) { type: 'string', label: 'Name' }, - kind: { + consumer_kind: { renderer: props => { return
@@ -587,14 +587,14 @@ function ConsumerDesigner(props) { props.rootOnChange({ ...props.rootValue, settings: TEMPLATES[newType], - kind: newType + consumer_kind: newType }) }} label="Plan Type" ngOptions={{ spread: true }} margin={0} style={{ flex: 1 }} - options={['apikey', 'cert', 'keyless', 'oauth2', 'jwt']} + options={['apikey', 'mtls', 'keyless', 'oauth2', 'jwt']} />
@@ -1318,6 +1318,8 @@ function Dashboard(props) { useEffect(() => { props.setTitle("Dashboard") + + return () => props.setTitle(undefined) }, []) const rawAPI = useQuery(["getAPI", params.apiId], @@ -1328,13 +1330,57 @@ function Dashboard(props) { const api = rawAPI.data + const hasCreateFlow = api && api.flows.length > 0 + const hasCreateRoute = api && api.routes.length > 0 + const hasCreateConsumer = api && api.consumers.length > 0 + return
{api &&
-
+
+ + + + {hasCreateFlow && hasCreateRoute && !hasCreateConsumer && + allows users or machines to subscribe to your API + } + button={ { }} + text="Create" />} + />} + + {hasCreateFlow && !hasCreateRoute && + Compose your API with your first + } + button={ { }} + text="Create" />} + />} + + {!hasCreateFlow && + Create flows of plufins to apply rules, transformations, and restrictions on routes, enabling advanced traffic control and customization. + } + button={ { }} + text="Create" />} + />} + + {!api.health &&

API Health will appear here

}
- {api.consumers.length === 0 && - + {hasCreateConsumer && + c.subscriptions).length <= 0 ? 'Souscriptions will appear here' : ''} /> - - allows users or machines to subscribe to your API - } - button={ { }} - text="Create" />} - /> + } - - - - + {hasCreateConsumer && + } /> + + + }
- + {api.flows.length > 0 && api.routes.length > 0 && - + }
}
} +function ApiConsumersView({ api }) { + return
+
+
Name
+
Description
+
Status
+
Kind
+
+ {api.consumers.map(consumer => { + return + })} +
+} + +function Consumer({ consumer }) { + const history = useHistory() + const params = useParams() + const [open, setOpen] = useState(false) + + return
setOpen(!open)}> + {open &&
+
} + {!open && <> +
{consumer.name}
+
{consumer.description}
+
{consumer.status}
+
{consumer.consumer_kind}
+ + } +
+} + function SubscriptionsView({ api }) { const [subscriptions, setSubscriptions] = useState([]) @@ -1411,7 +1507,7 @@ function SubscriptionsView({ api }) { } function Subscription({ subscription }) { - const [open, setOpened] = useState(false) + const [open, setOpen] = useState(false) return
setOpened(!open)}> + onClick={() => setOpen(!open)}> {open && <> + value={JSON.stringify(subscription, null, 2)} /> } {!open && <>
{subscription.name}
{subscription.description}
{moment(new Date(subscription.dates.created_at)).format('DD/MM/YY hh:mm')}
-
{subscription.subscription_kind}
+
{subscription.subscription_kind}
}
} function ContainerBlock({ children, full, highlighted }) { - return
+ return
{children}
} @@ -1485,10 +1582,13 @@ function APIState({ value }) { return null } -function SectionHeader({ text, description, main }) { +function SectionHeader({ text, description, main, actions }) { return
- {main ?

{text}

: -

{text}

} +
+ {main ?

{text}

: +

{text}

} + {actions} +

{description}

} @@ -1500,7 +1600,7 @@ function Entities({ children }) { } function Card({ title, description, to, button }) { - return + return
{title}