From 7288066d96a2bf358facd7dcc274c8d175e722d0 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Tue, 7 Oct 2025 01:33:48 +0800 Subject: [PATCH] misc: updated no license behavior for PAM --- frontend/public/images/integrations/RDP.png | Bin 0 -> 4166 bytes frontend/public/images/integrations/SSH.png | Bin 0 -> 4091 bytes frontend/src/hooks/api/pam/enums.ts | 5 +- frontend/src/hooks/api/pam/maps.ts | 5 +- .../components/PamAccountsTable.tsx | 4 +- .../components/PamResourcesTable.tsx | 8 +-- .../components/ResourceTypeSelect.tsx | 46 ++++++++++++++++-- 7 files changed, 53 insertions(+), 15 deletions(-) create mode 100644 frontend/public/images/integrations/RDP.png create mode 100644 frontend/public/images/integrations/SSH.png diff --git a/frontend/public/images/integrations/RDP.png b/frontend/public/images/integrations/RDP.png new file mode 100644 index 0000000000000000000000000000000000000000..1336888b7e84a9068dd2486aba48601e6955104b GIT binary patch literal 4166 zcma)=`8U*W^uXVSvWM)FtfjFfF*Jk8*!Q)`Zpc1%LY6@c5(*$ zgzOn($&#h7&mZvpp6?I$x#v93ea?N(z2}~LUr(a3p%ya(9|HgY%sSfYrsq29KcTyL zzILmi2G13}ueN0X08kVD6RI0MEY;_mynz}I0?m9}0)tWh&OmT*u(Z3kXMhvR*IC-f z-!+#E;{yN|qK^7K^N_sFd{1BVmC%07=oAjlU2{>0&`kR*c|%lTa*~7Ak?A+s5pA?B zmi`z|l*wNk%N8y3&M|aZAM=uyD^NTd%PzeJOV)|d0maxx6CI>G9G)>JdolHb9x|mh zJ@M9VU0I9AB`B`gRzEtZ+Sd+?EW9&HR@y3w__q>Kc(Bhe9cCC3L}lNgRpEhH%hPew6l12?DB(N zN?9puhb@{LARJ|W=BF#_d_X9jRN1Q?d&tDn$X$k2drxfevYj8S_6*GK%kJQ=2gD2o zqb}cIg(tGp74^{57%$L(#Qi{28H&+>ZXW#qK6XGP^pDA}GoZ;A)BumekxGN^4Kvjs z*$DjBs3_NQLv^}x7v7j9QDGfo5^052#Xc1`q6JZ&yV;Ba?|b(}7_DM>I;}NLm#D`s zo_mcEBy^e^>2OTPZPXVAAcF;?KyoM#pIY0d6dm9m_kT~Lutq;Bm&&H}!zHFX_ZD>p z0Tz>`SmH$F?6r0@pQ_nqelNOF5tHY8%(2 z`n}vlEiiYaZ-MR>ezJopnrxh9tlKHyWtH91D*|QF?WGOi{n*^h z6oq}&an$poVOQ4608K-&Q{Zm1J?P1aNvIoKUDQK$RC%FYwu3wuOb78~{q@I6C-0k7(*BIApnB*XmJFFm zy?aV*4OC`z%@da&$c-+aS^rqvKK3yY$ni|?-j)B1B^CQcpt=XG3jU01xTw=RoVr{^ zP7Pn;JWISYLo(pxkuZt+!-zgR;gYu#?|hoAd&-S=ni75!R(>z499l8e;$Pn44?46Bcm`937)r-zrY&t5w#0RK>)!AC|LSXkyH z#l?eLj}Q@0T*hy6rn3n};h^vDnv5toG_UPyKyG3h?|jaeA0WFNe7MtYWhp;>^6<)F zu9KPdCRbO1OOnilxRH!O-73D`(JF_D{mMl9O!ZzNZp!wf9<2KTgi z?7VUAm!(OJ5GYmByh`%#{`1am#_@4npx95$bnMexu;xjZbJOQX9eNV2pBGRe}nxYpc>b0Jn&MpR9j`_+V z_PYziZ73pYmJJ${A@FY4g>zYlDqwut%6+Xrnu}dtp<*L*iOq~9Ccg3D*?OD(G7_}B zs?q4x@oH-X7n+`d@Pgbw{F+4hX>$-=bl5Jjbb*TctG2#v zw3qC*4ImuOowYW8di|Ns1*K0lQcE`;!7WMg#av?}Wqffd=z|FZ}NUO_@t!YZ#{kEN~z|d8@5e_w=hVU9g zyY8UgxJLZ|!r*Yi6F`JMuT&naFvW{~irl_-JrN^0VHk-R(_yE{o^jz5a z?L!vPuzSeSwbdbVEP@mm;&7+}_gFcCw_6g>&50 zx+EMYQh_Xz>)ysV!GwRTzpxHnEbo5Bo{z=rIWq11ZT3*y$*V_gxjxbR`OEp86fsDr zTYqoXjB9b=8-#ju*=dSME9J(soeE^=jA$KHo2fO7258CrRxF6443eg{JJwr<-uqvqY+&47Wmy=4-6V z{GZE4xXQF`O%_;KYWAJ}8%7o#?Ie?ibBc!eRGXe`H6}=`kM?SHvSPVtRq2Z^WXXN; zJ?3zp|Fwq;UE*t-^Iz<7nv9VTp!Goo7u35wGVeM`dN9A}Z zlId2z-`$4E8s!QJypjFQ#`9@@*S+D{&ACCp!iNEdNah%y766DP<>3#kAAaF%wCaBP zDnJg;okdofd{a`&e2vFYV(E$ahwVM=p*}#5Vt>;XL2CAAR)OW7#aGG0;>ww)dv=zd zxo=DfN_D<^x4f+Cnz6j&e>T$%1*x!iro8`#XAS;7cQVwz+gO;Rdq6d^n}2gYq_@nw z>E~ppSX$)PD{vbQw56e#`@ z>R1QWIPFI8mlV~|^rU3Z*g9lMtN5z~`QNaAoK8u+2QV^gjdDyr9`g4xqc)G-TG~oJ zI5Y(!coi{A^_YiOyD(Je0wz2$bh4j}7Iyg_;VUw-2exGR~xO-@pqMgf*umqpN0BdM-^De1FG4z4R68gBbdm%$i3W_IjM> zaow5jrH&FX&dT)6ynOLn9h?B%{{BWGbhBOOa6F!?kjZUfMc?-LD z8yQVg=*g9|`}?U_f+~2T>B&8d!_BW<<>|Hu7L(y)r+dg)Gw1Uepo~ST0b<#A3~po7 z-JwXNCaxqw>=whQfVNuQ?+AL~&Pd{l)(E5O^tA;8P)sZa_J78~(f*D73U8ad37#3lqpVIM1zlrrCf`c&SRK;$o~`u5$vo;3R> zn=+d{WZMlp{(9%pcCzuVmi z=XNJC^QBn+J{oHKT&n7T)|Q(p&1nhdLvt2Xx9A3nTBvY1$ej7MErA3t6XP`wjT}rH zNSX1z2IMR>;#U=TjuKX1n8G#=ViFa=&BYBiG0$t%{h;-zSmg(+(w~5Gp;{hG2t1cy zytxnfkLe?i)}Qq(_?sxw!h)(-anjq@vpBpUpS0WD(#52GGu)3>S0^mmf{KVex~ zz#$vS7Pl)#CGqT?^bY%!7RO&9lES-BH+$T!&!h+ znW5uI!M<&hFKUzpc}`v?246rKid^`YtQ?{eUi+mwdq0ocpd$2)ZUKC6gZ`GFR%H)g zeX*iJYD#foe_L~pW&~7sgYEQ+zRaNfw(FrkU*1V92KkFfQqt5;;ZAi(MN-~I;yOsA z%^c0G$v*KdqOFP&S$maN_;@Qc9+`9=HZ@?qapOnnFcfa^;#9{7ytdO`dsoR4jnri4 zf_Gaf3DiBn3JFl?kG)Wq#z(UO%0u1{B>K0e`rAQ9V6=&%!8X?BbH@%u1Qt1}k}0qG gOZ`PS@A!#o@cv~2JB};+{0{)o(J)l6QFDm-A3!SVs{jB1 literal 0 HcmV?d00001 diff --git a/frontend/public/images/integrations/SSH.png b/frontend/public/images/integrations/SSH.png new file mode 100644 index 0000000000000000000000000000000000000000..ff7708f9fd68f515e23dd360088b36e7b986db5f GIT binary patch literal 4091 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 literal 0 HcmV?d00001 diff --git a/frontend/src/hooks/api/pam/enums.ts b/frontend/src/hooks/api/pam/enums.ts index c6c66961b..b6e5ce64c 100644 --- a/frontend/src/hooks/api/pam/enums.ts +++ b/frontend/src/hooks/api/pam/enums.ts @@ -1,5 +1,8 @@ export enum PamResourceType { - Postgres = "postgres" + Postgres = "postgres", + RDP = "rdp", + SSH = "ssh", + Kubernetes = "kubernetes" } export enum PamSessionStatus { diff --git a/frontend/src/hooks/api/pam/maps.ts b/frontend/src/hooks/api/pam/maps.ts index c8dfb9d26..a27507d7d 100644 --- a/frontend/src/hooks/api/pam/maps.ts +++ b/frontend/src/hooks/api/pam/maps.ts @@ -4,5 +4,8 @@ export const PAM_RESOURCE_TYPE_MAP: Record< PamResourceType, { name: string; image: string; size?: number } > = { - [PamResourceType.Postgres]: { name: "PostgreSQL", image: "Postgres.png" } + [PamResourceType.Postgres]: { name: "PostgreSQL", image: "Postgres.png" }, + [PamResourceType.RDP]: { name: "RDP", image: "RDP.png" }, + [PamResourceType.SSH]: { name: "SSH", image: "SSH.png" }, + [PamResourceType.Kubernetes]: { name: "Kubernetes", image: "Kubernetes.png" } }; diff --git a/frontend/src/pages/pam/PamAccountsPage/components/PamAccountsTable.tsx b/frontend/src/pages/pam/PamAccountsPage/components/PamAccountsTable.tsx index 9138d7ba8..588e69810 100644 --- a/frontend/src/pages/pam/PamAccountsPage/components/PamAccountsTable.tsx +++ b/frontend/src/pages/pam/PamAccountsPage/components/PamAccountsTable.tsx @@ -35,7 +35,6 @@ import { Tr } from "@app/components/v2"; import { ROUTE_PATHS } from "@app/const/routes"; -import { useSubscription } from "@app/context"; import { ProjectPermissionActions, ProjectPermissionPamAccountActions, @@ -71,7 +70,6 @@ type Props = { }; export const PamAccountsTable = ({ accounts, folders, projectId }: Props) => { - const { subscription } = useSubscription(); const navigate = useNavigate({ from: ROUTE_PATHS.Pam.AccountsPage.path }); const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([ @@ -357,7 +355,7 @@ export const PamAccountsTable = ({ accounts, folders, projectId }: Props) => { variant="outline_bg" leftIcon={} onClick={() => handlePopUpOpen("addAccount")} - isDisabled={!isAllowedToCreateAccounts || !subscription.pam} + isDisabled={!isAllowedToCreateAccounts} className={`h-10 transition-colors ${accountView === AccountView.Flat ? "" : "rounded-r-none"}`} > Add Account diff --git a/frontend/src/pages/pam/PamResourcesPage/components/PamResourcesTable.tsx b/frontend/src/pages/pam/PamResourcesPage/components/PamResourcesTable.tsx index 7a87f0dd4..8d8f310e4 100644 --- a/frontend/src/pages/pam/PamResourcesPage/components/PamResourcesTable.tsx +++ b/frontend/src/pages/pam/PamResourcesPage/components/PamResourcesTable.tsx @@ -34,7 +34,7 @@ import { Tr } from "@app/components/v2"; import { ROUTE_PATHS } from "@app/const/routes"; -import { ProjectPermissionActions, ProjectPermissionSub, useSubscription } from "@app/context"; +import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context"; import { OrgGatewayPermissionActions, OrgPermissionSubjects @@ -62,8 +62,6 @@ type Props = { }; export const PamResourcesTable = ({ projectId, resources }: Props) => { - const { subscription } = useSubscription(); - const navigate = useNavigate({ from: ROUTE_PATHS.Pam.ResourcesPage.path }); const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp([ @@ -246,9 +244,7 @@ export const PamResourcesTable = ({ projectId, resources }: Props) => { colorSchema="secondary" leftIcon={} onClick={() => handlePopUpOpen("addResource")} - isDisabled={ - !isAllowed || !isGatewayAllowed || !subscription.gateway || !subscription.pam - } + isDisabled={!isAllowed || !isGatewayAllowed} > Add Resource diff --git a/frontend/src/pages/pam/PamResourcesPage/components/ResourceTypeSelect.tsx b/frontend/src/pages/pam/PamResourcesPage/components/ResourceTypeSelect.tsx index 82de8f759..5104fb452 100644 --- a/frontend/src/pages/pam/PamResourcesPage/components/ResourceTypeSelect.tsx +++ b/frontend/src/pages/pam/PamResourcesPage/components/ResourceTypeSelect.tsx @@ -2,8 +2,10 @@ import { useMemo } from "react"; import { faInfoCircle, faMagnifyingGlass, faSearch } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal"; import { EmptyState, Input, Pagination, Spinner, Tooltip } from "@app/components/v2"; -import { usePagination, useResetPageHelper } from "@app/hooks"; +import { useSubscription } from "@app/context"; +import { usePagination, usePopUp, useResetPageHelper } from "@app/hooks"; import { PAM_RESOURCE_TYPE_MAP, PamResourceType, @@ -16,6 +18,18 @@ type Props = { export const ResourceTypeSelect = ({ onSelect }: Props) => { const { isPending, data: resourceOptions } = useListPamResourceOptions(); + const { subscription } = useSubscription(); + const { popUp, handlePopUpToggle } = usePopUp(["upgradePlan"] as const); + + const appendedResourceOptions = useMemo(() => { + if (!resourceOptions) return []; + return [ + ...resourceOptions, + { name: "RDP", resource: PamResourceType.RDP }, + { name: "SSH", resource: PamResourceType.SSH }, + { name: "Kubernetes", resource: PamResourceType.Kubernetes } + ]; + }, [resourceOptions]); const { search, setSearch, setPage, page, perPage, setPerPage, offset } = usePagination("", { initPerPage: 16 @@ -23,12 +37,12 @@ export const ResourceTypeSelect = ({ onSelect }: Props) => { const filteredOptions = useMemo( () => - resourceOptions?.filter( + appendedResourceOptions?.filter( ({ name, resource }) => name.toLowerCase().includes(search.trim().toLowerCase()) || resource.toLowerCase().includes(search.trim().toLowerCase()) ) ?? [], - [resourceOptions, search] + [appendedResourceOptions, search] ); useResetPageHelper({ @@ -37,6 +51,23 @@ export const ResourceTypeSelect = ({ onSelect }: Props) => { setPage }); + const handleResourceSelect = (resource: PamResourceType) => { + if (!subscription?.pam) { + handlePopUpToggle("upgradePlan", true); + return; + } + + if ( + resource === PamResourceType.RDP || + resource === PamResourceType.SSH || + resource === PamResourceType.Kubernetes + ) { + return; + } + + onSelect(resource); + }; + if (isPending) { return (
@@ -62,7 +93,7 @@ export const ResourceTypeSelect = ({ onSelect }: Props) => { return (