Skip to content

Commit

Permalink
Page Title (#817)
Browse files Browse the repository at this point in the history
* Setting Page Title from Within Route Component

Added title attribute to Layout component to show information about which view is currently active.

* Removing Unnecessary Imports

* CSS Update for Object Page

Forced display property to be set to inline instead of grid to allow title `block` placement before the `Secrets` view.

Added a 1rem padding to put some space between the title and the top of an ObjectPage.
  • Loading branch information
ralikio authored and kyma-gopher-bot committed Aug 22, 2024
1 parent 6bf830a commit 69e9798
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 57 deletions.
9 changes: 5 additions & 4 deletions ui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,19 @@ import Layout from './components/Layout';
function App() {

const [secret, setSecret] = React.useState("");
const [title, setTitle] = React.useState("");

return (
<div id="App" className="App html-wrap flex-container flex-column">
<BrowserRouter basename='/' >
<Routes>
<Route path="/" element={<Layout onSecretChanged={(s: string) => setSecret(s)} />}>
<Route path="/" element={<Layout title={title} onSecretChanged={(s: string) => setSecret(s)} /> }>
<Route index element={<Navigate to="offerings" replace />} />
<Route path="*" element={<Navigate to="offerings" replace />} />

<Route path="/instances" element={<ServiceInstancesView secret={secret} />} />
<Route path="/instances/:id" element={<ServiceInstancesView secret={secret} />} />
<Route path="/offerings" element={<ServiceOfferingsView secret={secret} />} />
<Route path="/instances" element={<ServiceInstancesView setTitle={(title: string) => setTitle(title)} secret={secret} />} />
<Route path="/instances/:id" element={<ServiceInstancesView setTitle={(title: string) => setTitle(title)} secret={secret} />} />
<Route path="/offerings" element={<ServiceOfferingsView setTitle={(title: string) => setTitle(title)} secret={secret} />} />
</Route>
</Routes>
</BrowserRouter>
Expand Down
19 changes: 8 additions & 11 deletions ui/src/components/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import * as ui5 from "@ui5/webcomponents-react";
import Secrets from "./SecretsView";
import { matchPath, Outlet, useLocation } from "react-router-dom";
import { useNavigate } from "react-router-dom";
import { ObjectPage } from "@ui5/webcomponents-react";
import { ObjectPage, Title } from "@ui5/webcomponents-react";


function Layout({ onSecretChanged }: { onSecretChanged: (secret: string) => void }) {
function Layout({ onSecretChanged, title }: { onSecretChanged: (secret: string) => void, title: string }) {
const navigate = useNavigate();
const location = useLocation();
return (
Expand All @@ -22,9 +22,6 @@ function Layout({ onSecretChanged }: { onSecretChanged: (secret: string) => void
</ui5.ShellBar>
</div>




<div className="flex-container flex-row">
<>
<div className="margin-wrapper">
Expand Down Expand Up @@ -61,15 +58,15 @@ function Layout({ onSecretChanged }: { onSecretChanged: (secret: string) => void
</div>

<div className="margin-wrapper main-column">



<ObjectPage className="scrollable flex-column"
headerTitle={
<Secrets onSecretChanged={(secret: string) => onSecretChanged(secret)} />
}
headerTitle={
<>
<Title level="H2">{title}</Title>
<Secrets onSecretChanged={(secret: string) => onSecretChanged(secret)} />
</>
}
>

<Outlet />
</ObjectPage>
</div>
Expand Down
6 changes: 6 additions & 0 deletions ui/src/components/ServiceInstancesView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,14 @@ function ServiceInstancesView(props: any) {
let { id } = useParams();

useEffect(() => {
if (!Ok(props.setTitle)) {
return;
}
props.setTitle("Service Instances");

var useTestData = process.env.REACT_APP_USE_TEST_DATA === "true"
if (!useTestData) {

if (!Ok(props.secret)) {
return;
}
Expand Down
89 changes: 47 additions & 42 deletions ui/src/components/ServiceOfferingsView.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import * as ui5 from "@ui5/webcomponents-react";
import {useEffect, useState} from "react";
import { useEffect, useState } from "react";
import axios from "axios";
import {ServiceOfferings} from "../shared/models";
import { ServiceOfferings } from "../shared/models";
import api from "../shared/api";
import "@ui5/webcomponents-icons/dist/AllIcons.js"
import "@ui5/webcomponents-fiori/dist/illustrations/NoEntries.js"
import "@ui5/webcomponents-fiori/dist/illustrations/AllIllustrations.js"
import "@ui5/webcomponents-fiori/dist/illustrations/NoData.js";
import Ok from "../shared/validator";
import {createPortal} from "react-dom";
import { createPortal } from "react-dom";
import ServiceOfferingsDetailsView from "./ServiceOfferingsDetailsView";
import { ResponsiveGridLayout } from "@ui5/webcomponents-react";

Expand All @@ -18,8 +18,13 @@ function ServiceOfferingsView(props: any) {
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [portal, setPortal] = useState<JSX.Element>();

useEffect(() => {
if (!Ok(props.setTitle)) {
return;
}
props.setTitle("Service Offerings");

if (!Ok(props.secret)) {
return;
}
Expand Down Expand Up @@ -50,64 +55,64 @@ function ServiceOfferingsView(props: any) {
}
return b64;
}

const renderData = () => {
if (loading) {
return <ui5.BusyIndicator
active
delay={1000}
size="Medium"
/>
active
delay={1000}
size="Medium"
/>
}

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

// @ts-ignore
if (!Ok(offerings) || !Ok(offerings.items)) {
return <ui5.IllustratedMessage name="NoEntries"/>
return <ui5.IllustratedMessage name="NoEntries" />
}
const cards = offerings?.items.map((offering, index) => {
// @ts-ignore
return (
<ui5.Card
key={index}
onClick={() => {
setPortal(createPortal( <ServiceOfferingsDetailsView offering={offering} />, document.getElementById("App")!!, window.crypto.randomUUID()))
}}
header={
<ui5.CardHeader
avatar={
<ui5.Avatar>
<img alt="" src={getImg(offering.metadata.imageUrl)}></img>
</ui5.Avatar>
}
subtitleText={offering.catalog_name}
titleText={offering.metadata.displayName}
status={formatStatus(index, offerings?.numItems)}
interactive
/>
}
>
</ui5.Card>
<ui5.Card
key={index}
onClick={() => {
setPortal(createPortal(<ServiceOfferingsDetailsView offering={offering} />, document.getElementById("App")!!, window.crypto.randomUUID()))
}}
header={
<ui5.CardHeader
avatar={
<ui5.Avatar>
<img alt="" src={getImg(offering.metadata.imageUrl)}></img>
</ui5.Avatar>
}
subtitleText={offering.catalog_name}
titleText={offering.metadata.displayName}
status={formatStatus(index, offerings?.numItems)}
interactive
/>
}
>
</ui5.Card>
);
});

return <>

<div className="margin-wrapper">

<ResponsiveGridLayout
columnsXL={3}
columnsL={2}
columnsM={1}
columnsS={1}
>
{/* <React.Fragment key=".0"> */}
{cards}
{/* </React.Fragment> */}
</ResponsiveGridLayout>
<ResponsiveGridLayout
columnsXL={3}
columnsL={2}
columnsM={1}
columnsS={1}
>
{/* <React.Fragment key=".0"> */}
{cards}
{/* </React.Fragment> */}
</ResponsiveGridLayout>
</div>
{portal != null && portal}
</>
Expand All @@ -124,7 +129,7 @@ function splitSecret(secret: string) {
const secret_name = secretParts[0];
let namespace = secretParts[2].replace("(", "");
namespace = namespace.replace(")", "");
return {secret_name, namespace};
return { secret_name, namespace };
}

function formatStatus(i: number, j: number) {
Expand Down
6 changes: 6 additions & 0 deletions ui/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,10 @@ ui5-select {
/* corrected margins on object page */
div[data-component-name="ObjectPage"] {
border-radius: 0.5em;
}

/* corrected margins on object page */
header[data-component-name="ObjectPageTopHeader"] {
padding-top: 1rem;
display: inline !important;
}

0 comments on commit 69e9798

Please sign in to comment.