Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add member role badges to user card model #1195

Merged
merged 6 commits into from
Aug 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions packages/common/src/core/types/IHubCardViewModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,19 @@ export interface IHubCardViewModel {
export interface IBadgeConfig {
i18nKey?: string;
label?: string;
/**
* whether the label or translated i18nKey
* should actually render or just be used
* for a11y purposes. By default, the label
* IS rendered
*/
hideLabel?: boolean;
icon?: string;
color: string;
tooltip?: {
i18nKey?: string;
label?: string;
};
}

// structure defining the additional info for a hub card
Expand All @@ -40,6 +51,11 @@ export interface ICardActionLink {
href?: string;
i18nKey?: string;
label?: string;
/**
* whether the label or translated i18nKey
* should actually render or just be used
* for a11y purposes
*/
showLabel?: boolean;
icon?: string;
buttonStyle?: "outline" | "outline-fill" | "solid" | "transparent";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ async function searchGroupMembers(
// over the includes and requestOptions
const fn = (member: IGroupMember) => {
return memberToSearchResult(
member,
{ ...member, isGroupOwner: resp.owner.username === member.username },
searchOptions.include,
searchOptions.requestOptions
);
Expand Down Expand Up @@ -179,7 +179,7 @@ interface IGroupMember {
* @returns
*/
async function memberToSearchResult(
member: IGroupMember,
member: IGroupMember & { isGroupOwner: boolean },
include: string[] = [],
requestOptions?: IHubRequestOptions
): Promise<IHubSearchResult> {
Expand All @@ -199,6 +199,7 @@ async function memberToSearchResult(
thumbnail: null,
created: null,
modified: null,
isGroupOwner: member.isGroupOwner,
};

const fsGetUser = failSafe(getUser, user);
Expand Down
10 changes: 9 additions & 1 deletion packages/common/src/users/HubUsers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ export async function enrichUserSearchResult(
access: user.access as AccessLevel,
id: user.username,
type: "User",
/**
* We need to return a valid IHubSearchResult, so we store
* IUser information where it makes the most sense - e.g.
* we store the user's full name under the "name" property,
* and since users don't have an owner, we fill that property
* with the user's username
*/
name: user.fullName,
owner: user.username,
// A private user will not have a description prop at all
Expand All @@ -42,9 +49,10 @@ export async function enrichUserSearchResult(
thumbnail: null,
},
};
// Group Memberships need this prop
// Group Memberships need these additional properties
if (user.memberType) {
result.memberType = user.memberType;
result.isGroupOwner = user.isGroupOwner;
}

// Informal Enrichments - basically adding type-specific props
Expand Down
39 changes: 38 additions & 1 deletion packages/common/src/users/view.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { IHubSearchResult } from "..";
import { ResultToCardModelFn } from "../core";
import {
IBadgeConfig,
IConvertToCardModelOpts,
IHubCardViewModel,
} from "../core/types/IHubCardViewModel";
Expand Down Expand Up @@ -44,9 +45,45 @@ export const userResultToCardModel: ResultToCardModelFn = (
* @param locale internationalization locale
*/
const getSharedUserCardModel = (user: IHubSearchResult): IHubCardViewModel => {
const badges = [] as IBadgeConfig[];
const memberType = user.memberType;

/**
* for group members, we want to configure
* member type badges to render in the user
* card
*/
if (memberType) {
if (user.isGroupOwner) {
badges.push({
icon: "user-key",
color: "gray",
i18nKey: "badges.members.owner",
hideLabel: true,
tooltip: { i18nKey: "badges.members.owner" },
});
} else if (memberType === "admin") {
badges.push({
icon: "user-up",
color: "gray",
i18nKey: "badges.members.admin",
hideLabel: true,
tooltip: { i18nKey: "badges.members.admin" },
});
} else {
badges.push({
icon: "user",
color: "gray",
i18nKey: "badges.members.member",
hideLabel: true,
tooltip: { i18nKey: "badges.members.member" },
});
}
}

return {
access: user.access,
badges: [],
badges,
family: user.family,
id: user.id,
source: user.name ? `@${user.id}` : undefined,
Expand Down
51 changes: 51 additions & 0 deletions packages/common/test/users/view.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,56 @@ describe("user view module:", () => {
expect(result.title).toBe(`@${USER_HUB_SEARCH_RESULT.owner}`);
expect(result.source).toBeFalsy();
});
describe("membership badges", () => {
it("adds an owner badge if the user is the group owner", () => {
const GROUP_MEMBER_RESULT = cloneObject(USER_HUB_SEARCH_RESULT);
GROUP_MEMBER_RESULT.isGroupOwner = true;
GROUP_MEMBER_RESULT.memberType = "admin";

const result = userResultToCardModel(GROUP_MEMBER_RESULT);

expect(result.badges).toEqual([
{
icon: "user-key",
color: "gray",
i18nKey: "badges.members.owner",
hideLabel: true,
tooltip: { i18nKey: "badges.members.owner" },
},
]);
});
it("adds an amin badge if the user is a group admin", () => {
const GROUP_MEMBER_RESULT = cloneObject(USER_HUB_SEARCH_RESULT);
GROUP_MEMBER_RESULT.memberType = "admin";

const result = userResultToCardModel(GROUP_MEMBER_RESULT);

expect(result.badges).toEqual([
{
icon: "user-up",
color: "gray",
i18nKey: "badges.members.admin",
hideLabel: true,
tooltip: { i18nKey: "badges.members.admin" },
},
]);
});
it("adds a member badge if the user is a group member", () => {
const GROUP_MEMBER_RESULT = cloneObject(USER_HUB_SEARCH_RESULT);
GROUP_MEMBER_RESULT.memberType = "member";

const result = userResultToCardModel(GROUP_MEMBER_RESULT);

expect(result.badges).toEqual([
{
icon: "user",
color: "gray",
i18nKey: "badges.members.member",
hideLabel: true,
tooltip: { i18nKey: "badges.members.member" },
},
]);
});
});
});
});