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

SM UI #711

Merged
merged 25 commits into from
Jun 12, 2024
Merged

SM UI #711

Show file tree
Hide file tree
Changes from all 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
17 changes: 12 additions & 5 deletions internal/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func (a *API) Start() {
mux.HandleFunc("GET /api/service-instance/{id}", a.GetServiceInstance)
mux.HandleFunc("GET /api/service-offerings/{namespace}/{name}", a.ListServiceOfferings)
mux.HandleFunc("GET /api/service-offering/{id}", a.GetServiceOffering)

go func() {
err := http.ListenAndServe(":3006", mux)
if err != nil {
Expand All @@ -44,6 +45,17 @@ func (a *API) CreateServiceInstance(writer http.ResponseWriter, request *http.Re
return
}

func (a *API) GetServiceOffering(writer http.ResponseWriter, request *http.Request) {
a.setupCors(writer, request)
id := request.PathValue("id")
details, err := a.serviceManager.ServiceOfferingDetails(id)
if returnError(writer, err) {
return
}
response, err := json.Marshal(vm.ToServiceOfferingDetailsVM(details))
returnResponse(writer, response, err)
}

func (a *API) ListServiceOfferings(writer http.ResponseWriter, request *http.Request) {
a.setupCors(writer, request)
namespace := request.PathValue("namespace")
Expand Down Expand Up @@ -75,11 +87,6 @@ func (a *API) GetServiceInstance(writer http.ResponseWriter, request *http.Reque
// not implemented in SM
}

func (a *API) GetServiceOffering(writer http.ResponseWriter, request *http.Request) {
a.setupCors(writer, request)
// not implemented in SM
}

func (a *API) ListServiceInstances(writer http.ResponseWriter, request *http.Request) {
a.setupCors(writer, request)
// will be taken from SM
Expand Down
21 changes: 21 additions & 0 deletions internal/api/vm/converters.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,24 @@ func ToServiceOfferingsVM(offerings *types.ServiceOfferings) ServiceOfferings {
}
return serviceOfferings
}

func ToServiceOfferingDetailsVM(serviceOfferings *types.ServiceOfferingDetails) ServiceOfferingDetails {
details := ServiceOfferingDetails{
Plans: []ServiceOfferingPlan{},
}

for _, plan := range serviceOfferings.ServicePlans.ServicePlans {
details.LongDescription, _ = serviceOfferings.MetadataValueByFieldName(types.ServiceOfferingLongDescription)
supportUrl, _ := serviceOfferings.MetadataValueByFieldName(types.ServiceOfferingSupportURL)
documentationUrl, _ := serviceOfferings.MetadataValueByFieldName(types.ServiceOfferingDocumentationUrl)
planReturn := ServiceOfferingPlan{
Name: plan.Name,
Description: plan.Description,
DocumentationUrl: documentationUrl,
SupportUrl: supportUrl,
}
details.Plans = append(details.Plans, planReturn)
}

return details
}
12 changes: 12 additions & 0 deletions internal/api/vm/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,15 @@ type ServiceInstance struct {
Name string `json:"name"`
Namespace string `json:"namespace"`
}

type ServiceOfferingDetails struct {
LongDescription string `json:"longDescription"`
Plans []ServiceOfferingPlan `json:"plans"`
}

type ServiceOfferingPlan struct {
Name string `json:"name"`
Description string `json:"description"`
DocumentationUrl string `json:"documentationUrl"`
SupportUrl string `json:"supportUrl"`
}
2 changes: 1 addition & 1 deletion ui/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,5 @@ html {

body {
margin: 0px auto;
width: 50vw;
width: 100vw;
}
125 changes: 73 additions & 52 deletions ui/src/components/SecretsView.tsx
Original file line number Diff line number Diff line change
@@ -1,70 +1,91 @@
import * as ui5 from "@ui5/webcomponents-react";
import axios from "axios";
import { useEffect, useState } from "react";
import { Secrets } from "../shared/models";
import {useEffect, useState} from "react";
import {Secrets} from "../shared/models";
import Ok from "../shared/validator";
import api from "../shared/api";
import ServiceOfferingsView from "./ServiceOfferingsView";

function SecretsView(props: any) {
const [secrets, setSecrets] = useState<Secrets>();
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [secrets, setSecrets] = useState<Secrets>();
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

useEffect(() => {
axios
.get<Secrets>(api("secrets"))
.then((response) => {
setSecrets(response.data);
useEffect(() => {
setLoading(true);
axios
.get<Secrets>(api("secrets"))
.then((response) => {
setLoading(false);
setSecrets(response.data);
if (Ok(response.data) && Ok(response.data.items)) {
const secret = formatSecretText(response.data.items[0].name, response.data.items[0].namespace)
props.handler(secret);
props.setPageContent(<ServiceOfferingsView secret={secret} />);
} else {
props.handler(formatSecretText("", ""));
}
})
.catch((error) => {
setLoading(false);
setError(error);
setSecrets(undefined);
props.handler(formatSecretText("", ""));
});
setLoading(false);
props.handler(
formatDisplay(
response.data.items[0].name,
response.data.items[0].namespace
)
);
})
.catch((error) => {
setError(error);
setLoading(false);
});
}, []);
}, []);

if (loading) {
return <ui5.Loader progress="60%" />
}
if (loading) {
return <ui5.Loader progress="100%"/>
}

if (error) {
return <ui5.Text>Error: {error}</ui5.Text>;
}
if (error) {
props.handler(formatSecretText("", ""));
return <ui5.IllustratedMessage name="UnableToLoad" />
}

const renderData = () => {
return secrets?.items.map((s, i) => {
return (
<ui5.Option key={i}>{formatDisplay(s.name, s.namespace)}</ui5.Option>
);
});
};
const renderData = () => {
// @ts-ignore
if (!Ok(secrets) || !Ok(secrets.items)){
return <div>
<>
<ui5.Option key={0}>{formatSecretText("", "")}</ui5.Option>
</>
</div>
}
return secrets?.items.map((secret, index) => {
return (
<ui5.Option key={index}>{formatSecretText(secret.name, secret.namespace)}</ui5.Option>
);
});
};

return (
<div>
<>
return (
<div>
<ui5.Select
style={{ width: "20vw" }}
onChange={(e) => {
// @ts-ignore
props.handler(e.target.value);
}}
>
{renderData()}
</ui5.Select>
<>
<div>
<ui5.Select
style={{width: "20vw"}}
onChange={(e) => {
// @ts-ignore
const secret = e .target.value;
props.handler(secret);
props.setPageContent(<ServiceOfferingsView secret={secret} />);
}}
>
{renderData()}
</ui5.Select>
</div>
</>
</div>
</>
</div>
);
);
}

function formatDisplay(secretName: string, secretNamespace: string) {
return `${secretName} in (${secretNamespace})`;
function formatSecretText(secretName: string, secretNamespace: string) {
if (secretName === "" || secretNamespace === "") {
return "No secret found"
}
return `${secretName} in (${secretNamespace})`;
}

export default SecretsView;
29 changes: 12 additions & 17 deletions ui/src/components/ServiceInstancesView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import axios from "axios";
import { useEffect, useState, useRef } from "react";
import { createPortal } from "react-dom";
import api from "../shared/api";
import Ok from "../shared/validator";

function ServiceInstancesView() {
const [serviceInstances, setServiceInstances] = useState<ServiceInstances>();
Expand All @@ -24,24 +25,29 @@ function ServiceInstancesView() {
axios
.get<ServiceInstances>(api("service-instances"))
.then((response) => {
setServiceInstances(response.data);
setLoading(false);
setLoading(false);
setServiceInstances(response.data);
})
.catch((error) => {
setError(error);
setLoading(false);
setLoading(false);
setError(error);
});
setLoading(false)
}, []);

if (loading) {
return <ui5.Loader progress="60%" />
return <ui5.Loader progress="100%" />
}

if (error) {
return <ui5.Text>Error: {error}</ui5.Text>;
return <ui5.IllustratedMessage name="UnableToLoad" />
}

const renderData = () => {
// @ts-ignore
if (!Ok(serviceInstances) || !Ok(serviceInstances.items)) {
return <ui5.IllustratedMessage name="NoEntries" />
}
return serviceInstances?.items.map((brief, index) => {
return (
<>
Expand Down Expand Up @@ -69,10 +75,6 @@ function ServiceInstancesView() {
</>
}
onClick={handleOpen}
onLoadMore={function _a() {}}
onPopinChange={function _a() {}}
onRowClick={function _a() { }}
onSelectionChange={function _a() {}}
>
{renderData()}
</ui5.Table>
Expand All @@ -96,15 +98,8 @@ function ServiceInstancesView() {
</ui5.Bar>
}
headerText="Dialog Header"
onAfterClose={function _a() {}}
onAfterOpen={function _a() {}}
onBeforeClose={function _a() {}}
onBeforeOpen={function _a() {}}
>
<ui5.List>
<ui5.StandardListItem additionalText="3">
List Item 1
</ui5.StandardListItem>
</ui5.List>
</ui5.Dialog>,
document.body
Expand Down
Loading
Loading