diff --git a/packages/backend/src/graphql/queries/get-connected-apps.js b/packages/backend/src/graphql/queries/get-connected-apps.js deleted file mode 100644 index 3826c746..00000000 --- a/packages/backend/src/graphql/queries/get-connected-apps.js +++ /dev/null @@ -1,67 +0,0 @@ -import App from '../../models/app.js'; -import Flow from '../../models/flow.js'; -import Connection from '../../models/connection.js'; - -const getConnectedApps = async (_parent, params, context) => { - const conditions = context.currentUser.can('read', 'Connection'); - - const userConnections = context.currentUser.$relatedQuery('connections'); - const allConnections = Connection.query(); - const connectionBaseQuery = conditions.isCreator - ? userConnections - : allConnections; - - const userFlows = context.currentUser.$relatedQuery('flows'); - const allFlows = Flow.query(); - const flowBaseQuery = conditions.isCreator ? userFlows : allFlows; - - let apps = await App.findAll(params.name); - - const connections = await connectionBaseQuery - .clone() - .select('connections.key') - .where({ draft: false }) - .count('connections.id as count') - .groupBy('connections.key'); - - const flows = await flowBaseQuery - .clone() - .withGraphJoined('steps') - .orderBy('created_at', 'desc'); - - const duplicatedUsedApps = flows - .map((flow) => flow.steps.map((step) => step.appKey)) - .flat() - .filter(Boolean); - - const connectionKeys = connections.map((connection) => connection.key); - const usedApps = [...new Set([...duplicatedUsedApps, ...connectionKeys])]; - - apps = apps - .filter((app) => { - return usedApps.includes(app.key); - }) - .map((app) => { - const connection = connections.find( - (connection) => connection.key === app.key - ); - - app.connectionCount = connection?.count || 0; - app.flowCount = 0; - - flows.forEach((flow) => { - const usedFlow = flow.steps.find((step) => step.appKey === app.key); - - if (usedFlow) { - app.flowCount += 1; - } - }); - - return app; - }) - .sort((appA, appB) => appA.name.localeCompare(appB.name)); - - return apps; -}; - -export default getConnectedApps; diff --git a/packages/backend/src/graphql/query-resolvers.js b/packages/backend/src/graphql/query-resolvers.js deleted file mode 100644 index 758fbc6e..00000000 --- a/packages/backend/src/graphql/query-resolvers.js +++ /dev/null @@ -1,7 +0,0 @@ -import getConnectedApps from './queries/get-connected-apps.js'; - -const queryResolvers = { - getConnectedApps, -}; - -export default queryResolvers; diff --git a/packages/backend/src/graphql/resolvers.js b/packages/backend/src/graphql/resolvers.js index 344c0416..70021c51 100644 --- a/packages/backend/src/graphql/resolvers.js +++ b/packages/backend/src/graphql/resolvers.js @@ -1,8 +1,6 @@ import mutationResolvers from './mutation-resolvers.js'; -import queryResolvers from './query-resolvers.js'; const resolvers = { - Query: queryResolvers, Mutation: mutationResolvers, }; diff --git a/packages/backend/src/graphql/schema.graphql b/packages/backend/src/graphql/schema.graphql index 780c509e..2a5454d3 100644 --- a/packages/backend/src/graphql/schema.graphql +++ b/packages/backend/src/graphql/schema.graphql @@ -1,7 +1,6 @@ type Query { - getConnectedApps(name: String): [App] + placeholderQuery(name: String): Boolean } - type Mutation { createAppConfig(input: CreateAppConfigInput): AppConfig createAppAuthClient(input: CreateAppAuthClientInput): AppAuthClient diff --git a/packages/backend/src/helpers/authentication.js b/packages/backend/src/helpers/authentication.js index 32bb2c9e..5ba9ae57 100644 --- a/packages/backend/src/helpers/authentication.js +++ b/packages/backend/src/helpers/authentication.js @@ -40,9 +40,6 @@ export const authenticateUser = async (request, response, next) => { const isAuthenticatedRule = rule()(isAuthenticated); export const authenticationRules = { - Query: { - '*': isAuthenticatedRule, - }, Mutation: { '*': isAuthenticatedRule, forgotPassword: allow, diff --git a/packages/backend/src/helpers/authentication.test.js b/packages/backend/src/helpers/authentication.test.js index 691a7628..f2b06d2a 100644 --- a/packages/backend/src/helpers/authentication.test.js +++ b/packages/backend/src/helpers/authentication.test.js @@ -42,19 +42,21 @@ describe('authentication rules', () => { const { queries, mutations } = getQueryAndMutationNames(authenticationRules); - describe('for queries', () => { - queries.forEach((query) => { - it(`should apply correct rule for query: ${query}`, () => { - const ruleApplied = authenticationRules.Query[query]; + if (queries.length) { + describe('for queries', () => { + queries.forEach((query) => { + it(`should apply correct rule for query: ${query}`, () => { + const ruleApplied = authenticationRules.Query[query]; - if (query === '*') { - expect(ruleApplied.func).toBe(isAuthenticated); - } else { - expect(ruleApplied).toEqual(allow); - } + if (query === '*') { + expect(ruleApplied.func).toBe(isAuthenticated); + } else { + expect(ruleApplied).toEqual(allow); + } + }); }); }); - }); + } describe('for mutations', () => { mutations.forEach((mutation) => { diff --git a/packages/web/src/graphql/queries/get-connected-apps.js b/packages/web/src/graphql/queries/get-connected-apps.js deleted file mode 100644 index 01cb8aa8..00000000 --- a/packages/web/src/graphql/queries/get-connected-apps.js +++ /dev/null @@ -1,15 +0,0 @@ -import { gql } from '@apollo/client'; -export const GET_CONNECTED_APPS = gql` - query GetConnectedApps($name: String) { - getConnectedApps(name: $name) { - key - name - iconUrl - docUrl - primaryColor - connectionCount - flowCount - supportsConnections - } - } -`; diff --git a/packages/web/src/hooks/useUserApps.js b/packages/web/src/hooks/useUserApps.js new file mode 100644 index 00000000..3c082445 --- /dev/null +++ b/packages/web/src/hooks/useUserApps.js @@ -0,0 +1,25 @@ +import { useQuery } from '@tanstack/react-query'; +import useCurrentUser from 'hooks/useCurrentUser'; +import api from 'helpers/api'; + +export default function useUserApps(appName) { + const { data } = useCurrentUser(); + const userId = data?.data.id; + + const query = useQuery({ + queryKey: ['users', userId, 'apps', appName], + queryFn: async ({ signal }) => { + const { data } = await api.get(`/v1/users/${userId}/apps`, { + signal, + params: { + ...(appName && { name: appName }), + }, + }); + + return data; + }, + enabled: !!userId, + }); + + return query; +} diff --git a/packages/web/src/pages/Applications/index.jsx b/packages/web/src/pages/Applications/index.jsx index bd8bb6ae..ed5940bb 100644 --- a/packages/web/src/pages/Applications/index.jsx +++ b/packages/web/src/pages/Applications/index.jsx @@ -1,6 +1,5 @@ import * as React from 'react'; import { Link, Routes, Route, useNavigate } from 'react-router-dom'; -import { useQuery } from '@apollo/client'; import Box from '@mui/material/Box'; import Grid from '@mui/material/Grid'; import Divider from '@mui/material/Divider'; @@ -15,23 +14,25 @@ import PageTitle from 'components/PageTitle'; import AppRow from 'components/AppRow'; import SearchInput from 'components/SearchInput'; import useFormatMessage from 'hooks/useFormatMessage'; -import { GET_CONNECTED_APPS } from 'graphql/queries/get-connected-apps'; import * as URLS from 'config/urls'; +import useUserApps from 'hooks/useUserApps'; + export default function Applications() { const navigate = useNavigate(); const formatMessage = useFormatMessage(); const [appName, setAppName] = React.useState(null); - const { data, loading } = useQuery(GET_CONNECTED_APPS, { - variables: { name: appName }, - }); - const apps = data?.getConnectedApps; + const { data, isLoading } = useUserApps(appName); + const apps = data?.data; const hasApps = apps?.length; + const onSearchChange = React.useCallback((event) => { setAppName(event.target.value); }, []); + const goToApps = React.useCallback(() => { navigate(URLS.APPS); }, [navigate]); + return ( @@ -75,21 +76,21 @@ export default function Applications() { - {loading && ( + {isLoading && ( )} - {!loading && !hasApps && ( + {!isLoading && !hasApps && ( )} - {!loading && + {!isLoading && apps?.map((app) => ( ))}