diff --git a/changelog/v0.0.36/rate-limit-display-updated-when-mixed.yaml b/changelog/v0.0.36/rate-limit-display-updated-when-mixed.yaml new file mode 100644 index 00000000..4eeebb1b --- /dev/null +++ b/changelog/v0.0.36/rate-limit-display-updated-when-mixed.yaml @@ -0,0 +1,10 @@ +changelog: + - type: FIX + issueLink: https://github.com/solo-io/solo-projects/issues/7043 + description: >- + Updates the rate limit UI element to show mixed values when there is a App which + has multiple subscriptions with different rate limits. + - type: FIX + issueLink: https://github.com/solo-io/solo-projects/issues/7066 + description: >- + Fixes a bug where subscriptions incorrectly showed up as deleted. diff --git a/projects/ui/src/Apis/api-types.ts b/projects/ui/src/Apis/api-types.ts index b162e869..ddbfb1f8 100644 --- a/projects/ui/src/Apis/api-types.ts +++ b/projects/ui/src/Apis/api-types.ts @@ -2,6 +2,8 @@ // Gloo Mesh Gateway Types // +import { getEnumValues } from "../Utility/utility"; + type RateLimitPolicy = { unit: "UNKNOWN" | "SECOND" | "MINUTE" | "HOUR" | "DAY"; requestsPerUnit: number; @@ -171,8 +173,7 @@ export type OauthCredential = { idpClientName: string; }; -// This list of units is used both for the type and for the dropdown in the UI. -const rateLimitUnits = [ +export enum RateLimitUnit { "UNKNOWN", "SECOND", "MINUTE", @@ -180,16 +181,18 @@ const rateLimitUnits = [ "DAY", "MONTH", "YEAR", -] as const; // The 'as const' tells TypeScript to treat these as literal types -export const rateLimitUnitOptions = rateLimitUnits.map((unit) => ({ - value: unit, - label: unit, -})); -export type RateLimitUnit = (typeof rateLimitUnits)[number]; +} +// This list of units is used both for the type and for the dropdown in the UI. +export const rateLimitUnitOptions = getEnumValues(RateLimitUnit).map( + (unit) => ({ + value: RateLimitUnit[unit], + label: RateLimitUnit[unit], + }) +); export type RateLimit = { requestsPerUnit: string; - unit: RateLimitUnit; + unit: string; }; export type SubscriptionMetadata = { diff --git a/projects/ui/src/Apis/gg_hooks.ts b/projects/ui/src/Apis/gg_hooks.ts index 33732e14..979b6df0 100644 --- a/projects/ui/src/Apis/gg_hooks.ts +++ b/projects/ui/src/Apis/gg_hooks.ts @@ -56,7 +56,7 @@ export function useListFlatAppsForTeamsOmitErrors(teams: Team[]) { return { ...swrRes, data }; } export function useGetAppDetails(id?: string) { - return useSwrWithAuth(`/apps/${id}`); + return useSwrWithAuth(`/apps/${id}`, id ?? null); } export function useListApiKeysForApp(appId: string) { return useSwrWithAuth(`/apps/${appId}/api-keys`); @@ -101,9 +101,11 @@ export function useListSubscriptionsForStatus(status: SubscriptionStatus) { }, [swrResponse]); return swrResponse; } -export function useListSubscriptionsForApp(appId: string) { +export function useListSubscriptionsForApp(appId: string | null) { + const endpoint = `/apps/${appId}/subscriptions`; const swrResponse = useSwrWithAuth( - `/apps/${appId}/subscriptions` + endpoint, + appId === null ? null : endpoint ); useEffect(() => { if (isSubscriptionsListError(swrResponse.data)) { diff --git a/projects/ui/src/Apis/utility.ts b/projects/ui/src/Apis/utility.ts index ff180ea6..e37329bd 100644 --- a/projects/ui/src/Apis/utility.ts +++ b/projects/ui/src/Apis/utility.ts @@ -69,7 +69,7 @@ export async function fetchJSON(...args: Parameters) { */ export const useSwrWithAuth = ( path: string, - swrKey?: string, + swrKey?: string | null, config?: Parameters>[2] ) => { const { latestAccessToken } = useContext(AuthContext); diff --git a/projects/ui/src/Components/Apps/Details/MetadataSection/AppMetadataSection.tsx b/projects/ui/src/Components/Apps/Details/MetadataSection/AppMetadataSection.tsx index 3e41de86..8fc6b09b 100644 --- a/projects/ui/src/Components/Apps/Details/MetadataSection/AppMetadataSection.tsx +++ b/projects/ui/src/Components/Apps/Details/MetadataSection/AppMetadataSection.tsx @@ -3,7 +3,6 @@ import { App } from "../../../../Apis/api-types"; import { DetailsPageStyles } from "../../../../Styles/shared/DetailsPageStyles"; import { GridCardStyles } from "../../../../Styles/shared/GridCard.style"; import { MetadataDisplay } from "../../../../Utility/AdminUtility/MetadataDisplay"; -import { EmptyData } from "../../../Common/EmptyData"; const AppMetadataSection = ({ app }: { app: App }) => { // @@ -14,17 +13,11 @@ const AppMetadataSection = ({ app }: { app: App }) => { Metadata - {!!app.metadata?.rateLimit ? ( - - ) : ( - - - - )} + diff --git a/projects/ui/src/Components/Common/SubscriptionsList/SubscriptionInfoCard/SubscriptionInfoCardAdminFooter.tsx b/projects/ui/src/Components/Common/SubscriptionsList/SubscriptionInfoCard/SubscriptionInfoCardAdminFooter.tsx index 9876d793..595ad44a 100644 --- a/projects/ui/src/Components/Common/SubscriptionsList/SubscriptionInfoCard/SubscriptionInfoCardAdminFooter.tsx +++ b/projects/ui/src/Components/Common/SubscriptionsList/SubscriptionInfoCard/SubscriptionInfoCardAdminFooter.tsx @@ -19,8 +19,6 @@ const SubscriptionInfoCardAdminFooter = ({ const [showRejectSubModal, setShowRejectSubModal] = useState(false); const [showDeleteSubModal, setShowDeleteSubModal] = useState(false); - const canDeleteSubscription = subscriptionState !== SubscriptionState.DELETED; - // // Render // @@ -50,7 +48,6 @@ const SubscriptionInfoCardAdminFooter = ({ + ) : ( + + )} + + {/* Admins will see this message when editing the App Rate Limits. */} + {!props.isSubscription && !!appSubscriptions && ( + + + Please note that Subscriptions are able to override this Apps Rate + Limit value. + + {Array.isArray(appSubscriptions) && ( + <> + This App has {appSubscriptions.length} Subscription + {appSubscriptions.length === 1 ? "" : "s"}. + + )} + + + )} + + {/* Non-admins will see this message on their App details pages. */} + {!props.isSubscription && !!props.inAppDetailsPage && !isAdmin && ( + + + Please note that Subscriptions are able to override this Apps Rate + Limit value. + + + )} + + ); +};