Skip to content

Commit

Permalink
added mutations
Browse files Browse the repository at this point in the history
Signed-off-by: Nicholas Bucher <[email protected]>
  • Loading branch information
Charlesthebird committed Sep 26, 2024
1 parent 140215e commit d695e95
Show file tree
Hide file tree
Showing 17 changed files with 370 additions and 78 deletions.
4 changes: 2 additions & 2 deletions projects/ui/src/Apis/api-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export type App = {
name: string;
description: string;
teamId: string;
metadata: AppMetadata;
metadata?: AppMetadata;
};

export type ApiKey = {
Expand Down Expand Up @@ -156,7 +156,7 @@ export type Subscription = {
id: string;
requestedAt: string;
updatedAt: string;
metadata: SubscriptionMetadata;
metadata?: SubscriptionMetadata;
};

export type ApiVersionExtended = ApiVersion & {
Expand Down
100 changes: 100 additions & 0 deletions projects/ui/src/Apis/gg_hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
App,
Member,
OauthCredential,
RateLimit,
Subscription,
SubscriptionStatus,
SubscriptionsListError,
Expand Down Expand Up @@ -520,3 +521,102 @@ export function useCreateUserMutation() {
};
return useSWRMutation(`create-user`, createUser);
}

// -------------------------------- //
// region (Admin) Create App Metadata

type CreateUpdateAppMetadataParams = MutationWithArgs<{
appId: string;
customMetadata: Record<string, string>;
rateLimit: RateLimit;
}>;

export function useCreateAppMetadataMutation(appId: string) {
const { latestAccessToken } = useContext(AuthContext);
const { mutate } = useSWRConfig();
const createAppMetadata = async (
_: string,
{ arg }: CreateUpdateAppMetadataParams
) => {
await fetchJSON(`/apps/${appId}/metadata`, {
method: "POST",
headers: getLatestAuthHeaders(latestAccessToken),
body: JSON.stringify(arg),
});
mutate(TEAM_APPS_SWR_KEY);
};
return useSWRMutation(`/apps/${appId}`, createAppMetadata);
}

// -------------------------------- //
// region (Admin) Update App Metadata

export function useUpdateAppMetadataMutation(appId: string) {
const { latestAccessToken } = useContext(AuthContext);
const { mutate } = useSWRConfig();
const fetcher = async (_: string, { arg }: CreateUpdateAppMetadataParams) => {
await fetchJSON(`/apps/${appId}/metadata`, {
method: "PUT",
headers: getLatestAuthHeaders(latestAccessToken),
body: JSON.stringify(arg),
});
mutate(TEAM_APPS_SWR_KEY);
};
return useSWRMutation(`/apps/${appId}`, fetcher);
}

// -------------------------------- //
// region (Admin) Create Subscription Metadata

type CreateUpdateSubscriptionMetadataParams = MutationWithArgs<{
subscriptionId: string;
customMetadata: Record<string, string>;
rateLimit: RateLimit;
}>;

export function useCreateSubscriptionMetadataMutation(
subscription: Subscription
) {
const { latestAccessToken } = useContext(AuthContext);
const { mutate } = useSWRConfig();
const fetcher = async (
_: string,
{ arg }: CreateUpdateSubscriptionMetadataParams
) => {
await fetchJSON(`/subscriptions/${subscription.id}/metadata`, {
method: "POST",
headers: getLatestAuthHeaders(latestAccessToken),
body: JSON.stringify(arg),
});
mutate(`/apps/${subscription.applicationId}/subscriptions`);
mutate(`/subscriptions?status=${SubscriptionStatus.APPROVED}`);
mutate(`/subscriptions?status=${SubscriptionStatus.PENDING}`);
mutate(APP_SUBS_SWR_KEY);
};
return useSWRMutation(`update-subscription-metadata`, fetcher);
}

// -------------------------------- //
// region (Admin) Update Subscription Metadata

export function useUpdateSubscriptionMetadataMutation(
subscription: Subscription
) {
const { latestAccessToken } = useContext(AuthContext);
const { mutate } = useSWRConfig();
const fetcher = async (
_: string,
{ arg }: CreateUpdateSubscriptionMetadataParams
) => {
await fetchJSON(`/subscriptions/${subscription.id}/metadata`, {
method: "PUT",
headers: getLatestAuthHeaders(latestAccessToken),
body: JSON.stringify(arg),
});
mutate(`/apps/${subscription.applicationId}/subscriptions`);
mutate(`/subscriptions?status=${SubscriptionStatus.APPROVED}`);
mutate(`/subscriptions?status=${SubscriptionStatus.PENDING}`);
mutate(APP_SUBS_SWR_KEY);
};
return useSWRMutation(`update-subscription-metadata`, fetcher);
}
5 changes: 5 additions & 0 deletions projects/ui/src/Components/AdminApps/AdminAppsPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { AppsPage } from "../Apps/AppsPage";

// The admin apps page reuses the standard apps page components,
// which have modifications to support admin functions.
export default AppsPage;
17 changes: 16 additions & 1 deletion projects/ui/src/Components/AppContentRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
oidcAuthCodeConfigLogoutPath,
} from "../user_variables.tmplr";
import { getCustomPagePath } from "../Utility/utility";
import AdminAppsPage from "./AdminApps/AdminAppsPage";
import AdminSubscriptionsPage from "./AdminSubscriptions/AdminSubscriptionsPage";
import AdminTeamsPage from "./AdminTeams/AdminTeamsPage";
import { ApiDetailsPage } from "./ApiDetails/ApiDetailsPage";
Expand Down Expand Up @@ -51,6 +52,9 @@ function AppContentRoutes() {

return (
<MainContentContainer>
{/*
// region Shared
*/}
<Routes>
<Route
path={oidcAuthCodeConfigCallbackPath}
Expand Down Expand Up @@ -92,6 +96,9 @@ function AppContentRoutes() {
</ErrorBoundary>
}
/>
{/*
// region GG
*/}
{portalServerType === "gloo-gateway" && isLoggedIn && (
<>
<Route
Expand Down Expand Up @@ -138,6 +145,14 @@ function AppContentRoutes() {
</ErrorBoundary>
}
/>
<Route
path="/admin/apps"
element={
<ErrorBoundary fallback="There was an issue displaying the Admin Apps page">
<AdminAppsPage />
</ErrorBoundary>
}
/>
<Route
path="/admin/teams"
element={
Expand All @@ -150,7 +165,7 @@ function AppContentRoutes() {
)}
{/*
Gloo Mesh Gateway Routes
// region GMG
*/}
{portalServerType === "gloo-mesh-gateway" && (
<>
Expand Down
41 changes: 0 additions & 41 deletions projects/ui/src/Components/Apps/AppMetadata/AppMetadataDisplay.tsx

This file was deleted.

12 changes: 9 additions & 3 deletions projects/ui/src/Components/Apps/AppsPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Box } from "@mantine/core";
import { useState } from "react";
import { Icon } from "../../Assets/Icons";
import { useIsAdmin } from "../../Context/AuthContext";
import { BannerHeading } from "../Common/Banner/BannerHeading";
import { BannerHeadingTitle } from "../Common/Banner/BannerHeadingTitle";
import { Button } from "../Common/Button";
Expand All @@ -10,6 +11,7 @@ import { AppsPageContent } from "./PageContent/AppsPageContent";

export function AppsPage() {
const [modalOpen, setModalOpen] = useState(false);
const isAdmin = useIsAdmin();

return (
<PageContainer>
Expand All @@ -18,9 +20,13 @@ export function AppsPage() {
description={
<>
Browse the list of Apps in this portal.
<Box pt={"20px"}>
<Button onClick={() => setModalOpen(true)}>CREATE NEW APP</Button>
</Box>
{!isAdmin && (
<Box pt={"20px"}>
<Button onClick={() => setModalOpen(true)}>
CREATE NEW APP
</Button>
</Box>
)}
</>
}
breadcrumbItems={[{ label: "Home", link: "/" }, { label: "Apps" }]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ const AppApiKeysSection = ({ app }: { app: App }) => {
<tr key={apiKey.id}>
<td>{apiKey.name}</td>
<td>{formatDateToMMDDYYYY(new Date(apiKey.createdAt))}</td>
{/* <td>{JSON.stringify(apiKey.metadata)}</td> */}
<td>
<UtilityStyles.CenteredCellContent>
<Button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const AppApiSubscriptionsSection = ({
}, [subscriptions, app]);

return (
<DetailsPageStyles.Section>
<DetailsPageStyles.Section mb="60px">
<Flex justify={"space-between"}>
<DetailsPageStyles.Title>API Subscriptions</DetailsPageStyles.Title>
<AddSubscriptionButton
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
import { Box, Flex, Tooltip } from "@mantine/core";
import { useState } from "react";
import { NavLink } from "react-router-dom";
import { Icon } from "../../../../Assets/Icons";
import { useIsAdmin } from "../../../../Context/AuthContext";
import { CardStyles } from "../../../../Styles/shared/Card.style";
import { GridCardStyles } from "../../../../Styles/shared/GridCard.style";
import { UtilityStyles } from "../../../../Styles/shared/Utility.style";
import { MetadataDisplay } from "../../../../Utility/AdminUtility/MetadataDisplay";
import {
getAppDetailsLink,
getTeamDetailsLink,
} from "../../../../Utility/link-builders";
import { SubscriptionInfoCardStyles } from "../../../Common/SubscriptionsList/SubscriptionInfoCard/SubscriptionInfoCard.style";
import AppMetadataDisplay from "../../AppMetadata/AppMetadataDisplay";
import { AppWithTeam } from "../AppsList";

/**
* MAIN COMPONENT
**/
export function AppSummaryGridCard({ app }: { app: AppWithTeam }) {
const isAdmin = useIsAdmin();
const [isManagingMetadata, setIsManagingMetadata] = useState(false);

return (
// <GridCardStyles.GridCardWithLink whiteBg to={getAppDetailsLink(app)}>
<GridCardStyles.GridCard whiteBg>
<GridCardStyles.GridCard whiteBg wide={isManagingMetadata}>
<div className="content">
<Box p={"20px"}>
<Flex direction={"column"} align={"flex-start"} gap={"5px"}>
Expand All @@ -36,16 +40,26 @@ export function AppSummaryGridCard({ app }: { app: AppWithTeam }) {
</UtilityStyles.NavLinkContainer>
</Tooltip>
</Flex>
<AppMetadataDisplay app={app} />
<CardStyles.Description>{app.description}</CardStyles.Description>
<MetadataDisplay
itemType="app"
itemId={app.id}
customMetadata={app.metadata?.customMetadata}
rateLimitInfo={app.metadata?.rateLimit}
onIsManagingMetadataChange={(value) =>
setIsManagingMetadata(value)
}
/>
</Flex>
</Box>
</div>
<SubscriptionInfoCardStyles.Footer>
<UtilityStyles.NavLinkContainer>
<NavLink to={getAppDetailsLink(app)}>DETAILS</NavLink>
</UtilityStyles.NavLinkContainer>
</SubscriptionInfoCardStyles.Footer>
{!isAdmin && (
<SubscriptionInfoCardStyles.Footer>
<UtilityStyles.NavLinkContainer>
<NavLink to={getAppDetailsLink(app)}>DETAILS</NavLink>
</UtilityStyles.NavLinkContainer>
</SubscriptionInfoCardStyles.Footer>
)}
</GridCardStyles.GridCard>
);
}
4 changes: 3 additions & 1 deletion projects/ui/src/Components/Common/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,12 @@ const colorMap: {
},
};

export type ButtonVariant = "outline" | "subtle" | "light" | "filled";

export function Button(
props: {
color?: "primary" | "success" | "warning" | "danger" | "secondary";
variant?: "outline" | "subtle" | "light" | "filled";
variant?: ButtonVariant;
onClick?: MouseEventHandler<HTMLButtonElement>;
/**
* `isText` defaults to true, and can be set to false to render the contents directly under the button.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,17 @@ import {
export namespace SubscriptionInfoCardStyles {
export const Card = styled.div<{
subscriptionState: SubscriptionState;
wide?: boolean;
}>(
({ theme, subscriptionState }) => css`
width: 428px;
${mediaQueryWithScreenSize.mediumAndSmaller} {
width: 100%;
}
({ theme, subscriptionState, wide }) => css`
${!wide
? css`
width: 428px;
${mediaQueryWithScreenSize.mediumAndSmaller} {
width: 100%;
}
`
: ""}
border: 1px solid ${subscriptionStateMap[subscriptionState].borderColor};
border-radius: ${borderRadiusConstants.small};
background-color: white;
Expand Down
Loading

0 comments on commit d695e95

Please sign in to comment.