diff --git a/app/components/Sparkline/Sparkline.tsx b/app/components/Sparkline/Sparkline.tsx index 52caef503..cb2b881ef 100644 --- a/app/components/Sparkline/Sparkline.tsx +++ b/app/components/Sparkline/Sparkline.tsx @@ -47,7 +47,7 @@ const Sparkline = ({ > Date: {label} - {payload[0].value + {payload[0].value || payload[0].value === 0 ? `${ commifyValue ? commify(payload[0].value) : payload[0].value } ${valueLabel}` diff --git a/app/models/portal/queries.graphqls b/app/models/portal/queries.graphqls index a4d9d917e..f5d9b1121 100644 --- a/app/models/portal/queries.graphqls +++ b/app/models/portal/queries.graphqls @@ -48,16 +48,13 @@ query getUserAccount( id name planType - users { - userID - owner + accountUsers { + accountUserID email - portalAppRoles { + owner + portalApps { portalAppID roleName - } - portalAppsAccepted { - portalAppID accepted } } @@ -158,8 +155,8 @@ query getUserAccounts( id name } - users { - userID + accountUsers { + accountUserID owner } } @@ -172,18 +169,11 @@ query getUserPortalApp($portalAppID: ID!) { accountID appEmoji description - users { - userID - owner + portalAppUsers { + portalAppUserID email - portalAppRoles { - portalAppID - roleName - } - portalAppsAccepted { - portalAppID - accepted - } + roleName + accepted } settings { appID @@ -264,18 +254,11 @@ query getUserPortalApps( accountID appEmoji description - users { - userID - owner + portalAppUsers { + portalAppUserID email - portalAppRoles { - portalAppID - roleName - } - portalAppsAccepted { - portalAppID - accepted - } + roleName + accepted } } } diff --git a/app/routes/account.$accountId.$appId.insights/view.tsx b/app/routes/account.$accountId.$appId.insights/view.tsx index 0ecdfde35..d966b69e4 100644 --- a/app/routes/account.$accountId.$appId.insights/view.tsx +++ b/app/routes/account.$accountId.$appId.insights/view.tsx @@ -54,12 +54,12 @@ export default function ApplicationInsightsView({ data }: ApplicationInsightsVie ( - - Total Relays - + + Total Relays + {commify(total?.countTotal ?? 0)} - + )} @@ -77,12 +77,12 @@ export default function ApplicationInsightsView({ data }: ApplicationInsightsVie ( - - Average Latency{" "} - + + Average Latency + {commify(total?.avgLatency ?? 0)}ms - + )} @@ -98,12 +98,12 @@ export default function ApplicationInsightsView({ data }: ApplicationInsightsVie ( - - Success Rate{" "} - + + Success Rate + {commify(total?.rateSuccess ?? 0)}% - + )} @@ -120,12 +120,12 @@ export default function ApplicationInsightsView({ data }: ApplicationInsightsVie ( - - Total Errors{" "} - + + Total Errors + {totalErrors ? commify(totalErrors) : 0} - + )} diff --git a/app/routes/account.$accountId.$appId.logs/route.tsx b/app/routes/account.$accountId.$appId.logs/route.tsx index e1a6f2922..ba12255e3 100644 --- a/app/routes/account.$accountId.$appId.logs/route.tsx +++ b/app/routes/account.$accountId.$appId.logs/route.tsx @@ -45,6 +45,7 @@ export const loader: LoaderFunction = async ({ request, params }) => { error: false, }) } catch (error) { + console.error(error) return json>({ data: null, error: true, diff --git a/app/routes/account.$accountId.$appId.security/components/ApprovedChainsModal/ApprovedChainsModal.tsx b/app/routes/account.$accountId.$appId.security/components/ApprovedChainsModal/ApprovedChainsModal.tsx index 8e15c02fb..5e7914b3b 100644 --- a/app/routes/account.$accountId.$appId.security/components/ApprovedChainsModal/ApprovedChainsModal.tsx +++ b/app/routes/account.$accountId.$appId.security/components/ApprovedChainsModal/ApprovedChainsModal.tsx @@ -39,7 +39,6 @@ const ApprovedChainsModal = ({ ) const deleteSelectedChain = (chainId: string) => { - console.log(chainId) setSelectedBlockchainsIds((ids) => ids.filter((id) => chainId !== id)) } diff --git a/app/routes/account.$accountId.$appId.security/components/WhitelistUserAgentsModal/WhitelistUserAgentsModal.tsx b/app/routes/account.$accountId.$appId.security/components/WhitelistUserAgentsModal/WhitelistUserAgentsModal.tsx index 75d777f47..4e43fb158 100644 --- a/app/routes/account.$accountId.$appId.security/components/WhitelistUserAgentsModal/WhitelistUserAgentsModal.tsx +++ b/app/routes/account.$accountId.$appId.security/components/WhitelistUserAgentsModal/WhitelistUserAgentsModal.tsx @@ -29,7 +29,6 @@ const WhitelistUserAgentsModal = ({ dispatch }: WhitelistUserAgentsModalProps) = const [selectedUserAgents, setSelectedUserAgents] = useState([]) const [inputUserAgent, setInputUserAgent] = useState("") const deletedAgent = (deletedAgent: string) => { - console.log(deletedAgent) setSelectedUserAgents((agents) => agents.filter((agent) => agent !== deletedAgent)) } diff --git a/app/routes/account.$accountId.$appId.team/components/TeamMemberAction/TeamMemberAction.tsx b/app/routes/account.$accountId.$appId.team/components/TeamMemberAction/TeamMemberAction.tsx index 75159042e..87b066eef 100644 --- a/app/routes/account.$accountId.$appId.team/components/TeamMemberAction/TeamMemberAction.tsx +++ b/app/routes/account.$accountId.$appId.team/components/TeamMemberAction/TeamMemberAction.tsx @@ -1,7 +1,7 @@ import { ActionIcon, Flex, Menu, Text } from "@pokt-foundation/pocket-blocks" import React, { useMemo } from "react" import { LuMinusCircle, LuMoreHorizontal, LuSend } from "react-icons/lu" -import { AccountUserAccess, PortalApp, RoleNameV2, User } from "~/models/portal/sdk" +import { PortalApp, PortalAppUser, RoleNameV2, User } from "~/models/portal/sdk" import useTeamModals from "~/routes/account.$accountId.$appId.team/hooks/useTeamModals" import useCommonStyles from "~/styles/commonStyles" @@ -9,7 +9,7 @@ type TeamMemberActionProps = { app: PortalApp userRole: RoleNameV2 | null user?: User - teamMember: AccountUserAccess & { accepted: boolean; roleName: RoleNameV2 | null } + teamMember: PortalAppUser status: Boolean } @@ -30,13 +30,14 @@ const TeamMemberAction = ({ switch (userRole) { case RoleNameV2.Owner: - if (teamMember.userID === user?.portalUserID) { + if (teamMember.portalAppUserID === user?.portalUserID) { // OWNER --CANNOT-- LEAVE THEIR OWN APP } else { // OWNER --CAN--REMOVE OTHER USERS items.push({ icon: , - onClick: () => openRemoveUserModal(teamMember.email, teamMember.userID), + onClick: () => + openRemoveUserModal(teamMember.email, teamMember.portalAppUserID), label: "Remove", }) if (!status) { @@ -50,18 +51,20 @@ const TeamMemberAction = ({ } break case RoleNameV2.Admin: - if (teamMember.userID === user?.portalUserID) { + if (teamMember.portalAppUserID === user?.portalUserID) { // ADMIN --CAN--REMOVE THEMSELVES items.push({ icon: , - onClick: () => openRemoveUserModal(teamMember.email, teamMember.userID), + onClick: () => + openRemoveUserModal(teamMember.email, teamMember.portalAppUserID), label: "Remove", }) } else { // ADMIN --CAN--REMOVE OTHER USERS items.push({ icon: , - onClick: () => openRemoveUserModal(teamMember.email, teamMember.userID), + onClick: () => + openRemoveUserModal(teamMember.email, teamMember.portalAppUserID), label: "Remove", }) if (!status) { @@ -76,11 +79,12 @@ const TeamMemberAction = ({ break case RoleNameV2.Member: default: - if (teamMember.userID === user?.portalUserID) { + if (teamMember.portalAppUserID === user?.portalUserID) { // MEMEBER --CAN-- LEAVE APP THEMSELVES items.push({ icon: , - onClick: () => openLeaveTeamModal(teamMember.email, teamMember.userID), + onClick: () => + openLeaveTeamModal(teamMember.email, teamMember.portalAppUserID), label: "Leave", }) } else { @@ -92,7 +96,7 @@ const TeamMemberAction = ({ return items }, [ userRole, - teamMember.userID, + teamMember.portalAppUserID, teamMember.email, user?.portalUserID, status, diff --git a/app/routes/account.$accountId.$appId.team/components/TeamMembersTable/TeamMembersTable.tsx b/app/routes/account.$accountId.$appId.team/components/TeamMembersTable/TeamMembersTable.tsx index 7fe2c4060..b13c5c286 100644 --- a/app/routes/account.$accountId.$appId.team/components/TeamMembersTable/TeamMembersTable.tsx +++ b/app/routes/account.$accountId.$appId.team/components/TeamMembersTable/TeamMembersTable.tsx @@ -11,7 +11,6 @@ import Identicon from "~/components/Identicon" import { PortalApp, RoleName, RoleNameV2, User } from "~/models/portal/sdk" import TeamMemberAction from "~/routes/account.$accountId.$appId.team/components/TeamMemberAction" import useTeamModals from "~/routes/account.$accountId.$appId.team/hooks/useTeamModals" -import { getAppAcceptedValue, getUserRole } from "~/utils/applicationUtils" type TeamMembersTableProps = { app: PortalApp @@ -22,26 +21,22 @@ type TeamMembersTableProps = { const TeamMembersTable = ({ app, userRole, user }: TeamMembersTableProps) => { const { openChangeRoleModal } = useTeamModals({ app }) - const teamData = app.users - .map((user) => ({ - ...user, - roleName: getUserRole(app, user.userID), - accepted: getAppAcceptedValue(app, user.userID), - })) - .sort((a, b) => Number(b.owner) - Number(a.owner)) + const teamData = app.portalAppUsers.sort( + (a, b) => Number(b.roleName === "OWNER") - Number(a.roleName === "OWNER"), + ) return ( { + data={teamData.map(({ email, roleName, accepted, portalAppUserID }, index) => { return { member: { element: ( @@ -71,7 +66,7 @@ const TeamMembersTable = ({ app, userRole, user }: TeamMembersTableProps) => { disabled={!accepted} onChange={(value) => value !== roleName && - openChangeRoleModal(email, userID, value as RoleName) + openChangeRoleModal(email, portalAppUserID, value as RoleName) } /> diff --git a/app/routes/account.$accountId.$appId/route.tsx b/app/routes/account.$accountId.$appId/route.tsx index 5f1d3d311..ddb011a11 100644 --- a/app/routes/account.$accountId.$appId/route.tsx +++ b/app/routes/account.$accountId.$appId/route.tsx @@ -21,6 +21,7 @@ import useActionNotification from "~/hooks/useActionNotification" import { initPortalClient } from "~/models/portal/portal.server" import { Blockchain, PortalApp, RoleNameV2 } from "~/models/portal/sdk" import { DataStruct } from "~/types/global" +import { getUserRole } from "~/utils/applicationUtils" import { getErrorMessage } from "~/utils/catchError" import { seo_title_append } from "~/utils/seo" import { requireUser } from "~/utils/user.server" @@ -126,7 +127,7 @@ export type AppIdOutletContext = AppIdLoaderData & { export default function AppIdLayout() { const { data, error, message } = useLoaderData() as DataStruct - const { userRoles } = useOutletContext() + const { user } = useOutletContext() const actionData = useActionData() as DataStruct // handle all notifications at the layout level @@ -137,7 +138,7 @@ export default function AppIdLayout() { } const { app, blockchains } = data - const userRole = userRoles.find((r) => r.portalAppID === app.id)?.roleName as RoleNameV2 + const userRole = getUserRole(app.portalAppUsers, user.portalUserID) as RoleNameV2 return ( diff --git a/app/routes/account.$accountId._index/route.tsx b/app/routes/account.$accountId._index/route.tsx index 8c7c53284..604551a30 100644 --- a/app/routes/account.$accountId._index/route.tsx +++ b/app/routes/account.$accountId._index/route.tsx @@ -71,6 +71,7 @@ export const loader: LoaderFunction = async ({ request, params }) => { error: false, }) } catch (error) { + console.error(error) return json>({ data: null, error: true, diff --git a/app/routes/account.$accountId._index/view.tsx b/app/routes/account.$accountId._index/view.tsx index 7687c8c25..a80a84650 100644 --- a/app/routes/account.$accountId._index/view.tsx +++ b/app/routes/account.$accountId._index/view.tsx @@ -55,12 +55,12 @@ export const AccountInsightsView = ({ data }: AccountInsightsViewProps) => { ( - - Total Relays{" "} - + + Total Relays + {commify(total?.countTotal ?? 0)} - + )} @@ -78,12 +78,12 @@ export const AccountInsightsView = ({ data }: AccountInsightsViewProps) => { ( - - Average Latency{" "} - + + Average Latency + {commify(total?.avgLatency ?? 0)}ms - + )} @@ -99,12 +99,12 @@ export const AccountInsightsView = ({ data }: AccountInsightsViewProps) => { ( - - Success Rate{" "} - + + Success Rate + {commify(total?.rateSuccess ?? 0)}% - + )} @@ -122,12 +122,12 @@ export const AccountInsightsView = ({ data }: AccountInsightsViewProps) => { ( - - Total Errors{" "} - + + Total Errors + {totalErrors ? commify(totalErrors) : 0} - + )} diff --git a/app/routes/account.$accountId/route.tsx b/app/routes/account.$accountId/route.tsx index 85bb64ffe..18fbc21a9 100644 --- a/app/routes/account.$accountId/route.tsx +++ b/app/routes/account.$accountId/route.tsx @@ -9,7 +9,6 @@ import { GetUserAccountQuery, GetUserAccountsQuery, PortalApp, - PortalAppRole, User, } from "~/models/portal/sdk" import { DataStruct } from "~/types/global" @@ -21,7 +20,6 @@ export type AccountIdLoaderData = { accounts: GetUserAccountsQuery["getUserAccounts"] user: User hasPendingInvites: boolean - userRoles: PortalAppRole[] } export const loader: LoaderFunction = async ({ request, params }) => { @@ -53,9 +51,6 @@ export const loader: LoaderFunction = async ({ request, params }) => { accounts: userAccounts.getUserAccounts, user: user.user, hasPendingInvites: userPendingApps.getUserPortalApps.length > 0, - userRoles: account.getUserAccount.users.filter( - (u) => u.userID === user.user.portalUserID, - )[0].portalAppRoles, }, error: false, }) @@ -67,7 +62,8 @@ export const loader: LoaderFunction = async ({ request, params }) => { let ownerAccount = userAccounts?.getUserAccounts?.find( (account) => - account?.users?.find((u) => u.userID === user.user.portalUserID)?.owner, + account?.accountUsers?.find((u) => u.accountUserID === user.user.portalUserID) + ?.owner, ) if (accountId !== ownerAccount?.id) { @@ -89,7 +85,7 @@ export default function AccountId() { return } - const { account, accounts, user, userRoles, hasPendingInvites } = data + const { account, accounts, user, hasPendingInvites } = data return ( - + ) } diff --git a/app/routes/account_.$accountId.$appId.update/route.tsx b/app/routes/account_.$accountId.$appId.update/route.tsx index 4fa32c6d1..c41ab52d4 100644 --- a/app/routes/account_.$accountId.$appId.update/route.tsx +++ b/app/routes/account_.$accountId.$appId.update/route.tsx @@ -55,7 +55,7 @@ export const loader: LoaderFunction = async ({ request, params }) => { const isUserMember = getUserRole( - getUserPortalAppResponse.getUserPortalApp as PortalApp, + getUserPortalAppResponse.getUserPortalApp.portalAppUsers, user.user.portalUserID, ) === "MEMBER" diff --git a/app/routes/account_.$accountId.create/components/AppForm/AppForm.tsx b/app/routes/account_.$accountId.create/components/AppForm/AppForm.tsx index ba4fd2d1c..4539b2821 100644 --- a/app/routes/account_.$accountId.create/components/AppForm/AppForm.tsx +++ b/app/routes/account_.$accountId.create/components/AppForm/AppForm.tsx @@ -38,7 +38,7 @@ const AppForm = ({ app, onSubmit }: AppFormProps) => { const [name, setName] = useState(app?.name ?? "") const [referral, setReferral] = useState("") - const [appmoji, setAppmoji] = useState(DEFAULT_APPMOJI) + const [appmoji, setAppmoji] = useState(app?.appEmoji ?? DEFAULT_APPMOJI) useEffect(() => { const rid = window.localStorage.getItem("rid") diff --git a/app/routes/user.accounts/components/AccountsTable/AccountsTable.tsx b/app/routes/user.accounts/components/AccountsTable/AccountsTable.tsx index f9b0eea9a..a520d7e59 100644 --- a/app/routes/user.accounts/components/AccountsTable/AccountsTable.tsx +++ b/app/routes/user.accounts/components/AccountsTable/AccountsTable.tsx @@ -16,7 +16,7 @@ const AccountsTable = ({ accounts, user }: AccountsTableProps) => { const sortedAccounts = useMemo(() => { const ownedAccount = accounts.find((account) => - account.users.find((u) => u.userID === user.portalUserID && u.owner), + account?.accountUsers.find((u) => u.accountUserID === user.portalUserID && u.owner), ) const filteredAccounts = accounts.filter(({ id }) => id !== ownedAccount?.id) return [ @@ -56,8 +56,8 @@ const AccountsTable = ({ accounts, user }: AccountsTableProps) => { members: { element: ( - {account?.users?.length} Member - {account?.users?.length > 1 ? "s" : ""} + {account?.accountUsers?.length} Member + {account?.accountUsers?.length > 1 ? "s" : ""} ), }, diff --git a/app/routes/user.invited-apps/view.tsx b/app/routes/user.invited-apps/view.tsx index aabcffd77..f6d76df3b 100644 --- a/app/routes/user.invited-apps/view.tsx +++ b/app/routes/user.invited-apps/view.tsx @@ -20,8 +20,8 @@ export const UserInvitedApps = ({ apps, user }: UserInvitedAppsProps) => { return apps .map((app) => ({ ...app, - accepted: getAppAcceptedValue(app, user.portalUserID), - role: getUserRole(app, user.portalUserID), + accepted: getAppAcceptedValue(app.portalAppUsers, user.portalUserID), + role: getUserRole(app.portalAppUsers, user.portalUserID), })) .sort((a, b) => Number(a.accepted) - Number(b.accepted)) .filter((app) => app.role !== RoleNameV2.Owner) diff --git a/app/styles/root.css b/app/styles/root.css index aa3e39b11..3d3295ce3 100644 --- a/app/styles/root.css +++ b/app/styles/root.css @@ -119,5 +119,5 @@ button.pokt-button-with__icon:hover { } .clickable-table tbody tr:hover { - background-color: rgba(37, 38, 43, 0.50) !important -} \ No newline at end of file + background-color: rgba(37, 38, 43, 0.5) !important; +} diff --git a/app/utils/applicationUtils.ts b/app/utils/applicationUtils.ts index 613d5c15b..8601f9da3 100644 --- a/app/utils/applicationUtils.ts +++ b/app/utils/applicationUtils.ts @@ -1,29 +1,11 @@ -import { PortalApp } from "~/models/portal/sdk" +import { PortalAppUser } from "~/models/portal/sdk" -export const getAppAcceptedValue = (app: PortalApp, userId: string) => { - const user = app.users.find((user) => user.userID === userId) - - if (user) { - const acceptedEntry = user.portalAppsAccepted.find( - (entry) => entry.portalAppID === app.id, - ) - - return acceptedEntry ? acceptedEntry.accepted : false - } - - return false +export const getAppAcceptedValue = (portalAppUsers: PortalAppUser[], userId: string) => { + const user = portalAppUsers.find((user) => user.portalAppUserID === userId) + return user?.accepted ?? false } -export const getUserRole = (app: PortalApp, userId: string) => { - const user = app.users.find((user) => user.userID === userId) - - if (user) { - const role = user.portalAppRoles.find((role) => role.portalAppID === app.id) - - if (role) { - return role.roleName - } - } - - return null +export const getUserRole = (portalAppUsers: PortalAppUser[], userId: string) => { + const user = portalAppUsers.find((user) => user.portalAppUserID === userId) + return user?.roleName ?? null } diff --git a/app/utils/chartUtils.ts b/app/utils/chartUtils.ts index 034241b63..14aadd2fb 100644 --- a/app/utils/chartUtils.ts +++ b/app/utils/chartUtils.ts @@ -3,7 +3,11 @@ import { AnalyticsRelaysAggregated, AnalyticsRelaysTotal } from "~/models/dwh/sd export const getTotalErrors = ( aggregatedData: AnalyticsRelaysAggregated | AnalyticsRelaysTotal, ) => { - if (!aggregatedData || !aggregatedData.rateError || !aggregatedData.countTotal) { + if ( + !aggregatedData || + !aggregatedData.countTotal || + (!aggregatedData.rateError && aggregatedData?.rateError !== 0) + ) { return null } diff --git a/app/utils/user.server.ts b/app/utils/user.server.ts index 25a4c5330..ed56038a6 100644 --- a/app/utils/user.server.ts +++ b/app/utils/user.server.ts @@ -103,7 +103,9 @@ export const redirectToUserAccount = async (user: AuthUser) => { let account = accounts.getUserAccounts[0] as Partial let owner = accounts.getUserAccounts.find( - (account) => account?.users.find((u) => u.userID === user.user.portalUserID)?.owner, + (account) => + account?.accountUsers.find((u) => u.accountUserID === user.user.portalUserID) + ?.owner, ) if (owner) { diff --git a/app/utils/user.ts b/app/utils/user.ts index 5f736c727..66efea5ad 100644 --- a/app/utils/user.ts +++ b/app/utils/user.ts @@ -11,6 +11,8 @@ const isUserAccountOwner = ({ }) => accounts .find(({ id }) => accountId === id) - ?.users.some((u) => u.userID === user.portalUserID && u.owner) as boolean + ?.accountUsers.some( + (u) => u.accountUserID === user.portalUserID && u.owner, + ) as boolean export default isUserAccountOwner