• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

alkem-io / client-web / #9048

11 Oct 2024 01:42PM UTC coverage: 5.943%. First build
#9048

Pull #7022

travis-ci

Pull Request #7022: [v0.74.0] Roles API + Unauthenticated Explore page

202 of 10241 branches covered (1.97%)

Branch coverage included in aggregate %.

63 of 431 new or added lines in 60 files covered. (14.62%)

1468 of 17861 relevant lines covered (8.22%)

0.19 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/domain/community/user/ContributorsPage.tsx
1
import { useState, ChangeEvent, useMemo } from 'react';
2
import { useTranslation } from 'react-i18next';
3
import { InputAdornment, OutlinedInput } from '@mui/material';
4
import SearchIcon from '@mui/icons-material/Search';
5
import { debounce } from 'lodash';
6
import { useCurrentUserContext } from '../userCurrent/useCurrentUserContext';
7
import ContributorsView, { ITEMS_PER_PAGE } from './ContributorsView';
8
import TopLevelPageLayout from '@/main/ui/layout/topLevelPageLayout/TopLevelPageLayout';
9
import PageContentColumn from '@/core/ui/content/PageContentColumn';
10
import PageContentBlockSeamless from '@/core/ui/content/PageContentBlockSeamless';
11
import useInnovationHubOutsideRibbon from '@/domain/innovationHub/InnovationHubOutsideRibbon/useInnovationHubOutsideRibbon';
12
import { GroupOutlined } from '@mui/icons-material';
13
import TopLevelPageBreadcrumbs from '@/main/topLevelPages/topLevelPageBreadcrumbs/TopLevelPageBreadcrumbs';
14
import GroupOutlinedIcon from '@mui/icons-material/GroupOutlined';
15
import BreadcrumbsItem from '@/core/ui/navigation/BreadcrumbsItem';
16
import {
17
  useContributorsPageOrganizationsQuery,
18
  useContributorsPageUsersQuery,
19
  useContributorsVirtualInLibraryQuery,
20
} from '@/core/apollo/generated/apollo-hooks';
×
21
import {
×
22
  ContributorsPageOrganizationsQuery,
23
  ContributorsPageOrganizationsQueryVariables,
NEW
24
  ContributorsPageUsersQuery,
×
25
  ContributorsPageUsersQueryVariables,
26
  OrganizationContributorFragment,
×
27
  OrganizationVerificationEnum,
×
28
  UserContributorFragment,
29
} from '@/core/apollo/generated/graphql-schema';
×
30
import { arrayShuffle } from '@/core/utils/array.shuffle';
31
import usePaginatedQuery from '@/domain/shared/pagination/usePaginatedQuery';
×
32
import { VirtualContributorModelBase } from '../virtualContributor/model/VirtualContributorModelBase';
33
import { ApolloError } from '@apollo/client';
×
34

×
35
export interface VirtualContributors {
×
36
  items: VirtualContributorModelBase[] | undefined;
37
  loading: boolean;
38
}
×
39

40
export interface PaginatedResult<T> {
×
41
  items: T[] | undefined;
42
  hasMore: boolean | undefined;
43
  pageSize: number;
44
  firstPageSize: number;
45
  loading: boolean;
46
  error?: ApolloError;
47
  fetchMore: (itemsNumber?: number) => Promise<void>;
48
}
49

50
const ContributorsPage = () => {
51
  const { t } = useTranslation();
52

53
  // temporary disable the search (server #4545)
54
  const [searchEnabled] = useState(false);
55

×
56
  const [searchTerms, setSearchTerms] = useState('');
57

58
  const [searchTermsDebounced, setSearchTermsDebounced] = useState('');
59

60
  const { isAuthenticated } = useCurrentUserContext();
61

62
  const pageSize = ITEMS_PER_PAGE;
63

64
  const onSearchHandlerDebounced = debounce((value: string) => setSearchTermsDebounced(value), 500);
65

66
  const onSearchHandler = (e: ChangeEvent<HTMLInputElement>) => {
67
    setSearchTerms(e.target.value);
68
    onSearchHandlerDebounced(e.target.value);
69
  };
70

71
  const ribbon = useInnovationHubOutsideRibbon({ label: 'innovationHub.outsideOfSpace.contributors' });
72

×
73
  const usersQueryResult = usePaginatedQuery<ContributorsPageUsersQuery, ContributorsPageUsersQueryVariables>({
74
    useQuery: useContributorsPageUsersQuery,
75
    options: {
76
      fetchPolicy: 'cache-first',
77
      nextFetchPolicy: 'cache-first',
78
      skip: !isAuthenticated,
79
    },
80
    variables: {
81
      withTags: true,
82
      filter: { firstName: searchTermsDebounced, lastName: searchTermsDebounced, email: searchTermsDebounced },
83
    },
84
    pageSize: pageSize,
85
    getPageInfo: result => result.usersPaginated.pageInfo,
86
  });
87

88
  const randomizedUsers = useMemo(() => {
89
    // if the length changed, shuffle only the new portion of the array
90
    // to avoid re-rendering the entire list
91
    const users = usersQueryResult.data?.usersPaginated.users;
92

93
    if (!users) {
94
      return [];
95
    }
96

97
    const randomizedNewUsers = arrayShuffle(users.slice(-pageSize));
98

99
    return [...users.slice(0, users.length - pageSize), ...randomizedNewUsers];
100
  }, [usersQueryResult.data?.usersPaginated.users?.length]);
101

102
  const users: PaginatedResult<UserContributorFragment> = {
103
    items: randomizedUsers,
104
    loading: usersQueryResult.loading,
105
    hasMore: usersQueryResult.hasMore,
106
    pageSize: usersQueryResult.pageSize,
107
    firstPageSize: usersQueryResult.firstPageSize,
108
    error: usersQueryResult.error,
109
    fetchMore: usersQueryResult.fetchMore,
110
  };
111

112
  const organizationsQueryResult = usePaginatedQuery<
113
    ContributorsPageOrganizationsQuery,
114
    ContributorsPageOrganizationsQueryVariables
115
  >({
116
    useQuery: useContributorsPageOrganizationsQuery,
117
    options: {
118
      fetchPolicy: 'cache-first',
119
      nextFetchPolicy: 'cache-first',
120
    },
121
    variables: {
122
      status: OrganizationVerificationEnum.VerifiedManualAttestation,
123
      filter: {
124
        contactEmail: searchTerms,
125
        displayName: searchTerms,
126
        domain: searchTerms,
127
        nameID: searchTerms,
128
        website: searchTerms,
129
      },
130
    },
131
    pageSize: pageSize,
132
    getPageInfo: result => result.organizationsPaginated.pageInfo,
133
  });
134

135
  const organizations: PaginatedResult<OrganizationContributorFragment> = {
136
    items: organizationsQueryResult.data?.organizationsPaginated.organization,
137
    loading: organizationsQueryResult.loading,
138
    hasMore: organizationsQueryResult.hasMore,
139
    pageSize: organizationsQueryResult.pageSize,
140
    firstPageSize: organizationsQueryResult.firstPageSize,
141
    error: organizationsQueryResult.error,
142
    fetchMore: organizationsQueryResult.fetchMore,
143
  };
144

145
  const { data: vcData, loading: loadingVCs } = useContributorsVirtualInLibraryQuery();
146

147
  const virtualContributors = {
148
    items: vcData?.platform.library.virtualContributors ?? [],
149
    loading: loadingVCs,
150
  };
151

152
  return (
153
    <TopLevelPageLayout
154
      title={t('pages.contributors.search.title')}
155
      subtitle={t('pages.contributors.search.subtitle')}
156
      iconComponent={GroupOutlined}
157
      ribbon={ribbon}
158
      breadcrumbs={
159
        <TopLevelPageBreadcrumbs>
160
          <BreadcrumbsItem uri="/contributors" iconComponent={GroupOutlinedIcon}>
161
            {t('pages.contributors.shortName')}
162
          </BreadcrumbsItem>
163
        </TopLevelPageBreadcrumbs>
164
      }
165
    >
166
      <PageContentColumn columns={12}>
167
        {searchEnabled && (
168
          <PageContentBlockSeamless disablePadding>
169
            <OutlinedInput
170
              value={searchTerms}
171
              sx={{ width: '100%' }}
172
              placeholder={t('components.searchableList.placeholder')}
173
              onChange={onSearchHandler}
174
              endAdornment={
175
                <InputAdornment position="end">
176
                  <SearchIcon />
177
                </InputAdornment>
178
              }
179
            />
180
          </PageContentBlockSeamless>
181
        )}
182
        <ContributorsView
183
          usersPaginated={users}
184
          showUsers={isAuthenticated}
185
          organizationsPaginated={organizations}
186
          virtualContributors={virtualContributors}
187
        />
188
      </PageContentColumn>
189
    </TopLevelPageLayout>
190
  );
191
};
192

193
export default ContributorsPage;
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc