From bf08cb08d2298780cf0b387579c7a95ad9bd714f Mon Sep 17 00:00:00 2001 From: Nicholas Bucher Date: Tue, 27 Aug 2024 16:50:19 -0400 Subject: [PATCH 01/19] changelog Signed-off-by: Nicholas Bucher --- changelog/v0.0.36/teams-page.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 changelog/v0.0.36/teams-page.yaml diff --git a/changelog/v0.0.36/teams-page.yaml b/changelog/v0.0.36/teams-page.yaml new file mode 100644 index 00000000..0361ce77 --- /dev/null +++ b/changelog/v0.0.36/teams-page.yaml @@ -0,0 +1,5 @@ +changelog: + - type: FIX + issueLink: https://github.com/solo-io/gloo-mesh-enterprise/issues/18336 + description: >- + Fixes an issue with the startup script where it didn't create the project/server/public folder. From b5d92744907033d3d93b1dbc953144bb21552f09 Mon Sep 17 00:00:00 2001 From: Nicholas Bucher Date: Tue, 27 Aug 2024 16:51:35 -0400 Subject: [PATCH 02/19] changelog Signed-off-by: Nicholas Bucher --- changelog/v0.0.36/teams-page.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/changelog/v0.0.36/teams-page.yaml b/changelog/v0.0.36/teams-page.yaml index 0361ce77..93a10681 100644 --- a/changelog/v0.0.36/teams-page.yaml +++ b/changelog/v0.0.36/teams-page.yaml @@ -1,5 +1,5 @@ changelog: - - type: FIX - issueLink: https://github.com/solo-io/gloo-mesh-enterprise/issues/18336 + - type: NEW_FEATURE + issueLink: https://github.com/solo-io/solo-projects/issues/6808 description: >- - Fixes an issue with the startup script where it didn't create the project/server/public folder. + Adds the teams page in to the gloo gateway version of the UI. From ac020854eb8bcc6c05631f57e69da282fd3f264f Mon Sep 17 00:00:00 2001 From: Nicholas Bucher Date: Thu, 5 Sep 2024 10:07:25 -0400 Subject: [PATCH 03/19] added existing portal server teams and apps and admin features Signed-off-by: Nicholas Bucher --- .../ApiProductDetailsPageHeading.tsx | 15 +- projects/ui/src/Components/Apis/ApisPage.tsx | 3 +- .../ui/src/Components/Apis/EmptyApisPage.tsx | 73 ++++++++ .../gloo-gateway-components/GG_ApisPage.tsx | 123 +++++++------ projects/ui/src/Components/AppContent.tsx | 2 +- .../ui/src/Components/AppContentRoutes.tsx | 171 ++++++++++-------- .../Details/Modals/NewSubscriptionModal.tsx | 5 +- .../AppSummaryCards/AppSummaryGridCard.tsx | 22 +-- .../ui/src/Components/Common/EmptyData.tsx | 2 +- .../Structure/BasicAuthVariant/Header.tsx | 154 ++++++++++++++++ .../HeaderSectionLoggedIn.tsx | 10 +- .../HeaderSectionLoggedOut.tsx | 17 +- .../ui/src/Components/Structure/Header.tsx | 156 ---------------- .../OidcAuthCodeHeaderDropdown.tsx | 2 +- .../Components/Teams/TeamsList/TeamsList.tsx | 4 +- projects/yarn.lock | 4 + 16 files changed, 427 insertions(+), 336 deletions(-) create mode 100644 projects/ui/src/Components/Apis/EmptyApisPage.tsx create mode 100644 projects/ui/src/Components/Structure/BasicAuthVariant/Header.tsx rename projects/ui/src/Components/Structure/{ => BasicAuthVariant}/HeaderSectionLoggedIn.tsx (91%) rename projects/ui/src/Components/Structure/{ => BasicAuthVariant}/HeaderSectionLoggedOut.tsx (92%) delete mode 100644 projects/ui/src/Components/Structure/Header.tsx create mode 100644 projects/yarn.lock diff --git a/projects/ui/src/Components/ApiDetails/gloo-gateway-components/ApiProductDetailsPageHeading.tsx b/projects/ui/src/Components/ApiDetails/gloo-gateway-components/ApiProductDetailsPageHeading.tsx index 8a2b832e..ba2c831a 100644 --- a/projects/ui/src/Components/ApiDetails/gloo-gateway-components/ApiProductDetailsPageHeading.tsx +++ b/projects/ui/src/Components/ApiDetails/gloo-gateway-components/ApiProductDetailsPageHeading.tsx @@ -1,4 +1,5 @@ import { Box, Flex, Select } from "@mantine/core"; +import { useContext, useState } from "react"; import toast from "react-hot-toast"; import { ApiProductSummary, @@ -6,12 +7,14 @@ import { ApiVersionSchema, } from "../../../Apis/api-types"; import { Icon } from "../../../Assets/Icons"; +import { AuthContext } from "../../../Context/AuthContext"; import { FormModalStyles } from "../../../Styles/shared/FormModalStyles"; import { useGetImageURL } from "../../../Utility/custom-image-utility"; import { downloadFile, filterMetadataToDisplay, } from "../../../Utility/utility"; +import NewSubscriptionModal from "../../Apps/Details/Modals/NewSubscriptionModal"; import { BannerHeading } from "../../Common/Banner/BannerHeading"; import { BannerHeadingTitle } from "../../Common/Banner/BannerHeadingTitle"; import { Button } from "../../Common/Button"; @@ -31,8 +34,8 @@ const ApiProductDetailsPageHeading = ({ onSelectedApiVersionChange: (newVersionId: string | null) => void; apiVersionSpec: ApiVersionSchema | undefined; }) => { - // const { isLoggedIn } = useContext(AuthContext); - // const [showSubscribeModal, setShowSubscribeModal] = useState(false); + const { isLoggedIn } = useContext(AuthContext); + const [showSubscribeModal, setShowSubscribeModal] = useState(false); const downloadApiSpec = () => { if (!selectedApiVersion?.apiSpec) { @@ -102,14 +105,12 @@ const ApiProductDetailsPageHeading = ({ /> )} - {/* - // Note: Removing sections for GGv2 demo. {isLoggedIn && ( - )} */} + )} + + + + ); +}; + +export default AddApiKeysSubSection; diff --git a/projects/ui/src/Components/Apps/Details/ApiKeysSection/AppApiKeysSection.tsx b/projects/ui/src/Components/Apps/Details/ApiKeysSection/AppApiKeysSection.tsx new file mode 100644 index 00000000..ab03c770 --- /dev/null +++ b/projects/ui/src/Components/Apps/Details/ApiKeysSection/AppApiKeysSection.tsx @@ -0,0 +1,137 @@ +import { Box, Flex } from "@mantine/core"; +import { useContext, useMemo, useState } from "react"; +import { di } from "react-magnetic-di"; +import { APIKey, App } from "../../../../Apis/api-types"; +import { + useListApiKeysForApp, + useListAppsForTeam, +} from "../../../../Apis/gg_hooks"; +import { AuthContext } from "../../../../Context/AuthContext"; +import { DetailsPageStyles } from "../../../../Styles/shared/DetailsPageStyles"; +import { GridCardStyles } from "../../../../Styles/shared/GridCard.style"; +import { UtilityStyles } from "../../../../Styles/shared/Utility.style"; +import { formatDateToMMDDYYYY } from "../../../../Utility/utility"; +import { Button } from "../../../Common/Button"; +import CustomPagination, { + pageOptions, + useCustomPagination, +} from "../../../Common/CustomPagination"; +import { SimpleEmptyContent } from "../../../Common/EmptyData"; +import { Loading } from "../../../Common/Loading"; +import Table from "../../../Common/Table"; +import ToggleAddButton from "../../../Common/ToggleAddButton"; +import ConfirmDeleteApiKeyModal from "../Modals/ConfirmDeleteApiKeyModal"; +import AddApiKeysSubSection from "./AddApiKeysSubSection"; + +const AppApiKeysSection = ({ app }: { app: App }) => { + di(useListAppsForTeam); + const { isAdmin } = useContext(AuthContext); + const { isLoading, data: apiKeys } = useListApiKeysForApp(app.id); + const [showAddApiKeySubSection, setShowAddApiKeySubSection] = useState(false); + + const customPaginationData = useCustomPagination( + apiKeys ?? [], + pageOptions.table + ); + const { paginatedData } = customPaginationData; + + const [confirmDeleteApiKey, setConfirmDeleteApiKey] = useState(); + + const rows = useMemo(() => { + return paginatedData?.map((apiKey) => { + return ( + ( + + {apiKey.name} + {formatDateToMMDDYYYY(new Date(apiKey.createdAt))} + {/* {JSON.stringify(apiKey.metadata)} */} + + + + + + + ) ?? [] + ); + }); + }, [paginatedData]); + + if (isLoading) { + return ; + } + return ( + + + API Keys + {!isAdmin && ( + + setShowAddApiKeySubSection(!showAddApiKeySubSection) + } + /> + )} + + setShowAddApiKeySubSection(false)} + /> + {!apiKeys?.length ? ( + // + + + {/* */} + + ) : ( + + + + + + + + + + + + {rows} + + + + + +
NameCreated + + Delete + +
+ + + +
+
+
+
+ )} + setConfirmDeleteApiKey(undefined)} + /> +
+ ); +}; + +export default AppApiKeysSection; diff --git a/projects/ui/src/Components/Apps/Details/AppDetailsPageContent.tsx b/projects/ui/src/Components/Apps/Details/AppDetailsPageContent.tsx index 11575485..df042716 100644 --- a/projects/ui/src/Components/Apps/Details/AppDetailsPageContent.tsx +++ b/projects/ui/src/Components/Apps/Details/AppDetailsPageContent.tsx @@ -1,19 +1,34 @@ -import { Box, Flex, Loader } from "@mantine/core"; +import { Box, Flex, Loader, Tooltip } from "@mantine/core"; +import { useMemo } from "react"; import { di } from "react-magnetic-di"; +import { NavLink } from "react-router-dom"; import { App } from "../../../Apis/api-types"; -import { useListSubscriptionsForApp } from "../../../Apis/gg_hooks"; +import { + useListSubscriptionsForApp, + useListTeams, +} from "../../../Apis/gg_hooks"; +import { Icon } from "../../../Assets/Icons"; +import { UtilityStyles } from "../../../Styles/shared/Utility.style"; +import { getTeamDetailsLink } from "../../../Utility/link-builders"; import { BannerHeading } from "../../Common/Banner/BannerHeading"; import { BannerHeadingTitle } from "../../Common/Banner/BannerHeadingTitle"; import { PageContainer } from "../../Common/PageContainer"; +import AppApiKeysSection from "./ApiKeysSection/AppApiKeysSection"; import AppApiSubscriptionsSection from "./ApiSubscriptionsSection/AppApiSubscriptionsSection"; import AppAuthenticationSection from "./AuthenticationSection/AppAuthenticationSection"; import EditAppButtonWithModal from "./EditAppButtonWithModal"; export const AppDetailsPageContent = ({ app }: { app: App }) => { - di(useListSubscriptionsForApp); + di(useListSubscriptionsForApp, useListTeams); const { isLoading: isLoadingSubscriptions, data: subscriptions } = useListSubscriptionsForApp(app.id); + const { isLoading: isLoadingTeams, data: teams } = useListTeams(); + const team = useMemo( + () => teams?.find((t) => t.id === app.teamId), + [teams, app] + ); + // Mock data for testing // app.idpClientId = "4df81266-f855-466d-8ded-699056780850"; // app.idpClientName = "test-idp"; @@ -27,6 +42,7 @@ export const AppDetailsPageContent = ({ app }: { app: App }) => { title={ } stylingTweaks={{ fontSize: "32px", lineHeight: "36px", @@ -34,7 +50,31 @@ export const AppDetailsPageContent = ({ app }: { app: App }) => { additionalInfo={} /> } - description={app.description} + description={ + <> + {!!team && !!team.name && ( + + + + + + {team?.name} + + + + + )} + {app.description} + + } breadcrumbItems={[ { label: "Home", link: "/" }, { label: "Apps", link: "/apps" }, @@ -44,6 +84,9 @@ export const AppDetailsPageContent = ({ app }: { app: App }) => { {appHasOAuthClient && } + + + {isLoadingSubscriptions || subscriptions === undefined ? ( ) : ( diff --git a/projects/ui/src/Components/Apps/Details/Modals/ConfirmDeleteApiKeyModal.tsx b/projects/ui/src/Components/Apps/Details/Modals/ConfirmDeleteApiKeyModal.tsx new file mode 100644 index 00000000..4d01a8e8 --- /dev/null +++ b/projects/ui/src/Components/Apps/Details/Modals/ConfirmDeleteApiKeyModal.tsx @@ -0,0 +1,61 @@ +import { Box, CloseButton, Flex } from "@mantine/core"; +import { FormEvent } from "react"; +import toast from "react-hot-toast"; +import { di } from "react-magnetic-di"; +import { useDeleteApiKeyMutation } from "../../../../Apis/gg_hooks"; +import { FormModalStyles } from "../../../../Styles/shared/FormModalStyles"; +import { Button } from "../../../Common/Button"; + +const ConfirmDeleteApiKeyModal = ({ + apiKeyId, + appId, + open, + onClose, +}: { + apiKeyId: string; + appId: string; + open: boolean; + onClose: () => void; +}) => { + di(useDeleteApiKeyMutation); + const { trigger: deleteApiKey } = useDeleteApiKeyMutation(appId); + const onConfirm = async (e?: FormEvent) => { + e?.preventDefault(); + await toast.promise(deleteApiKey({ apiKeyId }), { + error: (e) => "There was an error deleting the API Key. " + e, + loading: "Deleting the API Key...", + success: "Deleted the API Key!", + }); + onClose(); + }; + + // + // Render + // + return ( + + +
+ Delete API Key + + Are you sure that you want to delete this API Key? + +
+ +
+ + + + + + + +
+ ); +}; + +export default ConfirmDeleteApiKeyModal; diff --git a/projects/ui/src/Components/Common/EmptyData.tsx b/projects/ui/src/Components/Common/EmptyData.tsx index ca9135e1..d0659f91 100644 --- a/projects/ui/src/Components/Common/EmptyData.tsx +++ b/projects/ui/src/Components/Common/EmptyData.tsx @@ -1,6 +1,7 @@ import { css } from "@emotion/react"; import styled from "@emotion/styled"; import { Box, Flex, Text } from "@mantine/core"; +import { borderRadiusConstants } from "../../Styles/constants"; const StyledEmptyContentOuter = styled.div( ({ theme }) => css` @@ -8,7 +9,12 @@ const StyledEmptyContentOuter = styled.div( justify-content: center; text-align: center; line-height: 2rem; - background-color: ${theme.marchGrey}; + /* background-color: ${theme.splashBlueLight7}; */ + background-color: white; + box-shadow: 1px 1px 5px ${theme.splashBlue}; + border: 1px solid ${theme.splashBlue}; + border-radius: ${borderRadiusConstants.small}; + margin-bottom: 30px; padding: 30px; ` ); @@ -26,14 +32,18 @@ export const SimpleEmptyContent = (props: { {props.title && ( {props.title} )} - {props.children} + {!!props.children && ( + + {props.children} + + )}
); diff --git a/projects/ui/src/Components/Teams/Details/TeamDetailsPageContent.tsx b/projects/ui/src/Components/Teams/Details/TeamDetailsPageContent.tsx index e1494227..8c600b02 100644 --- a/projects/ui/src/Components/Teams/Details/TeamDetailsPageContent.tsx +++ b/projects/ui/src/Components/Teams/Details/TeamDetailsPageContent.tsx @@ -1,6 +1,7 @@ import { Box, Flex } from "@mantine/core"; import { useContext } from "react"; import { Team } from "../../../Apis/api-types"; +import { Icon } from "../../../Assets/Icons"; import { AuthContext } from "../../../Context/AuthContext"; import { BannerHeading } from "../../Common/Banner/BannerHeading"; import { BannerHeadingTitle } from "../../Common/Banner/BannerHeadingTitle"; @@ -17,6 +18,7 @@ const TeamDetailsPageContent = ({ team }: { team: Team }) => { title={ } stylingTweaks={{ fontSize: "32px", lineHeight: "36px", diff --git a/projects/ui/src/Styles/colors.ts b/projects/ui/src/Styles/colors.ts index 06513481..d8c35710 100644 --- a/projects/ui/src/Styles/colors.ts +++ b/projects/ui/src/Styles/colors.ts @@ -43,6 +43,8 @@ const baseColors = { const colorMap = { ...baseColors, + januaryGreyDark1: Color(baseColors.januaryGrey).darken(0.01).hex(), + marchGreyDark3: Color(baseColors.marchGrey).darken(0.03).hex(), marchGreyDark5: Color(baseColors.marchGrey).darken(0.05).hex(), marchGreyDark10: Color(baseColors.marchGrey).darken(0.1).hex(), diff --git a/projects/ui/src/Styles/global-styles/mantine-overrides.style.ts b/projects/ui/src/Styles/global-styles/mantine-overrides.style.ts index e020250e..4eb8c2fc 100644 --- a/projects/ui/src/Styles/global-styles/mantine-overrides.style.ts +++ b/projects/ui/src/Styles/global-styles/mantine-overrides.style.ts @@ -63,4 +63,8 @@ export const mantineGlobalStyles = css` } } } + + code.mantine-Code-root { + background-color: ${colors.januaryGreyDark1}; + } `; From 9c771188097682fd43b68ac6dd1042ed82e74d71 Mon Sep 17 00:00:00 2001 From: Nicholas Bucher Date: Wed, 11 Sep 2024 10:43:22 -0400 Subject: [PATCH 16/19] updated empty state, added some instructions for empty states. Signed-off-by: Nicholas Bucher --- .../ApiProductDetailsPageBody.tsx | 1 - .../SchemaTab/SchemaTabContent.tsx | 29 +++++++------- .../ApisTab/ApisList.tsx | 9 ++++- .../gloo-mesh-gateway-components/ApisList.tsx | 6 ++- .../ApiKeysSection/AppApiKeysSection.tsx | 4 +- .../AppApiSubscriptionsSection.tsx | 6 +-- .../Apps/Details/AppDetailsPageContent.tsx | 2 +- .../Components/Apps/PageContent/AppsList.tsx | 9 ++++- .../ui/src/Components/Common/EmptyData.tsx | 39 +------------------ .../SubscriptionsList/SubscriptionsList.tsx | 4 +- .../Details/AppsSection/TeamAppsSection.tsx | 4 +- .../Details/UsersSection/TeamUsersSection.tsx | 5 ++- .../Components/Teams/TeamsList/TeamsList.tsx | 6 +-- .../UsagePlanList/APIUsagePlansList.tsx | 4 +- 14 files changed, 51 insertions(+), 77 deletions(-) diff --git a/projects/ui/src/Components/ApiDetails/gloo-gateway-components/ApiProductDetailsPageBody.tsx b/projects/ui/src/Components/ApiDetails/gloo-gateway-components/ApiProductDetailsPageBody.tsx index b3285d25..bcaca627 100644 --- a/projects/ui/src/Components/ApiDetails/gloo-gateway-components/ApiProductDetailsPageBody.tsx +++ b/projects/ui/src/Components/ApiDetails/gloo-gateway-components/ApiProductDetailsPageBody.tsx @@ -71,7 +71,6 @@ export function ApiProductDetailsPageBody({ */} - + + Add a version to the spec.versions field of this{" "} + ApiProduct for data to appear. + ); } @@ -36,9 +31,13 @@ const SchemaTabContent = ({ // There is a selected API version, but no schema. return ( - + + The schema was not returned for this ApiProduct version. +
+ Verify that your OpenApi spec was generated correctly in the + corresponding ApiDoc resource for this{" "} + Service. +
); } diff --git a/projects/ui/src/Components/Apis/gloo-gateway-components/ApisTab/ApisList.tsx b/projects/ui/src/Components/Apis/gloo-gateway-components/ApisTab/ApisList.tsx index 7e8d8f4d..83a5ac36 100644 --- a/projects/ui/src/Components/Apis/gloo-gateway-components/ApisTab/ApisList.tsx +++ b/projects/ui/src/Components/Apis/gloo-gateway-components/ApisTab/ApisList.tsx @@ -12,7 +12,7 @@ import CustomPagination, { pageOptions, useCustomPagination, } from "../../../Common/CustomPagination"; -import { EmptyData } from "../../../Common/EmptyData"; +import { SimpleEmptyContent } from "../../../Common/EmptyData"; import { Loading } from "../../../Common/Loading"; import { ApisPageStyles } from "../../ApisPage.style"; import { ApiSummaryGridCard } from "./ApiSummaryCards/ApiSummaryGridCard"; @@ -78,8 +78,13 @@ export function ApisList({ if (apiProductsList === undefined) { return ; } + if (!apiProductsList.length) { + return ; + } if (!filteredApiProductsList.length) { - return ; + return ( + + ); } if (preferGridView) { return ( diff --git a/projects/ui/src/Components/Apis/gloo-mesh-gateway-components/ApisList.tsx b/projects/ui/src/Components/Apis/gloo-mesh-gateway-components/ApisList.tsx index 46d5f7c0..3a2a2921 100644 --- a/projects/ui/src/Components/Apis/gloo-mesh-gateway-components/ApisList.tsx +++ b/projects/ui/src/Components/Apis/gloo-mesh-gateway-components/ApisList.tsx @@ -7,7 +7,7 @@ import CustomPagination, { pageOptions, useCustomPagination, } from "../../Common/CustomPagination"; -import { EmptyData } from "../../Common/EmptyData"; +import { SimpleEmptyContent } from "../../Common/EmptyData"; import { Loading } from "../../Common/Loading"; import { ApiSummaryGridCard } from "./ApiSummaryGridCard"; import { ApiSummaryListCard } from "./ApiSummaryListCard"; @@ -72,7 +72,9 @@ export function ApisList({ } if (!displayedApisList.length) { - return ; + return ( + + ); } return ( <> diff --git a/projects/ui/src/Components/Apps/Details/ApiKeysSection/AppApiKeysSection.tsx b/projects/ui/src/Components/Apps/Details/ApiKeysSection/AppApiKeysSection.tsx index ab03c770..2e145992 100644 --- a/projects/ui/src/Components/Apps/Details/ApiKeysSection/AppApiKeysSection.tsx +++ b/projects/ui/src/Components/Apps/Details/ApiKeysSection/AppApiKeysSection.tsx @@ -86,10 +86,8 @@ const AppApiKeysSection = ({ app }: { app: App }) => { onClose={() => setShowAddApiKeySubSection(false)} /> {!apiKeys?.length ? ( - // - - {/* */} + ) : ( diff --git a/projects/ui/src/Components/Apps/Details/ApiSubscriptionsSection/AppApiSubscriptionsSection.tsx b/projects/ui/src/Components/Apps/Details/ApiSubscriptionsSection/AppApiSubscriptionsSection.tsx index 0dc43e45..4155066b 100644 --- a/projects/ui/src/Components/Apps/Details/ApiSubscriptionsSection/AppApiSubscriptionsSection.tsx +++ b/projects/ui/src/Components/Apps/Details/ApiSubscriptionsSection/AppApiSubscriptionsSection.tsx @@ -5,7 +5,7 @@ import { Icon } from "../../../../Assets/Icons"; import { DetailsPageStyles } from "../../../../Styles/shared/DetailsPageStyles"; import { UtilityStyles } from "../../../../Styles/shared/Utility.style"; import { Button } from "../../../Common/Button"; -import { EmptyData } from "../../../Common/EmptyData"; +import { SimpleEmptyContent } from "../../../Common/EmptyData"; import SubscriptionInfoCard from "../../../Common/SubscriptionsList/SubscriptionInfoCard/SubscriptionInfoCard"; import NewSubscriptionModal from "../Modals/NewSubscriptionModal"; @@ -43,8 +43,8 @@ const AppApiSubscriptionsSection = ({ /> {subscriptions.length === 0 && ( - - + + )} diff --git a/projects/ui/src/Components/Apps/Details/AppDetailsPageContent.tsx b/projects/ui/src/Components/Apps/Details/AppDetailsPageContent.tsx index df042716..a4b2a4a2 100644 --- a/projects/ui/src/Components/Apps/Details/AppDetailsPageContent.tsx +++ b/projects/ui/src/Components/Apps/Details/AppDetailsPageContent.tsx @@ -23,7 +23,7 @@ export const AppDetailsPageContent = ({ app }: { app: App }) => { const { isLoading: isLoadingSubscriptions, data: subscriptions } = useListSubscriptionsForApp(app.id); - const { isLoading: isLoadingTeams, data: teams } = useListTeams(); + const { data: teams } = useListTeams(); const team = useMemo( () => teams?.find((t) => t.id === app.teamId), [teams, app] diff --git a/projects/ui/src/Components/Apps/PageContent/AppsList.tsx b/projects/ui/src/Components/Apps/PageContent/AppsList.tsx index 7e8ee4fe..c0b49191 100644 --- a/projects/ui/src/Components/Apps/PageContent/AppsList.tsx +++ b/projects/ui/src/Components/Apps/PageContent/AppsList.tsx @@ -4,7 +4,7 @@ import { App, Team } from "../../../Apis/api-types"; import { useListAppsForTeams } from "../../../Apis/gg_hooks"; import { FilterPair, FilterType } from "../../../Utility/filter-utility"; import { omitErrorMessageResponse } from "../../../Utility/utility"; -import { EmptyData } from "../../Common/EmptyData"; +import { SimpleEmptyContent } from "../../Common/EmptyData"; import { Loading } from "../../Common/Loading"; import { AppsPageStyles } from "../AppsPage.style"; import { AppSummaryGridCard } from "./AppSummaryCards/AppSummaryGridCard"; @@ -85,8 +85,13 @@ export function AppsList({ if (isLoading) { return ; } + if (!appsList?.length) { + return ; + } if (!filteredAppsList.length) { - return ; + return ( + + ); } return ( diff --git a/projects/ui/src/Components/Common/EmptyData.tsx b/projects/ui/src/Components/Common/EmptyData.tsx index d0659f91..54a2031e 100644 --- a/projects/ui/src/Components/Common/EmptyData.tsx +++ b/projects/ui/src/Components/Common/EmptyData.tsx @@ -1,6 +1,6 @@ import { css } from "@emotion/react"; import styled from "@emotion/styled"; -import { Box, Flex, Text } from "@mantine/core"; +import { Box } from "@mantine/core"; import { borderRadiusConstants } from "../../Styles/constants"; const StyledEmptyContentOuter = styled.div( @@ -9,7 +9,6 @@ const StyledEmptyContentOuter = styled.div( justify-content: center; text-align: center; line-height: 2rem; - /* background-color: ${theme.splashBlueLight7}; */ background-color: white; box-shadow: 1px 1px 5px ${theme.splashBlue}; border: 1px solid ${theme.splashBlue}; @@ -19,9 +18,6 @@ const StyledEmptyContentOuter = styled.div( ` ); -/** - * This is typically used for Empty sections with more custom content. - */ export const SimpleEmptyContent = (props: { children?: React.ReactNode; title?: React.ReactNode; @@ -40,7 +36,7 @@ export const SimpleEmptyContent = (props: { )} {!!props.children && ( - + {props.children} )} @@ -48,34 +44,3 @@ export const SimpleEmptyContent = (props: { ); }; - -/** - * This is typically used for Empty data for topics. - */ -export function EmptyData( - props: - | { - topic: string; - message?: string; - } - | { - topicMessageOverride: React.ReactNode; - } -) { - return ( - - - {"topicMessageOverride" in props ? ( - <>{props.topicMessageOverride} - ) : ( - <>No {props.topic} results were found - )} - - {"message" in props && !!props.message && ( - - {props.message} - - )} - - ); -} diff --git a/projects/ui/src/Components/Common/SubscriptionsList/SubscriptionsList.tsx b/projects/ui/src/Components/Common/SubscriptionsList/SubscriptionsList.tsx index 14328fb1..9479c885 100644 --- a/projects/ui/src/Components/Common/SubscriptionsList/SubscriptionsList.tsx +++ b/projects/ui/src/Components/Common/SubscriptionsList/SubscriptionsList.tsx @@ -5,7 +5,7 @@ import { isSubscriptionsListError, } from "../../../Apis/api-types"; import { colors } from "../../../Styles"; -import { EmptyData } from "../../Common/EmptyData"; +import { SimpleEmptyContent } from "../../Common/EmptyData"; import { FiltrationProp } from "../Filters/AppliedFiltersSection"; import SubscriptionInfoCard from "./SubscriptionInfoCard/SubscriptionInfoCard"; @@ -35,7 +35,7 @@ const SubscriptionsList = ({ return null; } if (subscriptions.length === 0) { - return ; + return ; } return ( diff --git a/projects/ui/src/Components/Teams/Details/AppsSection/TeamAppsSection.tsx b/projects/ui/src/Components/Teams/Details/AppsSection/TeamAppsSection.tsx index 39515fd9..96a81dd0 100644 --- a/projects/ui/src/Components/Teams/Details/AppsSection/TeamAppsSection.tsx +++ b/projects/ui/src/Components/Teams/Details/AppsSection/TeamAppsSection.tsx @@ -14,7 +14,7 @@ import CustomPagination, { pageOptions, useCustomPagination, } from "../../../Common/CustomPagination"; -import { EmptyData } from "../../../Common/EmptyData"; +import { SimpleEmptyContent } from "../../../Common/EmptyData"; import { Loading } from "../../../Common/Loading"; import Table from "../../../Common/Table"; import ToggleAddButton from "../../../Common/ToggleAddButton"; @@ -86,7 +86,7 @@ const TeamAppsSection = ({ team }: { team: Team }) => { )} {!apps?.length ? ( - + ) : ( diff --git a/projects/ui/src/Components/Teams/Details/UsersSection/TeamUsersSection.tsx b/projects/ui/src/Components/Teams/Details/UsersSection/TeamUsersSection.tsx index 12bf55a9..f0cc1060 100644 --- a/projects/ui/src/Components/Teams/Details/UsersSection/TeamUsersSection.tsx +++ b/projects/ui/src/Components/Teams/Details/UsersSection/TeamUsersSection.tsx @@ -16,7 +16,7 @@ import CustomPagination, { pageOptions, useCustomPagination, } from "../../../Common/CustomPagination"; -import { EmptyData } from "../../../Common/EmptyData"; +import { SimpleEmptyContent } from "../../../Common/EmptyData"; import { Loading } from "../../../Common/Loading"; import Table from "../../../Common/Table"; import ToggleAddButton from "../../../Common/ToggleAddButton"; @@ -100,7 +100,8 @@ const TeamUsersSection = ({ team }: { team: Team }) => { /> {!members?.length ? ( - + {/* We never should get here, since the user must be a member. */} + ) : ( diff --git a/projects/ui/src/Components/Teams/TeamsList/TeamsList.tsx b/projects/ui/src/Components/Teams/TeamsList/TeamsList.tsx index 119914c6..5bedf4ce 100644 --- a/projects/ui/src/Components/Teams/TeamsList/TeamsList.tsx +++ b/projects/ui/src/Components/Teams/TeamsList/TeamsList.tsx @@ -1,7 +1,7 @@ import { Box, Flex } from "@mantine/core"; import { di } from "react-magnetic-di"; import { useListTeams } from "../../../Apis/gg_hooks"; -import { EmptyData } from "../../Common/EmptyData"; +import { SimpleEmptyContent } from "../../Common/EmptyData"; import { Loading } from "../../Common/Loading"; import { TeamSummaryGridCard } from "./TeamSummaryCards/TeamSummaryGridCard"; @@ -15,8 +15,8 @@ export function TeamsList() { if (teamsList === undefined || isLoading) { return ; } - if (!teamsList.length) { - return ; + if (!teamsList?.length) { + return ; } return ( diff --git a/projects/ui/src/Components/UsagePlans/UsagePlanList/APIUsagePlansList.tsx b/projects/ui/src/Components/UsagePlans/UsagePlanList/APIUsagePlansList.tsx index 0cd03c09..bb93abbc 100644 --- a/projects/ui/src/Components/UsagePlans/UsagePlanList/APIUsagePlansList.tsx +++ b/projects/ui/src/Components/UsagePlans/UsagePlanList/APIUsagePlansList.tsx @@ -2,7 +2,7 @@ import { useMemo } from "react"; import { di } from "react-magnetic-di"; import { API } from "../../../Apis/api-types"; import { useListApis } from "../../../Apis/shared_hooks"; -import { EmptyData } from "../../Common/EmptyData"; +import { SimpleEmptyContent } from "../../Common/EmptyData"; import { ErrorBoundary } from "../../Common/ErrorBoundary"; import { Loading } from "../../Common/Loading"; import { APIUsagePlanCard } from "./APIUsagePlanCard"; @@ -46,7 +46,7 @@ export function APIUsagePlansList() { )) ) : ( - + )} ); From 6e3a336d10623d88d52b4ebd2596737669fc49fe Mon Sep 17 00:00:00 2001 From: Nicholas Bucher Date: Wed, 11 Sep 2024 10:51:53 -0400 Subject: [PATCH 17/19] empty data rename Signed-off-by: Nicholas Bucher --- .../ApiProductDetailsPageBody.tsx | 13 ++++++------- .../SchemaTab/SchemaTabContent.tsx | 10 +++++----- projects/ui/src/Components/Apis/EmptyApisPage.tsx | 12 ++++-------- .../gloo-gateway-components/ApisTab/ApisList.tsx | 6 +++--- .../Apis/gloo-mesh-gateway-components/ApisList.tsx | 6 ++---- .../Details/ApiKeysSection/AppApiKeysSection.tsx | 4 ++-- .../AppApiSubscriptionsSection.tsx | 4 ++-- .../ui/src/Components/Apps/PageContent/AppsList.tsx | 8 +++----- projects/ui/src/Components/Common/EmptyData.tsx | 2 +- .../Common/SubscriptionsList/SubscriptionsList.tsx | 4 ++-- .../Teams/Details/AppsSection/TeamAppsSection.tsx | 4 ++-- .../Teams/Details/UsersSection/TeamUsersSection.tsx | 4 ++-- .../ui/src/Components/Teams/TeamsList/TeamsList.tsx | 4 ++-- .../UsagePlans/UsagePlanList/APIUsagePlansList.tsx | 4 ++-- .../Styles/global-styles/mantine-overrides.style.ts | 1 + 15 files changed, 39 insertions(+), 47 deletions(-) diff --git a/projects/ui/src/Components/ApiDetails/gloo-gateway-components/ApiProductDetailsPageBody.tsx b/projects/ui/src/Components/ApiDetails/gloo-gateway-components/ApiProductDetailsPageBody.tsx index bcaca627..0ea6fdd2 100644 --- a/projects/ui/src/Components/ApiDetails/gloo-gateway-components/ApiProductDetailsPageBody.tsx +++ b/projects/ui/src/Components/ApiDetails/gloo-gateway-components/ApiProductDetailsPageBody.tsx @@ -7,7 +7,7 @@ import { ApiVersionSchema, } from "../../../Apis/api-types"; import { ContentWidthDiv } from "../../../Styles/ContentWidthHelpers"; -import { SimpleEmptyContent } from "../../Common/EmptyData"; +import { EmptyData } from "../../Common/EmptyData"; import DocsTabContent from "./DocsTab/DocsTabContent"; import SchemaTabContent from "./SchemaTab/SchemaTabContent"; @@ -80,17 +80,16 @@ export function ApiProductDetailsPageBody({ {includesDocumentation ? ( ) : ( - + You may add documentation for this API in the{" "} - + spec.versions[your-version].openapiMetadata.description {" "} - field of this{" "} - ApiProduct resource. - Markdown is supported. + field of this ApiProduct resource. Markdown is + supported. - + )}
diff --git a/projects/ui/src/Components/ApiDetails/gloo-gateway-components/SchemaTab/SchemaTabContent.tsx b/projects/ui/src/Components/ApiDetails/gloo-gateway-components/SchemaTab/SchemaTabContent.tsx index 7d5397de..198596a6 100644 --- a/projects/ui/src/Components/ApiDetails/gloo-gateway-components/SchemaTab/SchemaTabContent.tsx +++ b/projects/ui/src/Components/ApiDetails/gloo-gateway-components/SchemaTab/SchemaTabContent.tsx @@ -1,6 +1,6 @@ import { Box, Code } from "@mantine/core"; import { ApiVersion, ApiVersionSchema } from "../../../../Apis/api-types"; -import { SimpleEmptyContent } from "../../../Common/EmptyData"; +import { EmptyData } from "../../../Common/EmptyData"; import { ErrorBoundary } from "../../../Common/ErrorBoundary"; import { ApiSchemaDisplay } from "./ApiSchemaDisplay"; @@ -16,10 +16,10 @@ const SchemaTabContent = ({ if (!apiProductVersions.length) { return ( - + Add a version to the spec.versions field of this{" "} ApiProduct for data to appear. - + ); } @@ -31,13 +31,13 @@ const SchemaTabContent = ({ // There is a selected API version, but no schema. return ( - + The schema was not returned for this ApiProduct version.
Verify that your OpenApi spec was generated correctly in the corresponding ApiDoc resource for this{" "} Service. -
+
); } diff --git a/projects/ui/src/Components/Apis/EmptyApisPage.tsx b/projects/ui/src/Components/Apis/EmptyApisPage.tsx index 51dfd438..cd1dd706 100644 --- a/projects/ui/src/Components/Apis/EmptyApisPage.tsx +++ b/projects/ui/src/Components/Apis/EmptyApisPage.tsx @@ -5,7 +5,7 @@ import { AuthContext } from "../../Context/AuthContext"; import { apisImageURL } from "../../user_variables.tmplr"; import { BannerHeading } from "../Common/Banner/BannerHeading"; import { BannerHeadingTitle } from "../Common/Banner/BannerHeadingTitle"; -import { SimpleEmptyContent } from "../Common/EmptyData"; +import { EmptyData } from "../Common/EmptyData"; import { PageContainer } from "../Common/PageContainer"; import { StyledApisListMain } from "./gloo-mesh-gateway-components/ApisPage.style"; @@ -31,19 +31,15 @@ export const EmptyApisPageContent = () => { const { isLoggedIn } = useContext(AuthContext); if (!!isLoggedIn) - return ( - - No API Products have been created. - - ); + return No API Products have been created.; return ( - + To view API Products in private Portals, please log in.
To view API Products in public Portals, the Portal resource must have{" "} spec.visibility.public = true.
-
+ ); }; diff --git a/projects/ui/src/Components/Apis/gloo-gateway-components/ApisTab/ApisList.tsx b/projects/ui/src/Components/Apis/gloo-gateway-components/ApisTab/ApisList.tsx index 83a5ac36..51b8459f 100644 --- a/projects/ui/src/Components/Apis/gloo-gateway-components/ApisTab/ApisList.tsx +++ b/projects/ui/src/Components/Apis/gloo-gateway-components/ApisTab/ApisList.tsx @@ -12,7 +12,7 @@ import CustomPagination, { pageOptions, useCustomPagination, } from "../../../Common/CustomPagination"; -import { SimpleEmptyContent } from "../../../Common/EmptyData"; +import { EmptyData } from "../../../Common/EmptyData"; import { Loading } from "../../../Common/Loading"; import { ApisPageStyles } from "../../ApisPage.style"; import { ApiSummaryGridCard } from "./ApiSummaryCards/ApiSummaryGridCard"; @@ -79,11 +79,11 @@ export function ApisList({ return ; } if (!apiProductsList.length) { - return ; + return ; } if (!filteredApiProductsList.length) { return ( - + ); } if (preferGridView) { diff --git a/projects/ui/src/Components/Apis/gloo-mesh-gateway-components/ApisList.tsx b/projects/ui/src/Components/Apis/gloo-mesh-gateway-components/ApisList.tsx index 3a2a2921..bd193c01 100644 --- a/projects/ui/src/Components/Apis/gloo-mesh-gateway-components/ApisList.tsx +++ b/projects/ui/src/Components/Apis/gloo-mesh-gateway-components/ApisList.tsx @@ -7,7 +7,7 @@ import CustomPagination, { pageOptions, useCustomPagination, } from "../../Common/CustomPagination"; -import { SimpleEmptyContent } from "../../Common/EmptyData"; +import { EmptyData } from "../../Common/EmptyData"; import { Loading } from "../../Common/Loading"; import { ApiSummaryGridCard } from "./ApiSummaryGridCard"; import { ApiSummaryListCard } from "./ApiSummaryListCard"; @@ -72,9 +72,7 @@ export function ApisList({ } if (!displayedApisList.length) { - return ( - - ); + return ; } return ( <> diff --git a/projects/ui/src/Components/Apps/Details/ApiKeysSection/AppApiKeysSection.tsx b/projects/ui/src/Components/Apps/Details/ApiKeysSection/AppApiKeysSection.tsx index 2e145992..5a000b9d 100644 --- a/projects/ui/src/Components/Apps/Details/ApiKeysSection/AppApiKeysSection.tsx +++ b/projects/ui/src/Components/Apps/Details/ApiKeysSection/AppApiKeysSection.tsx @@ -16,7 +16,7 @@ import CustomPagination, { pageOptions, useCustomPagination, } from "../../../Common/CustomPagination"; -import { SimpleEmptyContent } from "../../../Common/EmptyData"; +import { EmptyData } from "../../../Common/EmptyData"; import { Loading } from "../../../Common/Loading"; import Table from "../../../Common/Table"; import ToggleAddButton from "../../../Common/ToggleAddButton"; @@ -87,7 +87,7 @@ const AppApiKeysSection = ({ app }: { app: App }) => { /> {!apiKeys?.length ? ( - + ) : ( diff --git a/projects/ui/src/Components/Apps/Details/ApiSubscriptionsSection/AppApiSubscriptionsSection.tsx b/projects/ui/src/Components/Apps/Details/ApiSubscriptionsSection/AppApiSubscriptionsSection.tsx index 4155066b..ee2caa1e 100644 --- a/projects/ui/src/Components/Apps/Details/ApiSubscriptionsSection/AppApiSubscriptionsSection.tsx +++ b/projects/ui/src/Components/Apps/Details/ApiSubscriptionsSection/AppApiSubscriptionsSection.tsx @@ -5,7 +5,7 @@ import { Icon } from "../../../../Assets/Icons"; import { DetailsPageStyles } from "../../../../Styles/shared/DetailsPageStyles"; import { UtilityStyles } from "../../../../Styles/shared/Utility.style"; import { Button } from "../../../Common/Button"; -import { SimpleEmptyContent } from "../../../Common/EmptyData"; +import { EmptyData } from "../../../Common/EmptyData"; import SubscriptionInfoCard from "../../../Common/SubscriptionsList/SubscriptionInfoCard/SubscriptionInfoCard"; import NewSubscriptionModal from "../Modals/NewSubscriptionModal"; @@ -44,7 +44,7 @@ const AppApiSubscriptionsSection = ({ {subscriptions.length === 0 && ( - + )} diff --git a/projects/ui/src/Components/Apps/PageContent/AppsList.tsx b/projects/ui/src/Components/Apps/PageContent/AppsList.tsx index c0b49191..18135daa 100644 --- a/projects/ui/src/Components/Apps/PageContent/AppsList.tsx +++ b/projects/ui/src/Components/Apps/PageContent/AppsList.tsx @@ -4,7 +4,7 @@ import { App, Team } from "../../../Apis/api-types"; import { useListAppsForTeams } from "../../../Apis/gg_hooks"; import { FilterPair, FilterType } from "../../../Utility/filter-utility"; import { omitErrorMessageResponse } from "../../../Utility/utility"; -import { SimpleEmptyContent } from "../../Common/EmptyData"; +import { EmptyData } from "../../Common/EmptyData"; import { Loading } from "../../Common/Loading"; import { AppsPageStyles } from "../AppsPage.style"; import { AppSummaryGridCard } from "./AppSummaryCards/AppSummaryGridCard"; @@ -86,12 +86,10 @@ export function AppsList({ return ; } if (!appsList?.length) { - return ; + return ; } if (!filteredAppsList.length) { - return ( - - ); + return ; } return ( diff --git a/projects/ui/src/Components/Common/EmptyData.tsx b/projects/ui/src/Components/Common/EmptyData.tsx index 54a2031e..bde84dbe 100644 --- a/projects/ui/src/Components/Common/EmptyData.tsx +++ b/projects/ui/src/Components/Common/EmptyData.tsx @@ -18,7 +18,7 @@ const StyledEmptyContentOuter = styled.div( ` ); -export const SimpleEmptyContent = (props: { +export const EmptyData = (props: { children?: React.ReactNode; title?: React.ReactNode; }) => { diff --git a/projects/ui/src/Components/Common/SubscriptionsList/SubscriptionsList.tsx b/projects/ui/src/Components/Common/SubscriptionsList/SubscriptionsList.tsx index 9479c885..b401c7eb 100644 --- a/projects/ui/src/Components/Common/SubscriptionsList/SubscriptionsList.tsx +++ b/projects/ui/src/Components/Common/SubscriptionsList/SubscriptionsList.tsx @@ -5,7 +5,7 @@ import { isSubscriptionsListError, } from "../../../Apis/api-types"; import { colors } from "../../../Styles"; -import { SimpleEmptyContent } from "../../Common/EmptyData"; +import { EmptyData } from "../../Common/EmptyData"; import { FiltrationProp } from "../Filters/AppliedFiltersSection"; import SubscriptionInfoCard from "./SubscriptionInfoCard/SubscriptionInfoCard"; @@ -35,7 +35,7 @@ const SubscriptionsList = ({ return null; } if (subscriptions.length === 0) { - return ; + return ; } return ( diff --git a/projects/ui/src/Components/Teams/Details/AppsSection/TeamAppsSection.tsx b/projects/ui/src/Components/Teams/Details/AppsSection/TeamAppsSection.tsx index 96a81dd0..e7407a2a 100644 --- a/projects/ui/src/Components/Teams/Details/AppsSection/TeamAppsSection.tsx +++ b/projects/ui/src/Components/Teams/Details/AppsSection/TeamAppsSection.tsx @@ -14,7 +14,7 @@ import CustomPagination, { pageOptions, useCustomPagination, } from "../../../Common/CustomPagination"; -import { SimpleEmptyContent } from "../../../Common/EmptyData"; +import { EmptyData } from "../../../Common/EmptyData"; import { Loading } from "../../../Common/Loading"; import Table from "../../../Common/Table"; import ToggleAddButton from "../../../Common/ToggleAddButton"; @@ -86,7 +86,7 @@ const TeamAppsSection = ({ team }: { team: Team }) => { )} {!apps?.length ? ( - + ) : ( diff --git a/projects/ui/src/Components/Teams/Details/UsersSection/TeamUsersSection.tsx b/projects/ui/src/Components/Teams/Details/UsersSection/TeamUsersSection.tsx index f0cc1060..fa1559a6 100644 --- a/projects/ui/src/Components/Teams/Details/UsersSection/TeamUsersSection.tsx +++ b/projects/ui/src/Components/Teams/Details/UsersSection/TeamUsersSection.tsx @@ -16,7 +16,7 @@ import CustomPagination, { pageOptions, useCustomPagination, } from "../../../Common/CustomPagination"; -import { SimpleEmptyContent } from "../../../Common/EmptyData"; +import { EmptyData } from "../../../Common/EmptyData"; import { Loading } from "../../../Common/Loading"; import Table from "../../../Common/Table"; import ToggleAddButton from "../../../Common/ToggleAddButton"; @@ -101,7 +101,7 @@ const TeamUsersSection = ({ team }: { team: Team }) => { {!members?.length ? ( {/* We never should get here, since the user must be a member. */} - + ) : ( diff --git a/projects/ui/src/Components/Teams/TeamsList/TeamsList.tsx b/projects/ui/src/Components/Teams/TeamsList/TeamsList.tsx index 5bedf4ce..0b711ce4 100644 --- a/projects/ui/src/Components/Teams/TeamsList/TeamsList.tsx +++ b/projects/ui/src/Components/Teams/TeamsList/TeamsList.tsx @@ -1,7 +1,7 @@ import { Box, Flex } from "@mantine/core"; import { di } from "react-magnetic-di"; import { useListTeams } from "../../../Apis/gg_hooks"; -import { SimpleEmptyContent } from "../../Common/EmptyData"; +import { EmptyData } from "../../Common/EmptyData"; import { Loading } from "../../Common/Loading"; import { TeamSummaryGridCard } from "./TeamSummaryCards/TeamSummaryGridCard"; @@ -16,7 +16,7 @@ export function TeamsList() { return ; } if (!teamsList?.length) { - return ; + return ; } return ( diff --git a/projects/ui/src/Components/UsagePlans/UsagePlanList/APIUsagePlansList.tsx b/projects/ui/src/Components/UsagePlans/UsagePlanList/APIUsagePlansList.tsx index bb93abbc..0808d446 100644 --- a/projects/ui/src/Components/UsagePlans/UsagePlanList/APIUsagePlansList.tsx +++ b/projects/ui/src/Components/UsagePlans/UsagePlanList/APIUsagePlansList.tsx @@ -2,7 +2,7 @@ import { useMemo } from "react"; import { di } from "react-magnetic-di"; import { API } from "../../../Apis/api-types"; import { useListApis } from "../../../Apis/shared_hooks"; -import { SimpleEmptyContent } from "../../Common/EmptyData"; +import { EmptyData } from "../../Common/EmptyData"; import { ErrorBoundary } from "../../Common/ErrorBoundary"; import { Loading } from "../../Common/Loading"; import { APIUsagePlanCard } from "./APIUsagePlanCard"; @@ -46,7 +46,7 @@ export function APIUsagePlansList() { )) ) : ( - + )} ); diff --git a/projects/ui/src/Styles/global-styles/mantine-overrides.style.ts b/projects/ui/src/Styles/global-styles/mantine-overrides.style.ts index 4eb8c2fc..bacc83a9 100644 --- a/projects/ui/src/Styles/global-styles/mantine-overrides.style.ts +++ b/projects/ui/src/Styles/global-styles/mantine-overrides.style.ts @@ -66,5 +66,6 @@ export const mantineGlobalStyles = css` code.mantine-Code-root { background-color: ${colors.januaryGreyDark1}; + white-space: nowrap; } `; From 7ca428ca0586f8cf38764f753b80ca0f43293358 Mon Sep 17 00:00:00 2001 From: Nicholas Bucher Date: Wed, 11 Sep 2024 12:49:21 -0400 Subject: [PATCH 18/19] generate api key modal complete. Signed-off-by: Nicholas Bucher --- projects/ui/src/Apis/gg_hooks.ts | 7 +- .../ApiKeysSection/AddApiKeysSubSection.tsx | 50 +++++---- .../Details/Modals/ViewCreatedApiKeyModal.tsx | 100 ++++++++++++++++++ 3 files changed, 135 insertions(+), 22 deletions(-) create mode 100644 projects/ui/src/Components/Apps/Details/Modals/ViewCreatedApiKeyModal.tsx diff --git a/projects/ui/src/Apis/gg_hooks.ts b/projects/ui/src/Apis/gg_hooks.ts index 1e5fe745..5b6b3143 100644 --- a/projects/ui/src/Apis/gg_hooks.ts +++ b/projects/ui/src/Apis/gg_hooks.ts @@ -453,13 +453,16 @@ type CreateApiKeyParams = MutationWithArgs<{ apiKeyName: string }>; export function useCreateApiKeyMutation(appId: string) { const { latestAccessToken } = useContext(AuthContext); const createApiKey = async (_: string, { arg }: CreateApiKeyParams) => { - await fetchJSON(`/apps/${appId}/api-keys`, { + return await fetchJSON(`/apps/${appId}/api-keys`, { method: "POST", headers: getLatestAuthHeaders(latestAccessToken), body: JSON.stringify(arg), }); }; - return useSWRMutation(`/apps/${appId}/api-keys`, createApiKey); + return useSWRMutation( + `/apps/${appId}/api-keys`, + createApiKey + ); } // -------------------------------- // diff --git a/projects/ui/src/Components/Apps/Details/ApiKeysSection/AddApiKeysSubSection.tsx b/projects/ui/src/Components/Apps/Details/ApiKeysSection/AddApiKeysSubSection.tsx index acba192e..fffb9533 100644 --- a/projects/ui/src/Components/Apps/Details/ApiKeysSection/AddApiKeysSubSection.tsx +++ b/projects/ui/src/Components/Apps/Details/ApiKeysSection/AddApiKeysSubSection.tsx @@ -7,6 +7,7 @@ import { useCreateApiKeyMutation } from "../../../../Apis/gg_hooks"; import { DetailsPageStyles } from "../../../../Styles/shared/DetailsPageStyles"; import { Accordion } from "../../../Common/Accordion"; import { Button } from "../../../Common/Button"; +import ViewCreatedApiKeyModal from "../Modals/ViewCreatedApiKeyModal"; const AddApiKeysSubSection = ({ open, @@ -37,6 +38,7 @@ const AddApiKeysSubSection = ({ // // Form Submit // + const [createdApiKey, setCreatedApiKey] = useState(""); const { trigger: createApiKey } = useCreateApiKeyMutation(app.id); const onSubmit = async (e?: FormEvent) => { e?.preventDefault(); @@ -44,37 +46,45 @@ const AddApiKeysSubSection = ({ if (!isValid || isFormDisabled) { return; } - await toast.promise(createApiKey({ apiKeyName: formAppName }), { + const res = await toast.promise(createApiKey({ apiKeyName: formAppName }), { error: "There was an error creating the API Key.", loading: "Creating the API Key...", success: "Created the API Key!", }); onClose(); + setCreatedApiKey(res.apiKey); }; // // Render // return ( - - - - setFormAppName(e.target.value)} - /> - - - - + <> + + + + setFormAppName(e.target.value)} + /> + + + + + setCreatedApiKey("")} + /> + ); }; diff --git a/projects/ui/src/Components/Apps/Details/Modals/ViewCreatedApiKeyModal.tsx b/projects/ui/src/Components/Apps/Details/Modals/ViewCreatedApiKeyModal.tsx new file mode 100644 index 00000000..7cedc78a --- /dev/null +++ b/projects/ui/src/Components/Apps/Details/Modals/ViewCreatedApiKeyModal.tsx @@ -0,0 +1,100 @@ +import { Alert, Box, CloseButton, Flex } from "@mantine/core"; +import { useEffect, useState } from "react"; +import toast from "react-hot-toast"; +import { Icon } from "../../../../Assets/Icons"; +import { FormModalStyles } from "../../../../Styles/shared/FormModalStyles"; +import { copyToClipboard } from "../../../../Utility/utility"; +import { Button } from "../../../Common/Button"; + +const ViewCreatedApiKeyModal = ({ + apiKey, + open, + onCloseModal, +}: { + apiKey: string; + open: boolean; + onCloseModal: () => void; +}) => { + const [hasCopiedKey, setHasCopiedKey] = useState(false); + + useEffect(() => { + // Reset state on close. + if (!open) { + setHasCopiedKey(false); + } + }, [open]); + + const handleOnClose = () => { + if (!hasCopiedKey) { + return; + } + onCloseModal(); + }; + + // + // Render + // + return ( + + + + Created API Key + + {hasCopiedKey && ( + + )} + + + + } + title="Warning!" + color="orange" + > + This API Key value will not be available later. Please click the API + Key value to copy and secure this value now. + + + + + + + + + + ); +}; + +export default ViewCreatedApiKeyModal; From 4485944fc3aa0f26899612fe90e2a6952583476e Mon Sep 17 00:00:00 2001 From: Nicholas Bucher Date: Thu, 12 Sep 2024 13:05:53 -0400 Subject: [PATCH 19/19] changelog Signed-off-by: Nicholas Bucher --- changelog/v0.0.36/custom-pages.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 changelog/v0.0.36/custom-pages.yaml diff --git a/changelog/v0.0.36/custom-pages.yaml b/changelog/v0.0.36/custom-pages.yaml new file mode 100644 index 00000000..504cc325 --- /dev/null +++ b/changelog/v0.0.36/custom-pages.yaml @@ -0,0 +1,5 @@ +changelog: + - type: FIX + issueLink: https://github.com/solo-io/solo-projects/issues/6860 + description: >- + Adds the ability for users to create custom pages that show up in the UI.