• 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/main/search/searchResults/useHydratedCard.tsx
1
import {
2
  CommunityMembershipStatus,
3
  SearchResultOrganizationFragment,
4
  SearchResultPostFragment,
5
  SearchResultSpaceFragment,
6
  SearchResultType,
7
  SearchResultUserFragment,
8
  SpaceLevel,
9
  UserRolesSearchCardsQuery,
10
  VisualType,
11
} from '@/core/apollo/generated/graphql-schema';
12
import { RoleType } from '@/domain/community/user/constants/RoleType';
13
import { getVisualByType } from '@/domain/common/visual/utils/visuals.utils';
14
import { useUserRolesSearchCardsQuery } from '@/core/apollo/generated/apollo-hooks';
15
import { useCurrentUserContext } from '@/domain/community/userCurrent/useCurrentUserContext';
16
import { TypedSearchResult } from '../SearchView';
17
import { SearchContributionCardCard } from '@/domain/shared/components/search-cards/SearchContributionPostCard';
18
import { SpaceL1Icon } from '@/domain/space/icons/SpaceL1Icon';
19
import { SpaceL0Icon } from '@/domain/space/icons/SpaceL0Icon';
20
import ContributingUserCard from '@/domain/community/user/ContributingUserCard/ContributingUserCard';
21
import CardContent from '@/core/ui/card/CardContent';
22
import ContributingOrganizationCard from '@/domain/community/organization/ContributingOrganizationCard/ContributingOrganizationCard';
23
import CardParentSpaceSegment from '@/domain/space/components/cards/components/CardParentSpaceSegment';
24
import SearchSpaceCard from '@/domain/shared/components/search-cards/base/SearchSpaceCard';
25
import { spaceLevelIcon } from '@/domain/space/icons/SpaceIconByLevel';
26
import { ComponentType } from 'react';
27
import { SvgIconProps } from '@mui/material';
28

29
const hydrateUserCard = (data: TypedSearchResult<SearchResultType.User, SearchResultUserFragment>) => {
30
  const user = data.user;
31
  const profile = user.profile;
32
  const avatarUri = profile.visual?.uri;
×
33
  const { country, city } = profile.location ?? {};
×
34
  const tags = profile.tagsets?.[0]?.tags ?? [];
×
35

×
36
  return (
×
37
    <ContributingUserCard
×
38
      id={user.id}
×
39
      displayName={user.profile.displayName}
40
      description={profile.description}
×
41
      avatarUri={avatarUri}
42
      city={city}
43
      country={country}
44
      tags={tags}
45
      userUri={user.profile.url}
46
      matchedTerms={data.terms}
47
      isContactable={user.isContactable}
48
    />
49
  );
50
};
51

52
const _hydrateOrganizationCard = (
53
  data: TypedSearchResult<SearchResultType.Organization, SearchResultOrganizationFragment>,
54
  userRoles: UserRolesSearchCardsQuery['rolesUser'] | undefined
55
) => {
56
  const organization = data.organization;
×
57
  const profile = data.organization.profile;
58
  const avatarUri = profile.visual?.uri;
59
  const { country, city } = profile.location ?? {};
60
  const url = organization.profile.url;
×
61
  const tags = profile.tagsets?.[0]?.tags ?? [];
×
62

×
63
  const organizationRoles = userRoles?.organizations.find(x => x.id === organization.id);
×
64
  const isMember = organizationRoles?.roles.some(x => x === RoleType.Associate);
×
65

×
66
  return (
67
    <ContributingOrganizationCard
×
68
      displayName={organization.profile.displayName}
×
69
      description={profile.description}
70
      avatarUri={avatarUri}
×
71
      city={city}
72
      country={country}
73
      tags={tags}
74
      userUri={url}
75
      member={isMember}
76
      matchedTerms={data.terms}
77
    />
78
  );
79
};
80

81
const hydrateSpaceCard = (
82
  data: TypedSearchResult<SearchResultType.Space | SearchResultType.Subspace, SearchResultSpaceFragment>
83
) => {
84
  const space = data.space;
85
  const spaceProfile = space.about.profile;
×
86
  const tagline = spaceProfile?.tagline ?? '';
87
  const name = spaceProfile.displayName;
88
  const tags = space.about.profile.tagset?.tags;
89
  const vision = space.about.why ?? '';
90

91
  const isMember = space.about.membership.myMembershipStatus === CommunityMembershipStatus.Member;
×
92

×
93
  const parentSegment = (
×
94
    data: TypedSearchResult<SearchResultType.Space | SearchResultType.Subspace, SearchResultSpaceFragment>
×
95
  ) => {
×
96
    if (!data.parentSpace) {
NEW
97
      return null;
×
98
    }
99

×
100
    const parentIcon = data.parentSpace.level === SpaceLevel.L0 ? SpaceL0Icon : SpaceL1Icon;
101

102
    return (
103
      <CardParentSpaceSegment
104
        iconComponent={parentIcon}
105
        parentSpaceUri={data.parentSpace?.about.profile.url ?? ''}
×
106
        locked={!data.parentSpace?.about.isContentPublic}
×
107
      >
108
        {data.parentSpace?.about.profile.displayName}
109
      </CardParentSpaceSegment>
×
110
    );
111
  };
×
112

113
  return (
114
    <SearchSpaceCard
×
115
      spaceLevel={space.level}
116
      banner={getVisualByType(VisualType.Card, spaceProfile.visuals)}
117
      member={isMember}
118
      displayName={name}
119
      tagline={tagline}
120
      spaceUri={spaceProfile.url}
121
      tags={tags}
122
      matchedTerms
×
123
      vision={vision}
124
      locked={!space.about.isContentPublic}
125
      spaceVisibility={space.visibility}
126
      parentSegment={parentSegment(data)}
127
    />
128
  );
129
};
130

131
interface ContributionParentInformation {
132
  displayName: string;
133
  locked: boolean;
134
  url: string;
135
  icon: ComponentType<SvgIconProps>;
136
}
137

138
const getContributionParentInformation = (
139
  data: TypedSearchResult<SearchResultType.Post, SearchResultPostFragment>
140
): ContributionParentInformation => {
×
141
  return {
×
142
    displayName: data.space.about.profile.displayName,
143
    locked: !data.space?.about.isContentPublic,
144
    url: data.space.about.profile.url,
145
    icon: spaceLevelIcon[data.space.level] ?? SpaceL0Icon,
146
  };
147
};
148

×
149
const hydrateContributionPost = (data: TypedSearchResult<SearchResultType.Post, SearchResultPostFragment>) => {
×
150
  if (!data?.post) {
×
151
    return null;
×
152
  }
×
153

×
154
  const card = data.post;
155

156
  const parent = getContributionParentInformation(data);
×
157

158
  return (
159
    <SearchContributionCardCard
×
160
      name={card.profile.displayName}
×
161
      author={card.createdBy?.profile.displayName}
×
162
      description={card.profile.description}
163
      tags={card.profile.tagset?.tags}
164
      createdDate={card.createdDate}
×
165
      commentsCount={card.comments?.messagesCount}
166
      matchedTerms={data.terms}
×
167
      url={data.post.profile.url}
168
      parentSegment={
×
169
        <CardContent>
170
          <CardParentSpaceSegment parentSpaceUri={data.callout.framing.profile.url}>
171
            {data.callout.framing.profile.displayName}
172
          </CardParentSpaceSegment>
173
          <CardParentSpaceSegment iconComponent={parent.icon} parentSpaceUri={parent.url} locked={parent.locked}>
174
            {parent.displayName}
175
          </CardParentSpaceSegment>
176
        </CardContent>
177
      }
178
    />
179
  );
180
};
181

182
interface HydratedCardGetter<Data> {
183
  (data: Data): null | React.ReactElement;
184
}
185

186
interface UseHydrateCardProvided {
187
  hydrateUserCard: HydratedCardGetter<TypedSearchResult<SearchResultType.User, SearchResultUserFragment>>;
188
  hydrateOrganizationCard: HydratedCardGetter<
189
    TypedSearchResult<SearchResultType.Organization, SearchResultOrganizationFragment>
190
  >;
191
  hydrateContributionCard: HydratedCardGetter<TypedSearchResult<SearchResultType.Post, SearchResultPostFragment>>;
192
  hydrateSpaceCard: HydratedCardGetter<
193
    TypedSearchResult<SearchResultType.Space | SearchResultType.Subspace, SearchResultSpaceFragment>
194
  >;
195
}
196

197
export const useHydrateCard = (): UseHydrateCardProvided => {
198
  const { userModel } = useCurrentUserContext();
199
  const userId = userModel?.id;
200

201
  const { data: rolesData } = useUserRolesSearchCardsQuery({
202
    variables: {
203
      userId: userId!,
204
    },
205
    skip: !userId,
206
  });
207

208
  const userRoles = rolesData?.rolesUser;
209

210
  const hydrateOrganizationCard = (
×
211
    result: TypedSearchResult<SearchResultType.Organization, SearchResultOrganizationFragment>
×
212
  ) => _hydrateOrganizationCard(result, userRoles);
×
213

214
  return {
×
215
    hydrateSpaceCard,
216
    hydrateContributionCard: hydrateContributionPost,
217
    hydrateUserCard,
218
    hydrateOrganizationCard,
219
  };
220
};
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