From c4a8d05548ac68c12efa95c4b40444a4666108bc Mon Sep 17 00:00:00 2001 From: lcampbell Date: Wed, 24 May 2023 14:34:46 -0300 Subject: [PATCH 1/3] add isVerified filter option to query --- .../load-organization-connections-by-user-id.js | 13 +++++++++++-- .../organization/queries/find-my-organizations.js | 14 ++++++-------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/api/src/organization/loaders/load-organization-connections-by-user-id.js b/api/src/organization/loaders/load-organization-connections-by-user-id.js index 35b9cc0527..00e09e103d 100644 --- a/api/src/organization/loaders/load-organization-connections-by-user-id.js +++ b/api/src/organization/loaders/load-organization-connections-by-user-id.js @@ -19,6 +19,7 @@ export const loadOrgConnectionsByUserId = ({ search, isAdmin, includeSuperAdminOrg, + isVerified, }) => { const userDBId = `users/${userKey}` @@ -372,12 +373,18 @@ export const loadOrgConnectionsByUserId = ({ includeSuperAdminOrgQuery = aql`FILTER org.orgDetails.en.slug != "super-admin" OR org.orgDetails.fr.slug != "super-admin"` } + let isVerifiedQuery = aql`` + if (isVerified) { + isVerifiedQuery = aql`FILTER org.verified == true` + } + let orgKeysQuery if (isSuperAdmin) { orgKeysQuery = aql` WITH claims, domains, organizations, organizationSearch LET orgKeys = ( FOR org IN organizations + ${isVerifiedQuery} ${includeSuperAdminOrgQuery} RETURN org._key ) @@ -388,8 +395,8 @@ export const loadOrgConnectionsByUserId = ({ LET orgKeys = ( FOR org, e IN 1..1 INBOUND ${userDBId} affiliations - FILTER e.permission == "admin" - OR e.permission == "super_admin" + FILTER e.permission == "admin" OR e.permission == "super_admin" + ${isVerifiedQuery} ${includeSuperAdminOrgQuery} RETURN org._key ) @@ -400,6 +407,7 @@ export const loadOrgConnectionsByUserId = ({ WITH claims, domains, organizations, organizationSearch LET orgKeys = ( FOR org IN organizations + ${isVerifiedQuery} FILTER org.orgDetails.en.slug != "super-admin" OR org.orgDetails.fr.slug != "super-admin" RETURN org._key ) @@ -410,6 +418,7 @@ export const loadOrgConnectionsByUserId = ({ LET orgKeys = ( FOR org, e IN 1..1 INBOUND ${userDBId} affiliations + ${isVerifiedQuery} ${includeSuperAdminOrgQuery} RETURN org._key ) diff --git a/api/src/organization/queries/find-my-organizations.js b/api/src/organization/queries/find-my-organizations.js index a468ac6125..2c4752208f 100644 --- a/api/src/organization/queries/find-my-organizations.js +++ b/api/src/organization/queries/find-my-organizations.js @@ -22,8 +22,11 @@ export const findMyOrganizations = { }, includeSuperAdminOrg: { type: GraphQLBoolean, - description: - 'Filter org list to either include or exclude the super admin org.', + description: 'Filter org list to either include or exclude the super admin org.', + }, + isVerified: { + type: GraphQLBoolean, + description: 'Filter org list to include only verified organizations.', }, ...connectionArgs, }, @@ -32,12 +35,7 @@ export const findMyOrganizations = { args, { userKey, - auth: { - checkSuperAdmin, - userRequired, - verifiedRequired, - loginRequiredBool, - }, + auth: { checkSuperAdmin, userRequired, verifiedRequired, loginRequiredBool }, loaders: { loadOrgConnectionsByUserId }, }, ) => { From 1d0cbbc0228ff1234b7821e86fb4632579cca372 Mon Sep 17 00:00:00 2001 From: lcampbell Date: Wed, 24 May 2023 14:39:57 -0300 Subject: [PATCH 2/3] add switch on organizations page --- frontend/src/graphql/queries.js | 2 + frontend/src/organizations/Organizations.js | 17 +++- .../__tests__/Organizations.test.js | 80 +++++++------------ 3 files changed, 47 insertions(+), 52 deletions(-) diff --git a/frontend/src/graphql/queries.js b/frontend/src/graphql/queries.js index ea7588da83..edb5554632 100644 --- a/frontend/src/graphql/queries.js +++ b/frontend/src/graphql/queries.js @@ -9,6 +9,7 @@ export const PAGINATED_ORGANIZATIONS = gql` $direction: OrderDirection! $search: String $includeSuperAdminOrg: Boolean + $isVerified: Boolean ) { findMyOrganizations( after: $after @@ -16,6 +17,7 @@ export const PAGINATED_ORGANIZATIONS = gql` orderBy: { field: $field, direction: $direction } search: $search includeSuperAdminOrg: $includeSuperAdminOrg + isVerified: $isVerified ) { edges { cursor diff --git a/frontend/src/organizations/Organizations.js b/frontend/src/organizations/Organizations.js index 216675ceb0..4d03371225 100644 --- a/frontend/src/organizations/Organizations.js +++ b/frontend/src/organizations/Organizations.js @@ -1,11 +1,11 @@ import React, { useCallback, useState } from 'react' import { t, Trans } from '@lingui/macro' import { ListOf } from '../components/ListOf' -import { Box, Divider, Flex, Heading, IconButton, Text, useDisclosure } from '@chakra-ui/react' +import { Box, Divider, Flex, Heading, IconButton, Switch, Text, useDisclosure } from '@chakra-ui/react' import { ErrorBoundary } from 'react-error-boundary' import { OrganizationCard } from './OrganizationCard' - +import { CheckCircleIcon } from '@chakra-ui/icons' import { ErrorFallbackMessage } from '../components/ErrorFallbackMessage' import { LoadingMessage } from '../components/LoadingMessage' import { RelayPaginationControls } from '../components/RelayPaginationControls' @@ -28,6 +28,7 @@ export default function Organizations() { const [orgsPerPage, setOrgsPerPage] = useState(10) const { isOpen: inviteRequestIsOpen, onOpen, onClose } = useDisclosure() const [orgInfo, setOrgInfo] = useState({}) + const [isVerified, setIsVerified] = useState(true) const memoizedSetDebouncedSearchTermCallback = useCallback(() => { setDebouncedSearchTerm(searchTerm) @@ -45,6 +46,7 @@ export default function Organizations() { direction: orderDirection, search: debouncedSearchTerm, includeSuperAdminOrg: false, + isVerified, }, fetchPolicy: 'cache-and-network', nextFetchPolicy: 'cache-first', @@ -166,6 +168,17 @@ export default function Organizations() { placeholder={t`Search for an organization`} onToggle={onToggle} /> + + setIsVerified(e.target.checked)} + /> + + {orgList} ', () => { direction: 'ASC', search: '', includeSuperAdminOrg: false, + isVerified: true, }, }, result: { @@ -89,7 +90,7 @@ describe('', () => { name: 'organization one', slug: 'organization-one', domainCount: 5, - verified: false, + verified: true, summaries, __typename: 'Organizations', }, @@ -103,7 +104,7 @@ describe('', () => { name: 'organization two', slug: 'organization-two', domainCount: 5, - verified: false, + verified: true, summaries, __typename: 'Organizations', }, @@ -135,10 +136,7 @@ describe('', () => { > - + @@ -148,9 +146,7 @@ describe('', () => { ) // expect(getByText(/organization two/i)).toBeInTheDocument(), - await waitFor(() => - expect(getByText(/organization one/i)).toBeInTheDocument(), - ) + await waitFor(() => expect(getByText(/organization one/i)).toBeInTheDocument()) }) it('navigates to an organization detail page when a link is clicked', async () => { @@ -164,6 +160,7 @@ describe('', () => { direction: 'ASC', search: '', includeSuperAdminOrg: false, + isVerified: true, }, }, result: { @@ -178,7 +175,7 @@ describe('', () => { name: 'organization one', slug: 'organization-one', domainCount: 5, - verified: false, + verified: true, summaries, __typename: 'Organizations', }, @@ -220,7 +217,7 @@ describe('', () => { name: 'organization two', slug: 'organization-two', domainCount: 5, - verified: false, + verified: true, summaries, __typename: 'Organizations', }, @@ -262,7 +259,7 @@ describe('', () => { name: 'organization two', slug: 'organization-two', domainCount: 5, - verified: false, + verified: true, summaries, __typename: 'Organizations', }, @@ -319,10 +316,7 @@ describe('', () => { - } - /> + } /> @@ -334,11 +328,7 @@ describe('', () => { const cardLink = await findByRole('link', /organization one/i) userEvent.click(cardLink) - await waitFor(() => - expect(history.location.pathname).toEqual( - '/organizations/organization-one', - ), - ) + await waitFor(() => expect(history.location.pathname).toEqual('/organizations/organization-one')) }) }) @@ -355,6 +345,7 @@ describe('', () => { direction: 'ASC', search: '', includeSuperAdminOrg: false, + isVerified: true, }, }, result: { @@ -369,7 +360,7 @@ describe('', () => { name: 'organization one', slug: 'organization-one', domainCount: 5, - verified: false, + verified: true, summaries, __typename: 'Organizations', }, @@ -398,6 +389,7 @@ describe('', () => { direction: 'ASC', search: '', includeSuperAdminOrg: false, + isVerified: true, }, }, result: { @@ -412,7 +404,7 @@ describe('', () => { name: 'organization two', slug: 'organization-two', domainCount: 5, - verified: false, + verified: true, summaries, __typename: 'Organizations', }, @@ -453,10 +445,7 @@ describe('', () => { - } - /> + } /> @@ -465,25 +454,19 @@ describe('', () => { , ) - await waitFor(() => - expect(getByText(/organization one/)).toBeInTheDocument(), - ) + await waitFor(() => expect(getByText(/organization one/)).toBeInTheDocument()) const next = await waitFor(() => getAllByLabelText('Next page')) fireEvent.click(next[0]) - await waitFor(() => - expect(getByText(/organization two/)).toBeInTheDocument(), - ) + await waitFor(() => expect(getByText(/organization two/)).toBeInTheDocument()) const previous = await waitFor(() => getAllByLabelText('Previous page')) fireEvent.click(previous[0]) - await waitFor(() => - expect(getByText(/organization one/)).toBeInTheDocument(), - ) + await waitFor(() => expect(getByText(/organization one/)).toBeInTheDocument()) }) }) @@ -498,6 +481,7 @@ describe('', () => { direction: 'ASC', search: '', includeSuperAdminOrg: false, + isVerified: true, }, data: { findMyOrganizations: { @@ -510,7 +494,7 @@ describe('', () => { name: 'organization one', slug: 'organization-one', domainCount: 5, - verified: false, + verified: true, summaries, __typename: 'Organizations', }, @@ -539,6 +523,7 @@ describe('', () => { direction: 'ASC', search: '', includeSuperAdminOrg: false, + isVerified: true, }, }, result: { @@ -553,7 +538,7 @@ describe('', () => { name: 'organization one', slug: 'organization-one', domainCount: 5, - verified: false, + verified: true, summaries, __typename: 'Organizations', }, @@ -582,6 +567,7 @@ describe('', () => { direction: 'ASC', search: '', includeSuperAdminOrg: false, + isVerified: true, }, }, result: { @@ -596,7 +582,7 @@ describe('', () => { name: 'organization two', slug: 'organization-two', domainCount: 5, - verified: false, + verified: true, summaries, __typename: 'Organizations', }, @@ -625,6 +611,7 @@ describe('', () => { direction: 'ASC', search: '', includeSuperAdminOrg: false, + isVerified: true, }, }, result: { @@ -639,7 +626,7 @@ describe('', () => { name: 'organization two', slug: 'organization-two', domainCount: 5, - verified: false, + verified: true, summaries, __typename: 'Organizations', }, @@ -678,10 +665,7 @@ describe('', () => { - } - /> + } /> @@ -690,17 +674,13 @@ describe('', () => { , ) - await waitFor(() => - expect(queryByText(/organization one/)).toBeInTheDocument(), - ) + await waitFor(() => expect(queryByText(/organization one/)).toBeInTheDocument()) const next = getAllByLabelText('Next page') fireEvent.click(next[0]) - await waitFor(() => - expect(queryByText(/organization two/)).toBeInTheDocument(), - ) + await waitFor(() => expect(queryByText(/organization two/)).toBeInTheDocument()) }) }) }) From a2f43a03e5dee63746fd20427e9d4964a49169a4 Mon Sep 17 00:00:00 2001 From: lcampbell Date: Wed, 24 May 2023 14:45:16 -0300 Subject: [PATCH 3/3] update faked schema --- frontend/mocking/faked_schema.js | 3 +++ frontend/src/organizations/Organizations.js | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/frontend/mocking/faked_schema.js b/frontend/mocking/faked_schema.js index 509f47838e..77978c63d0 100644 --- a/frontend/mocking/faked_schema.js +++ b/frontend/mocking/faked_schema.js @@ -112,6 +112,9 @@ export const getTypeNames = () => gql` # Filter org list to either include or exclude the super admin org. includeSuperAdminOrg: Boolean + # Filter org list to include only verified organizations. + isVerified: Boolean + # Returns the items in the list that come after the specified cursor. after: String diff --git a/frontend/src/organizations/Organizations.js b/frontend/src/organizations/Organizations.js index 4d03371225..be6b50094c 100644 --- a/frontend/src/organizations/Organizations.js +++ b/frontend/src/organizations/Organizations.js @@ -171,8 +171,7 @@ export default function Organizations() { setIsVerified(e.target.checked)}