Skip to content

Commit

Permalink
fix: ui uses relative base path. in case /ui/ is found in the current…
Browse files Browse the repository at this point in the history
… page url, all urls and api routes use the found prefix from the path. If /ui/ is not found, fall back to / as the base path. Fixes #317 Fixes IAM-911 Fixes WD-12306

Signed-off-by: David Edler <[email protected]>
  • Loading branch information
edlerd committed Jun 21, 2024
1 parent e857604 commit 709399c
Show file tree
Hide file tree
Showing 16 changed files with 93 additions and 53 deletions.
2 changes: 1 addition & 1 deletion ui/entrypoint
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#! /usr/bin/env bash
set -e

echo "Listening on http://localhost:8411"
echo "Listening on http://localhost:8411/ui/"

haproxy -f haproxy.cfg -db
19 changes: 10 additions & 9 deletions ui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import SchemaList from "pages/schemas/SchemaList";
import Navigation from "components/Navigation";
import Panels from "components/Panels";
import useLocalStorage from "util/useLocalStorage";
import { apiBasePath, basePath } from "util/basePaths";

const App: FC = () => {
// Store a user token that will be passed to the API using the
Expand All @@ -33,24 +34,24 @@ const App: FC = () => {
<Suspense fallback={<Loader />}>
<Routes>
<Route
path="/"
path={basePath}
element={
<Login isAuthenticated={!!authUser} setAuthUser={setAuthUser} />
}
>
<Route
path="/"
element={<Navigate to="/provider" replace={true} />}
path={basePath}
element={<Navigate to={`${basePath}provider`} replace={true} />}
/>
<Route path="/provider" element={<ProviderList />} />
<Route path="/client" element={<ClientList />} />
<Route path="/identity" element={<IdentityList />} />
<Route path="/schema" element={<SchemaList />} />
<Route path={`${basePath}provider`} element={<ProviderList />} />
<Route path={`${basePath}client`} element={<ClientList />} />
<Route path={`${basePath}identity`} element={<IdentityList />} />
<Route path={`${basePath}schema`} element={<SchemaList />} />
<Route
path="/*"
path={basePath + "*"}
element={
<ReBACAdmin
apiURL={import.meta.env.VITE_API_URL}
apiURL={apiBasePath}
asidePanelId="rebac-admin-panel"
authToken={authUser?.token}
/>
Expand Down
13 changes: 6 additions & 7 deletions ui/src/api/client.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { Client } from "types/client";
import { ApiResponse, PaginatedResponse } from "types/api";
import { handleResponse, PAGE_SIZE } from "util/api";
import { apiBasePath } from "util/basePaths";

export const fetchClients = (
pageToken: string,
): Promise<PaginatedResponse<Client[]>> => {
return new Promise((resolve, reject) => {
fetch(
`${import.meta.env.VITE_API_URL}/clients?page_token=${pageToken}&size=${PAGE_SIZE}`,
)
fetch(`${apiBasePath}clients?page_token=${pageToken}&size=${PAGE_SIZE}`)
.then(handleResponse)
.then((result: PaginatedResponse<Client[]>) => resolve(result))
.catch(reject);
Expand All @@ -17,7 +16,7 @@ export const fetchClients = (

export const fetchClient = (clientId: string): Promise<Client> => {
return new Promise((resolve, reject) => {
fetch(`${import.meta.env.VITE_API_URL}/clients/${clientId}`)
fetch(`${apiBasePath}clients/${clientId}`)
.then(handleResponse)
.then((result: ApiResponse<Client>) => resolve(result.data))
.catch(reject);
Expand All @@ -26,7 +25,7 @@ export const fetchClient = (clientId: string): Promise<Client> => {

export const createClient = (values: string): Promise<Client> => {
return new Promise((resolve, reject) => {
fetch(`${import.meta.env.VITE_API_URL}/clients`, {
fetch(`${apiBasePath}clients`, {
method: "POST",
body: values,
})
Expand All @@ -41,7 +40,7 @@ export const updateClient = (
values: string,
): Promise<Client> => {
return new Promise((resolve, reject) => {
fetch(`${import.meta.env.VITE_API_URL}/clients/${clientId}`, {
fetch(`${apiBasePath}clients/${clientId}`, {
method: "PUT",
body: values,
})
Expand All @@ -53,7 +52,7 @@ export const updateClient = (

export const deleteClient = (client: string) => {
return new Promise((resolve, reject) => {
fetch(`${import.meta.env.VITE_API_URL}/clients/${client}`, {
fetch(`${apiBasePath}clients/${client}`, {
method: "DELETE",
})
.then(resolve)
Expand Down
11 changes: 6 additions & 5 deletions ui/src/api/identities.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { ApiResponse, PaginatedResponse } from "types/api";
import { handleResponse, PAGE_SIZE } from "util/api";
import { Identity } from "types/identity";
import { apiBasePath } from "util/basePaths";

export const fetchIdentities = (
pageToken: string,
): Promise<PaginatedResponse<Identity[]>> => {
return new Promise((resolve, reject) => {
fetch(`/api/v0/identities?page_token=${pageToken}&size=${PAGE_SIZE}`)
fetch(`${apiBasePath}identities?page_token=${pageToken}&size=${PAGE_SIZE}`)
.then(handleResponse)
.then((result: PaginatedResponse<Identity[]>) => resolve(result))
.catch(reject);
Expand All @@ -15,7 +16,7 @@ export const fetchIdentities = (

export const fetchIdentity = (identityId: string): Promise<Identity> => {
return new Promise((resolve, reject) => {
fetch(`/api/v0/identities/${identityId}`)
fetch(`${apiBasePath}identities/${identityId}`)
.then(handleResponse)
.then((result: ApiResponse<Identity[]>) => resolve(result.data[0]))
.catch(reject);
Expand All @@ -24,7 +25,7 @@ export const fetchIdentity = (identityId: string): Promise<Identity> => {

export const createIdentity = (body: string): Promise<void> => {
return new Promise((resolve, reject) => {
fetch("/api/v0/identities", {
fetch(`${apiBasePath}identities`, {
method: "POST",
body: body,
})
Expand All @@ -39,7 +40,7 @@ export const updateIdentity = (
values: string,
): Promise<Identity> => {
return new Promise((resolve, reject) => {
fetch(`/api/v0/identities/${identityId}`, {
fetch(`${apiBasePath}identities/${identityId}`, {
method: "PATCH",
body: values,
})
Expand All @@ -51,7 +52,7 @@ export const updateIdentity = (

export const deleteIdentity = (identityId: string) => {
return new Promise((resolve, reject) => {
fetch(`/api/v0/identities/${identityId}`, {
fetch(`${apiBasePath}identities/${identityId}`, {
method: "DELETE",
})
.then(resolve)
Expand Down
17 changes: 9 additions & 8 deletions ui/src/api/provider.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
import { ApiResponse } from "types/api";
import { handleResponse } from "util/api";
import { IdentityProvider } from "types/provider";
import { apiBasePath } from "util/basePaths";

export const fetchProviders = (): Promise<IdentityProvider[]> => {
return new Promise((resolve, reject) => {
fetch(`${import.meta.env.VITE_API_URL}/idps`)
fetch(`${apiBasePath}idps`)
.then(handleResponse)
.then((result: ApiResponse<IdentityProvider[]>) => resolve(result.data))
.catch(reject);
});
};

export const fetchProvider = (
providerId: string
providerId: string,
): Promise<IdentityProvider> => {
return new Promise((resolve, reject) => {
fetch(`${import.meta.env.VITE_API_URL}/idps/${providerId}`)
fetch(`${apiBasePath}idps/${providerId}`)
.then(handleResponse)
.then((result: ApiResponse<IdentityProvider[]>) =>
resolve(result.data[0])
resolve(result.data[0]),
)
.catch(reject);
});
};

export const createProvider = (body: string): Promise<void> => {
return new Promise((resolve, reject) => {
fetch(`${import.meta.env.VITE_API_URL}/idps`, {
fetch(`${apiBasePath}idps`, {
method: "POST",
body: body,
})
Expand All @@ -38,10 +39,10 @@ export const createProvider = (body: string): Promise<void> => {

export const updateProvider = (
providerId: string,
values: string
values: string,
): Promise<IdentityProvider> => {
return new Promise((resolve, reject) => {
fetch(`${import.meta.env.VITE_API_URL}/idps/${providerId}`, {
fetch(`${apiBasePath}idps/${providerId}`, {
method: "PATCH",
body: values,
})
Expand All @@ -53,7 +54,7 @@ export const updateProvider = (

export const deleteProvider = (providerId: string) => {
return new Promise((resolve, reject) => {
fetch(`${import.meta.env.VITE_API_URL}/idps/${providerId}`, {
fetch(`${apiBasePath}idps/${providerId}`, {
method: "DELETE",
})
.then(resolve)
Expand Down
13 changes: 8 additions & 5 deletions ui/src/api/schema.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { ApiResponse, PaginatedResponse } from "types/api";
import { handleResponse, PAGE_SIZE } from "util/api";
import { Schema } from "types/schema";
import { apiBasePath } from "util/basePaths";

export const fetchSchemas = (
pageToken: string,
): Promise<PaginatedResponse<Schema[]>> => {
return new Promise((resolve, reject) => {
fetch(`/api/v0/schemas?page_token=${pageToken}&page_size=${PAGE_SIZE}`)
fetch(
`${apiBasePath}schemas?page_token=${pageToken}&page_size=${PAGE_SIZE}`,
)
.then(handleResponse)
.then((result: PaginatedResponse<Schema[]>) => resolve(result))
.catch(reject);
Expand All @@ -15,7 +18,7 @@ export const fetchSchemas = (

export const fetchSchema = (schemaId: string): Promise<Schema> => {
return new Promise((resolve, reject) => {
fetch(`/api/v0/schemas/${schemaId}`)
fetch(`${apiBasePath}schemas/${schemaId}`)
.then(handleResponse)
.then((result: ApiResponse<Schema[]>) => resolve(result.data[0]))
.catch(reject);
Expand All @@ -24,7 +27,7 @@ export const fetchSchema = (schemaId: string): Promise<Schema> => {

export const createSchema = (body: string): Promise<void> => {
return new Promise((resolve, reject) => {
fetch("/api/v0/schemas", {
fetch(`${apiBasePath}schemas`, {
method: "POST",
body: body,
})
Expand All @@ -39,7 +42,7 @@ export const updateSchema = (
values: string,
): Promise<Schema> => {
return new Promise((resolve, reject) => {
fetch(`/api/v0/schemas/${schemaId}`, {
fetch(`${apiBasePath}schemas/${schemaId}`, {
method: "PATCH",
body: values,
})
Expand All @@ -51,7 +54,7 @@ export const updateSchema = (

export const deleteSchema = (schemaId: string) => {
return new Promise((resolve, reject) => {
fetch(`/api/v0/schemas/${schemaId}`, {
fetch(`${apiBasePath}schemas/${schemaId}`, {
method: "DELETE",
})
.then(resolve)
Expand Down
3 changes: 2 additions & 1 deletion ui/src/components/Logo.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { FC } from "react";
import { NavLink } from "react-router-dom";
import { basePath } from "util/basePaths";

const Logo: FC = () => {
return (
<NavLink className="p-panel__logo" to="/">
<NavLink className="p-panel__logo" to={basePath}>
<div className="p-navigation__logo-tag">
<img
className="p-navigation__logo-icon"
Expand Down
13 changes: 7 additions & 6 deletions ui/src/components/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Button, Icon } from "@canonical/react-components";
import classnames from "classnames";
import Logo from "components/Logo";
import { GroupsLink, RolesLink } from "@canonical/rebac-admin";
import { basePath } from "util/basePaths";

type Props = {
username?: string;
Expand Down Expand Up @@ -37,7 +38,7 @@ const Navigation: FC<Props> = ({ username, logout }) => {
<li className="p-side-navigation__item secondary">
<NavLink
className="p-side-navigation__link"
to={`/provider`}
to={`${basePath}provider`}
title={`Provider list`}
>
<Icon
Expand All @@ -50,7 +51,7 @@ const Navigation: FC<Props> = ({ username, logout }) => {
<li className="p-side-navigation__item secondary">
<NavLink
className="p-side-navigation__link"
to={`/client`}
to={`${basePath}client`}
title={`Client list`}
>
<Icon
Expand All @@ -63,7 +64,7 @@ const Navigation: FC<Props> = ({ username, logout }) => {
<li className="p-side-navigation__item secondary">
<NavLink
className="p-side-navigation__link"
to={`/identity`}
to={`${basePath}identity`}
title={`Identity list`}
>
<Icon
Expand All @@ -76,7 +77,7 @@ const Navigation: FC<Props> = ({ username, logout }) => {
<li className="p-side-navigation__item secondary">
<NavLink
className="p-side-navigation__link"
to={`/schema`}
to={`${basePath}schema`}
title={`Schema list`}
>
<Icon
Expand All @@ -89,15 +90,15 @@ const Navigation: FC<Props> = ({ username, logout }) => {
<li className="p-side-navigation__item secondary">
<GroupsLink
className="p-side-navigation__link"
baseURL="/"
baseURL={basePath}
icon="user-group"
iconIsLight
/>
</li>
<li className="p-side-navigation__item secondary">
<RolesLink
className="p-side-navigation__link"
baseURL="/"
baseURL={basePath}
icon="profile"
iconIsLight
/>
Expand Down
8 changes: 6 additions & 2 deletions ui/src/pages/clients/ClientCreate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import ClientForm, { ClientFormTypes } from "pages/clients/ClientForm";
import { createClient } from "api/client";
import SidePanel from "components/SidePanel";
import ScrollableContainer from "components/ScrollableContainer";
import { basePath } from "util/basePaths";

const ClientCreate: FC = () => {
const navigate = useNavigate();
Expand Down Expand Up @@ -43,7 +44,7 @@ const ClientCreate: FC = () => {
queryKey: [queryKeys.clients],
});
const msg = `Client created. Id: ${result.client_id} Secret: ${result.client_secret}`;
navigate("/client", notify.queue(notify.success(msg)));
navigate(`${basePath}client`, notify.queue(notify.success(msg)));
})
.catch((e) => {
formik.setSubmitting(false);
Expand Down Expand Up @@ -72,7 +73,10 @@ const ClientCreate: FC = () => {
<SidePanel.Footer>
<Row className="u-align-text--right">
<Col size={12}>
<Button appearance="base" onClick={() => navigate("/client")}>
<Button
appearance="base"
onClick={() => navigate(`${basePath}client`)}
>
Cancel
</Button>
<ActionButton
Expand Down
8 changes: 6 additions & 2 deletions ui/src/pages/clients/ClientEdit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { fetchClient, updateClient } from "api/client";
import usePanelParams from "util/usePanelParams";
import SidePanel from "components/SidePanel";
import ScrollableContainer from "components/ScrollableContainer";
import { basePath } from "util/basePaths";

const ClientEdit: FC = () => {
const navigate = useNavigate();
Expand Down Expand Up @@ -55,7 +56,10 @@ const ClientEdit: FC = () => {
void queryClient.invalidateQueries({
queryKey: [queryKeys.clients],
});
navigate(`/client`, notify.queue(notify.success("Client updated")));
navigate(
`${basePath}client`,
notify.queue(notify.success("Client updated")),
);
})
.catch((e) => {
formik.setSubmitting(false);
Expand Down Expand Up @@ -87,7 +91,7 @@ const ClientEdit: FC = () => {
<Button
appearance="base"
className="u-no-margin--bottom u-sv2"
onClick={() => navigate(`/client`)}
onClick={() => navigate(`${basePath}client`)}
>
Cancel
</Button>
Expand Down
Loading

0 comments on commit 709399c

Please sign in to comment.