fix: replaced first name, last name or email to display name (#1796)

* fix: replacing first, last name and email with display name

* fix: different endpoint for workspace & project member

* fix: falling back to email if display_name doesn't exist
This commit is contained in:
Dakshesh Jain 2023-08-08 13:01:43 +05:30 committed by GitHub
parent cf306ee605
commit 981acc81c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
62 changed files with 333 additions and 419 deletions

View File

@ -16,15 +16,7 @@ export const CustomTooltip: React.FC<Props> = ({ datum, analytics, params }) =>
if (params.segment) { if (params.segment) {
if (DATE_KEYS.includes(params.segment)) tooltipValue = renderMonthAndYear(datum.id); if (DATE_KEYS.includes(params.segment)) tooltipValue = renderMonthAndYear(datum.id);
else if (params.segment === "assignees__email") { else tooltipValue = datum.id;
const assignee = analytics.extras.assignee_details.find(
(a) => a.assignees__email === datum.id
);
if (assignee)
tooltipValue = assignee.assignees__first_name + " " + assignee.assignees__last_name;
else tooltipValue = "No assignees";
} else tooltipValue = datum.id;
} else { } else {
if (DATE_KEYS.includes(params.x_axis)) tooltipValue = datum.indexValue; if (DATE_KEYS.includes(params.x_axis)) tooltipValue = datum.indexValue;
else tooltipValue = datum.id === "count" ? "Issue count" : "Estimate"; else tooltipValue = datum.id === "count" ? "Issue count" : "Estimate";

View File

@ -70,17 +70,17 @@ export const AnalyticsGraph: React.FC<Props> = ({
height={fullScreen ? "400px" : "300px"} height={fullScreen ? "400px" : "300px"}
margin={{ margin={{
right: 20, right: 20,
bottom: params.x_axis === "assignees__email" ? 50 : longestXAxisLabel.length * 5 + 20, bottom: params.x_axis === "assignees__id" ? 50 : longestXAxisLabel.length * 5 + 20,
}} }}
axisBottom={{ axisBottom={{
tickSize: 0, tickSize: 0,
tickPadding: 10, tickPadding: 10,
tickRotation: barGraphData.data.length > 7 ? -45 : 0, tickRotation: barGraphData.data.length > 7 ? -45 : 0,
renderTick: renderTick:
params.x_axis === "assignees__email" params.x_axis === "assignees__id"
? (datum) => { ? (datum) => {
const avatar = analytics.extras.assignee_details?.find( const avatar = analytics.extras.assignee_details?.find(
(a) => a?.assignees__email === datum?.value (a) => a?.assignees__display_name === datum?.value
)?.assignees__avatar; )?.assignees__avatar;
if (avatar && avatar !== "") if (avatar && avatar !== "")

View File

@ -277,9 +277,7 @@ export const AnalyticsSidebar: React.FC<Props> = ({
<div className="space-y-4 mt-4"> <div className="space-y-4 mt-4">
<div className="flex items-center gap-2 text-xs"> <div className="flex items-center gap-2 text-xs">
<h6 className="text-custom-text-200">Lead</h6> <h6 className="text-custom-text-200">Lead</h6>
<span> <span>{cycleDetails.owned_by?.display_name}</span>
{cycleDetails.owned_by?.first_name} {cycleDetails.owned_by?.last_name}
</span>
</div> </div>
<div className="flex items-center gap-2 text-xs"> <div className="flex items-center gap-2 text-xs">
<h6 className="text-custom-text-200">Start Date</h6> <h6 className="text-custom-text-200">Start Date</h6>
@ -305,10 +303,7 @@ export const AnalyticsSidebar: React.FC<Props> = ({
<div className="space-y-4 mt-4"> <div className="space-y-4 mt-4">
<div className="flex items-center gap-2 text-xs"> <div className="flex items-center gap-2 text-xs">
<h6 className="text-custom-text-200">Lead</h6> <h6 className="text-custom-text-200">Lead</h6>
<span> <span>{moduleDetails.lead_detail?.display_name}</span>
{moduleDetails.lead_detail?.first_name}{" "}
{moduleDetails.lead_detail?.last_name}
</span>
</div> </div>
<div className="flex items-center gap-2 text-xs"> <div className="flex items-center gap-2 text-xs">
<h6 className="text-custom-text-200">Start Date</h6> <h6 className="text-custom-text-200">Start Date</h6>

View File

@ -21,19 +21,7 @@ type Props = {
yAxisKey: "count" | "estimate"; yAxisKey: "count" | "estimate";
}; };
export const AnalyticsTable: React.FC<Props> = ({ analytics, barGraphData, params, yAxisKey }) => { export const AnalyticsTable: React.FC<Props> = ({ analytics, barGraphData, params, yAxisKey }) => (
const renderAssigneeName = (email: string): string => {
const assignee = analytics.extras.assignee_details.find((a) => a.assignees__email === email);
if (!assignee) return "No assignee";
if (assignee.assignees__first_name !== "")
return assignee.assignees__first_name + " " + assignee.assignees__last_name;
return email;
};
return (
<div className="flow-root"> <div className="flow-root">
<div className="overflow-x-auto"> <div className="overflow-x-auto">
<div className="inline-block min-w-full align-middle"> <div className="inline-block min-w-full align-middle">
@ -65,11 +53,7 @@ export const AnalyticsTable: React.FC<Props> = ({ analytics, barGraphData, param
}} }}
/> />
)} )}
{DATE_KEYS.includes(params.segment ?? "") {DATE_KEYS.includes(params.segment ?? "") ? renderMonthAndYear(key) : key}
? renderMonthAndYear(key)
: params.segment === "assignees__email"
? renderAssigneeName(key)
: key}
</div> </div>
</th> </th>
)) ))
@ -108,9 +92,7 @@ export const AnalyticsTable: React.FC<Props> = ({ analytics, barGraphData, param
}} }}
/> />
)} )}
{params.x_axis === "assignees__email" {addSpaceIfCamelCase(`${item.name}`)}
? renderAssigneeName(`${item.name}`)
: addSpaceIfCamelCase(`${item.name}`)}
</td> </td>
{params.segment ? ( {params.segment ? (
barGraphData.xAxisKeys.map((key, index) => ( barGraphData.xAxisKeys.map((key, index) => (
@ -132,4 +114,3 @@ export const AnalyticsTable: React.FC<Props> = ({ analytics, barGraphData, param
</div> </div>
</div> </div>
); );
};

View File

@ -1,7 +1,7 @@
type Props = { type Props = {
users: { users: {
avatar: string | null; avatar: string | null;
email: string | null; display_name: string | null;
firstName: string; firstName: string;
lastName: string; lastName: string;
count: number; count: number;
@ -16,7 +16,7 @@ export const AnalyticsLeaderboard: React.FC<Props> = ({ users, title }) => (
<div className="mt-3 space-y-3"> <div className="mt-3 space-y-3">
{users.map((user) => ( {users.map((user) => (
<div <div
key={user.email ?? "None"} key={user.display_name ?? "None"}
className="flex items-start justify-between gap-4 text-xs" className="flex items-start justify-between gap-4 text-xs"
> >
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
@ -25,16 +25,16 @@ export const AnalyticsLeaderboard: React.FC<Props> = ({ users, title }) => (
<img <img
src={user.avatar} src={user.avatar}
className="absolute top-0 left-0 h-full w-full object-cover rounded-full" className="absolute top-0 left-0 h-full w-full object-cover rounded-full"
alt={user.email ?? "None"} alt={user.display_name ?? "None"}
/> />
</div> </div>
) : ( ) : (
<div className="grid place-items-center flex-shrink-0 rounded-full bg-gray-700 text-[11px] capitalize text-white h-4 w-4"> <div className="grid place-items-center flex-shrink-0 rounded-full bg-gray-700 text-[11px] capitalize text-white h-4 w-4">
{user.firstName !== "" ? user.firstName[0] : "?"} {user.display_name !== "" ? user?.display_name?.[0] : "?"}
</div> </div>
)} )}
<span className="break-words text-custom-text-200"> <span className="break-words text-custom-text-200">
{user.firstName !== "" ? `${user.firstName} ${user.lastName}` : "No assignee"} {user.display_name !== "" ? `${user.display_name}` : "No assignee"}
</span> </span>
</div> </div>
<span className="flex-shrink-0">{user.count}</span> <span className="flex-shrink-0">{user.count}</span>

View File

@ -56,9 +56,9 @@ export const ScopeAndDemand: React.FC<Props> = ({ fullScreen = true }) => {
<AnalyticsLeaderboard <AnalyticsLeaderboard
users={defaultAnalytics.most_issue_created_user?.map((user) => ({ users={defaultAnalytics.most_issue_created_user?.map((user) => ({
avatar: user?.created_by__avatar, avatar: user?.created_by__avatar,
email: user?.created_by__email,
firstName: user?.created_by__first_name, firstName: user?.created_by__first_name,
lastName: user?.created_by__last_name, lastName: user?.created_by__last_name,
display_name: user?.created_by__display_name,
count: user?.count, count: user?.count,
}))} }))}
title="Most issues created" title="Most issues created"
@ -66,9 +66,9 @@ export const ScopeAndDemand: React.FC<Props> = ({ fullScreen = true }) => {
<AnalyticsLeaderboard <AnalyticsLeaderboard
users={defaultAnalytics.most_issue_closed_user?.map((user) => ({ users={defaultAnalytics.most_issue_closed_user?.map((user) => ({
avatar: user?.assignees__avatar, avatar: user?.assignees__avatar,
email: user?.assignees__email,
firstName: user?.assignees__first_name, firstName: user?.assignees__first_name,
lastName: user?.assignees__last_name, lastName: user?.assignees__last_name,
display_name: user?.assignees__display_name,
count: user?.count, count: user?.count,
}))} }))}
title="Most issues closed" title="Most issues closed"

View File

@ -16,23 +16,20 @@ export const AnalyticsScope: React.FC<Props> = ({ defaultAnalytics }) => (
{defaultAnalytics.pending_issue_user.length > 0 ? ( {defaultAnalytics.pending_issue_user.length > 0 ? (
<BarGraph <BarGraph
data={defaultAnalytics.pending_issue_user} data={defaultAnalytics.pending_issue_user}
indexBy="assignees__email" indexBy="assignees__display_name"
keys={["count"]} keys={["count"]}
height="250px" height="250px"
colors={() => `#f97316`} colors={() => `#f97316`}
customYAxisTickValues={defaultAnalytics.pending_issue_user.map((d) => d.count)} customYAxisTickValues={defaultAnalytics.pending_issue_user.map((d) => d.count)}
tooltip={(datum) => { tooltip={(datum) => {
const assignee = defaultAnalytics.pending_issue_user.find( const assignee = defaultAnalytics.pending_issue_user.find(
(a) => a.assignees__email === `${datum.indexValue}` (a) => a.assignees__display_name === `${datum.indexValue}`
); );
return ( return (
<div className="rounded-md border border-custom-border-200 bg-custom-background-80 p-2 text-xs"> <div className="rounded-md border border-custom-border-200 bg-custom-background-80 p-2 text-xs">
<span className="font-medium text-custom-text-200"> <span className="font-medium text-custom-text-200">
{assignee {assignee ? assignee.assignees__display_name : "No assignee"}:{" "}
? assignee.assignees__first_name + " " + assignee.assignees__last_name
: "No assignee"}
:{" "}
</span> </span>
{datum.value} {datum.value}
</div> </div>

View File

@ -34,15 +34,12 @@ export const ChangeIssueAssignee: React.FC<Props> = ({ setIsPaletteOpen, issue,
const options = const options =
members?.map(({ member }) => ({ members?.map(({ member }) => ({
value: member.id, value: member.id,
query: query: member.display_name,
(member.first_name && member.first_name !== "" ? member.first_name : member.email) +
" " +
member.last_name ?? "",
content: ( content: (
<> <>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Avatar user={member} /> <Avatar user={member} />
{member.first_name && member.first_name !== "" ? member.first_name : member.email} {member.display_name}
</div> </div>
{issue.assignees.includes(member.id) && ( {issue.assignees.includes(member.id) && (
<div> <div>

View File

@ -157,10 +157,10 @@ export const FiltersList: React.FC<Props> = ({
return ( return (
<div <div
key={memberId} key={memberId}
className="inline-flex items-center gap-x-1 rounded-full bg-custom-background-90 px-1 capitalize" className="inline-flex items-center gap-x-1 rounded-full bg-custom-background-90 px-1"
> >
<Avatar user={member} /> <Avatar user={member} />
<span>{member?.first_name}</span> <span>{member?.display_name}</span>
<span <span
className="cursor-pointer" className="cursor-pointer"
onClick={() => onClick={() =>
@ -184,7 +184,7 @@ export const FiltersList: React.FC<Props> = ({
className="inline-flex items-center gap-x-1 rounded-full bg-custom-background-90 px-1 capitalize" className="inline-flex items-center gap-x-1 rounded-full bg-custom-background-90 px-1 capitalize"
> >
<Avatar user={member} /> <Avatar user={member} />
<span>{member?.first_name}</span> <span>{member?.display_name}</span>
<span <span
className="cursor-pointer" className="cursor-pointer"
onClick={() => onClick={() =>

View File

@ -62,7 +62,7 @@ export const LinksList: React.FC<Props> = ({ links, handleDeleteLink, userAuth }
by{" "} by{" "}
{link.created_by_detail.is_bot {link.created_by_detail.is_bot
? link.created_by_detail.first_name + " Bot" ? link.created_by_detail.first_name + " Bot"
: link.created_by_detail.email} : link.created_by_detail.display_name}
</p> </p>
</div> </div>
</a> </a>

View File

@ -133,9 +133,10 @@ export const SidebarProgressStats: React.FC<Props> = ({
avatar: assignee.avatar ?? "", avatar: assignee.avatar ?? "",
first_name: assignee.first_name ?? "", first_name: assignee.first_name ?? "",
last_name: assignee.last_name ?? "", last_name: assignee.last_name ?? "",
display_name: assignee.display_name ?? "",
}} }}
/> />
<span>{assignee.first_name}</span> <span>{assignee.display_name}</span>
</div> </div>
} }
completed={assignee.completed_issues} completed={assignee.completed_issues}

View File

@ -81,10 +81,7 @@ export const BoardHeader: React.FC<Props> = ({
break; break;
case "created_by": case "created_by":
const member = members?.find((member) => member.member.id === groupTitle)?.member; const member = members?.find((member) => member.member.id === groupTitle)?.member;
title = title = member?.display_name ?? "";
member?.first_name && member.first_name !== ""
? `${member.first_name} ${member.last_name}`
: member?.email ?? "";
break; break;
} }
@ -149,7 +146,9 @@ export const BoardHeader: React.FC<Props> = ({
> >
<span className="flex items-center">{getGroupIcon()}</span> <span className="flex items-center">{getGroupIcon()}</span>
<h2 <h2
className="text-lg font-semibold capitalize truncate" className={`text-lg font-semibold truncate ${
selectedGroup === "created_by" ? "" : "capitalize"
}`}
style={{ style={{
writingMode: isCollapsed ? "horizontal-tb" : "vertical-rl", writingMode: isCollapsed ? "horizontal-tb" : "vertical-rl",
}} }}

View File

@ -96,10 +96,7 @@ export const SingleList: React.FC<Props> = ({
break; break;
case "created_by": case "created_by":
const member = members?.find((member) => member.member.id === groupTitle)?.member; const member = members?.find((member) => member.member.id === groupTitle)?.member;
title = title = member?.display_name ?? "";
member?.first_name && member.first_name !== ""
? `${member.first_name} ${member.last_name}`
: member?.email ?? "";
break; break;
} }
@ -163,7 +160,11 @@ export const SingleList: React.FC<Props> = ({
<div className="flex items-center">{getGroupIcon()}</div> <div className="flex items-center">{getGroupIcon()}</div>
)} )}
{selectedGroup !== null ? ( {selectedGroup !== null ? (
<h2 className="text-sm font-semibold capitalize leading-6 text-custom-text-100"> <h2
className={`text-sm font-semibold leading-6 text-custom-text-100 ${
selectedGroup === "created_by" ? "" : "capitalize"
}`}
>
{getGroupTitle()} {getGroupTitle()}
</h2> </h2>
) : ( ) : (

View File

@ -361,14 +361,14 @@ export const ActiveCycleDetails: React.FC = () => {
height={16} height={16}
width={16} width={16}
className="rounded-full" className="rounded-full"
alt={cycle.owned_by.first_name} alt={cycle.owned_by.display_name}
/> />
) : ( ) : (
<span className="flex h-5 w-5 items-center justify-center rounded-full bg-custom-background-100 capitalize"> <span className="flex h-5 w-5 items-center justify-center rounded-full bg-custom-background-100 capitalize">
{cycle.owned_by.first_name.charAt(0)} {cycle.owned_by.display_name.charAt(0)}
</span> </span>
)} )}
<span className="text-custom-text-200">{cycle.owned_by.first_name}</span> <span className="text-custom-text-200">{cycle.owned_by.display_name}</span>
</div> </div>
{cycle.assignees.length > 0 && ( {cycle.assignees.length > 0 && (

View File

@ -88,9 +88,10 @@ export const ActiveCycleProgressStats: React.FC<Props> = ({ cycle }) => {
avatar: assignee.avatar ?? "", avatar: assignee.avatar ?? "",
first_name: assignee.first_name ?? "", first_name: assignee.first_name ?? "",
last_name: assignee.last_name ?? "", last_name: assignee.last_name ?? "",
display_name: assignee.display_name ?? "",
}} }}
/> />
<span>{assignee.first_name}</span> <span>{assignee.display_name}</span>
</div> </div>
} }
completed={assignee.completed_issues} completed={assignee.completed_issues}

View File

@ -450,14 +450,14 @@ export const CycleDetailsSidebar: React.FC<Props> = ({
height={12} height={12}
width={12} width={12}
className="rounded-full" className="rounded-full"
alt={cycle.owned_by.first_name} alt={cycle.owned_by.display_name}
/> />
) : ( ) : (
<span className="flex h-5 w-5 items-center justify-center rounded-full bg-gray-800 capitalize text-white"> <span className="flex h-5 w-5 items-center justify-center rounded-full bg-gray-800 capitalize text-white">
{cycle.owned_by.first_name.charAt(0)} {cycle.owned_by.display_name.charAt(0)}
</span> </span>
)} )}
<span className="text-custom-text-200">{cycle.owned_by.first_name}</span> <span className="text-custom-text-200">{cycle.owned_by.display_name}</span>
</div> </div>
</div> </div>

View File

@ -250,14 +250,14 @@ export const SingleCycleCard: React.FC<TSingleStatProps> = ({
height={16} height={16}
width={16} width={16}
className="rounded-full" className="rounded-full"
alt={cycle.owned_by.first_name} alt={cycle.owned_by.display_name}
/> />
) : ( ) : (
<span className="flex h-5 w-5 items-center justify-center rounded-full bg-orange-300 capitalize text-white"> <span className="flex h-5 w-5 items-center justify-center rounded-full bg-orange-300 capitalize text-white">
{cycle.owned_by.first_name.charAt(0)} {cycle.owned_by.display_name.charAt(0)}
</span> </span>
)} )}
<span className="text-custom-text-200">{cycle.owned_by.first_name}</span> <span className="text-custom-text-200">{cycle.owned_by.display_name}</span>
</div> </div>
</div> </div>
<div className="flex h-5 items-center gap-2"> <div className="flex h-5 items-center gap-2">

View File

@ -254,11 +254,11 @@ export const SingleCycleList: React.FC<TSingleStatProps> = ({
height={16} height={16}
width={16} width={16}
className="rounded-full" className="rounded-full"
alt={cycle.owned_by.first_name} alt={cycle.owned_by.display_name}
/> />
) : ( ) : (
<span className="flex h-5 w-5 items-center justify-center rounded-full bg-orange-300 capitalize text-white"> <span className="flex h-5 w-5 items-center justify-center rounded-full bg-orange-300 capitalize text-white">
{cycle.owned_by.first_name.charAt(0)} {cycle.owned_by.display_name.charAt(0)}
</span> </span>
)} )}
</div> </div>

View File

@ -44,19 +44,12 @@ export const SingleUserSelect: React.FC<Props> = ({ collaborator, index, users,
); );
const options = members?.map((member) => ({ const options = members?.map((member) => ({
value: member.member.email, value: member.member.display_name,
query: query: member.member.display_name ?? "",
(member.member.first_name && member.member.first_name !== ""
? member.member.first_name
: member.member.email) +
" " +
member.member.last_name ?? "",
content: ( content: (
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Avatar user={member.member} /> <Avatar user={member.member} />
{member.member.first_name && member.member.first_name !== "" {member.member.display_name}
? member.member.first_name + "(" + member.member.email + ")"
: member.member.email}
</div> </div>
), ),
})); }));

View File

@ -34,18 +34,11 @@ export const JiraImportUsers: FC = () => {
const options = members?.map((member) => ({ const options = members?.map((member) => ({
value: member.member.email, value: member.member.email,
query: query: member.member.display_name ?? "",
(member.member.first_name && member.member.first_name !== ""
? member.member.first_name
: member.member.email) +
" " +
member.member.last_name ?? "",
content: ( content: (
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Avatar user={member.member} /> <Avatar user={member.member} />
{member.member.first_name && member.member.first_name !== "" {member.member.display_name}
? member.member.first_name + " (" + member.member.email + ")"
: member.member.email}
</div> </div>
), ),
})); }));

View File

@ -42,12 +42,7 @@ export const SingleImport: React.FC<Props> = ({ service, refreshing, handleDelet
</h4> </h4>
<div className="mt-2 flex items-center gap-2 text-xs text-custom-text-200"> <div className="mt-2 flex items-center gap-2 text-xs text-custom-text-200">
<span>{renderShortDateWithYearFormat(service.created_at)}</span>| <span>{renderShortDateWithYearFormat(service.created_at)}</span>|
<span> <span>Imported by {service.initiated_by_detail.display_name}</span>
Imported by{" "}
{service.initiated_by_detail.first_name && service.initiated_by_detail.first_name !== ""
? service.initiated_by_detail.first_name + " " + service.initiated_by_detail.last_name
: service.initiated_by_detail.email}
</span>
</div> </div>
</div> </div>
<CustomMenu ellipsis> <CustomMenu ellipsis>

View File

@ -122,7 +122,7 @@ export const IssueActivitySection: React.FC<Props> = ({ issueId, user }) => {
activityItem.actor_detail.avatar !== "" ? ( activityItem.actor_detail.avatar !== "" ? (
<img <img
src={activityItem.actor_detail.avatar} src={activityItem.actor_detail.avatar}
alt={activityItem.actor_detail.first_name} alt={activityItem.actor_detail.display_name}
height={24} height={24}
width={24} width={24}
className="rounded-full" className="rounded-full"
@ -131,7 +131,7 @@ export const IssueActivitySection: React.FC<Props> = ({ issueId, user }) => {
<div <div
className={`grid h-7 w-7 place-items-center rounded-full border-2 border-white bg-gray-700 text-xs text-white`} className={`grid h-7 w-7 place-items-center rounded-full border-2 border-white bg-gray-700 text-xs text-white`}
> >
{activityItem.actor_detail.first_name.charAt(0)} {activityItem.actor_detail.display_name.charAt(0)}
</div> </div>
)} )}
</div> </div>
@ -150,8 +150,7 @@ export const IssueActivitySection: React.FC<Props> = ({ issueId, user }) => {
) : ( ) : (
<Link href={`/${workspaceSlug}/profile/${activityItem.actor_detail.id}`}> <Link href={`/${workspaceSlug}/profile/${activityItem.actor_detail.id}`}>
<a className="text-gray font-medium"> <a className="text-gray font-medium">
{activityItem.actor_detail.first_name}{" "} {activityItem.actor_detail.display_name}
{activityItem.actor_detail.last_name}
</a> </a>
</Link> </Link>
)}{" "} )}{" "}

View File

@ -77,7 +77,7 @@ export const IssueAttachments = () => {
<Tooltip <Tooltip
tooltipContent={`${ tooltipContent={`${
people?.find((person) => person.member.id === file.updated_by)?.member people?.find((person) => person.member.id === file.updated_by)?.member
.first_name ?? "" .display_name ?? ""
} uploaded on ${renderLongDateFormat(file.updated_at)}`} } uploaded on ${renderLongDateFormat(file.updated_at)}`}
> >
<span> <span>

View File

@ -70,7 +70,7 @@ export const CommentCard: React.FC<Props> = ({ comment, onSubmit, handleCommentD
{comment.actor_detail.avatar && comment.actor_detail.avatar !== "" ? ( {comment.actor_detail.avatar && comment.actor_detail.avatar !== "" ? (
<img <img
src={comment.actor_detail.avatar} src={comment.actor_detail.avatar}
alt={comment.actor_detail.first_name} alt={comment.actor_detail.display_name}
height={30} height={30}
width={30} width={30}
className="grid h-7 w-7 place-items-center rounded-full border-2 border-custom-border-200" className="grid h-7 w-7 place-items-center rounded-full border-2 border-custom-border-200"
@ -79,7 +79,7 @@ export const CommentCard: React.FC<Props> = ({ comment, onSubmit, handleCommentD
<div <div
className={`grid h-7 w-7 place-items-center rounded-full border-2 border-white bg-gray-500 text-white`} className={`grid h-7 w-7 place-items-center rounded-full border-2 border-white bg-gray-500 text-white`}
> >
{comment.actor_detail.first_name.charAt(0)} {comment.actor_detail.display_name.charAt(0)}
</div> </div>
)} )}
@ -93,8 +93,9 @@ export const CommentCard: React.FC<Props> = ({ comment, onSubmit, handleCommentD
<div className="min-w-0 flex-1"> <div className="min-w-0 flex-1">
<div> <div>
<div className="text-xs"> <div className="text-xs">
{comment.actor_detail.first_name} {comment.actor_detail.is_bot
{comment.actor_detail.is_bot ? "Bot" : " " + comment.actor_detail.last_name} ? comment.actor_detail.first_name + " Bot"
: comment.actor_detail.display_name}
</div> </div>
<p className="mt-0.5 text-xs text-custom-text-200"> <p className="mt-0.5 text-xs text-custom-text-200">
Commented {timeAgo(comment.created_at)} Commented {timeAgo(comment.created_at)}

View File

@ -30,20 +30,11 @@ export const IssueAssigneeSelect: React.FC<Props> = ({ projectId, value = [], on
const options = members?.map((member) => ({ const options = members?.map((member) => ({
value: member.member.id, value: member.member.id,
query: query: member.member.display_name ?? "",
(member.member.first_name && member.member.first_name !== ""
? member.member.first_name
: member.member.email) +
" " +
member.member.last_name ?? "",
content: ( content: (
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Avatar user={member.member} /> <Avatar user={member.member} />
{`${ {member.member.display_name}
member.member.first_name && member.member.first_name !== ""
? member.member.first_name
: member.member.email
} ${member.member.last_name ?? ""}`}
</div> </div>
), ),
})); }));

View File

@ -41,20 +41,11 @@ export const SidebarAssigneeSelect: React.FC<Props> = ({
const options = members?.map((member) => ({ const options = members?.map((member) => ({
value: member.member.id, value: member.member.id,
query: query: member.member.display_name,
(member.member.first_name && member.member.first_name !== ""
? member.member.first_name
: member.member.email) +
" " +
member.member.last_name ?? "",
content: ( content: (
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Avatar user={member.member} /> <Avatar user={member.member} />
{`${ {member.member.display_name}
member.member.first_name && member.member.first_name !== ""
? member.member.first_name
: member.member.email
} ${member.member.last_name ?? ""}`}
</div> </div>
), ),
})); }));

View File

@ -47,20 +47,11 @@ export const ViewAssigneeSelect: React.FC<Props> = ({
const options = members?.map((member) => ({ const options = members?.map((member) => ({
value: member.member.id, value: member.member.id,
query: query: member.member.display_name,
(member.member.first_name && member.member.first_name !== ""
? member.member.first_name
: member.member.email) +
" " +
member.member.last_name ?? "",
content: ( content: (
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Avatar user={member.member} /> <Avatar user={member.member} />
{`${ {member.member.display_name}
member.member.first_name && member.member.first_name !== ""
? member.member.first_name
: member.member.email
} ${member.member.last_name ?? ""}`}
</div> </div>
), ),
})); }));
@ -71,11 +62,7 @@ export const ViewAssigneeSelect: React.FC<Props> = ({
tooltipHeading="Assignees" tooltipHeading="Assignees"
tooltipContent={ tooltipContent={
issue.assignee_details.length > 0 issue.assignee_details.length > 0
? issue.assignee_details ? issue.assignee_details.map((assignee) => assignee?.display_name).join(", ")
.map((assignee) =>
assignee?.first_name !== "" ? assignee?.first_name : assignee?.email
)
.join(", ")
: "No Assignee" : "No Assignee"
} }
> >

View File

@ -32,18 +32,11 @@ export const ModuleLeadSelect: React.FC<Props> = ({ value, onChange }) => {
const options = members?.map((member) => ({ const options = members?.map((member) => ({
value: member.member.id, value: member.member.id,
query: query: member.member.display_name,
(member.member.first_name && member.member.first_name !== ""
? member.member.first_name
: member.member.email) +
" " +
member.member.last_name ?? "",
content: ( content: (
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Avatar user={member.member} /> <Avatar user={member.member} />
{member.member.first_name && member.member.first_name !== "" {member.member.display_name}
? member.member.first_name
: member.member.email}
</div> </div>
), ),
})); }));
@ -62,11 +55,7 @@ export const ModuleLeadSelect: React.FC<Props> = ({ value, onChange }) => {
<UserCircleIcon className="h-4 w-4 text-custom-text-200" /> <UserCircleIcon className="h-4 w-4 text-custom-text-200" />
)} )}
{selectedOption ? ( {selectedOption ? (
selectedOption?.first_name && selectedOption.first_name !== "" ? ( selectedOption?.display_name
selectedOption?.first_name
) : (
selectedOption?.email
)
) : ( ) : (
<span className="text-custom-text-200">Lead</span> <span className="text-custom-text-200">Lead</span>
)} )}

View File

@ -30,18 +30,11 @@ export const ModuleMembersSelect: React.FC<Props> = ({ value, onChange }) => {
); );
const options = members?.map((member) => ({ const options = members?.map((member) => ({
value: member.member.id, value: member.member.id,
query: query: member.member.display_name,
(member.member.first_name && member.member.first_name !== ""
? member.member.first_name
: member.member.email) +
" " +
member.member.last_name ?? "",
content: ( content: (
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Avatar user={member.member} /> <Avatar user={member.member} />
{member.member.first_name && member.member.first_name !== "" {member.member.display_name}
? member.member.first_name
: member.member.email}
</div> </div>
), ),
})); }));

View File

@ -33,18 +33,11 @@ export const SidebarLeadSelect: React.FC<Props> = ({ value, onChange }) => {
const options = members?.map((member) => ({ const options = members?.map((member) => ({
value: member.member.id, value: member.member.id,
query: query: member.member.display_name,
(member.member.first_name && member.member.first_name !== ""
? member.member.first_name
: member.member.email) +
" " +
member.member.last_name ?? "",
content: ( content: (
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Avatar user={member.member} /> <Avatar user={member.member} />
{member.member.first_name && member.member.first_name !== "" {member.member.display_name}
? member.member.first_name
: member.member.email}
</div> </div>
), ),
})); }));
@ -64,11 +57,7 @@ export const SidebarLeadSelect: React.FC<Props> = ({ value, onChange }) => {
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
{selectedOption && <Avatar user={selectedOption} />} {selectedOption && <Avatar user={selectedOption} />}
{selectedOption ? ( {selectedOption ? (
selectedOption?.first_name && selectedOption.first_name !== "" ? ( selectedOption?.display_name
selectedOption?.first_name
) : (
selectedOption?.email
)
) : ( ) : (
<span className="text-custom-text-200">No lead</span> <span className="text-custom-text-200">No lead</span>
)} )}

View File

@ -31,18 +31,11 @@ export const SidebarMembersSelect: React.FC<Props> = ({ value, onChange }) => {
const options = members?.map((member) => ({ const options = members?.map((member) => ({
value: member.member.id, value: member.member.id,
query: query: member.member.display_name,
(member.member.first_name && member.member.first_name !== ""
? member.member.first_name
: member.member.email) +
" " +
member.member.last_name ?? "",
content: ( content: (
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Avatar user={member.member} /> <Avatar user={member.member} />
{member.member.first_name && member.member.first_name !== "" {member.member.display_name}
? member.member.first_name
: member.member.email}
</div> </div>
), ),
})); }));

View File

@ -78,8 +78,8 @@ export const NotificationCard: React.FC<NotificationCardProps> = (props) => {
) : ( ) : (
<div className="w-12 h-12 bg-custom-background-80 rounded-full flex justify-center items-center"> <div className="w-12 h-12 bg-custom-background-80 rounded-full flex justify-center items-center">
<span className="text-custom-text-100 font-medium text-lg"> <span className="text-custom-text-100 font-medium text-lg">
{notification.triggered_by_details.first_name?.[0] ? ( {notification.triggered_by_details.display_name?.[0] ? (
notification.triggered_by_details.first_name?.[0]?.toUpperCase() notification.triggered_by_details.display_name?.[0]?.toUpperCase()
) : ( ) : (
<Icon iconName="person" className="h-6 w-6" /> <Icon iconName="person" className="h-6 w-6" />
)} )}
@ -89,10 +89,7 @@ export const NotificationCard: React.FC<NotificationCardProps> = (props) => {
</div> </div>
<div className="space-y-2.5 w-full overflow-hidden"> <div className="space-y-2.5 w-full overflow-hidden">
<div className="text-sm w-full break-words"> <div className="text-sm w-full break-words">
<span className="font-semibold"> <span className="font-semibold">{notification.triggered_by_details.display_name} </span>
{notification.triggered_by_details.first_name}{" "}
{notification.triggered_by_details.last_name}{" "}
</span>
{notification.data.issue_activity.field !== "comment" && {notification.data.issue_activity.field !== "comment" &&
notification.data.issue_activity.verb}{" "} notification.data.issue_activity.verb}{" "}
{notification.data.issue_activity.field === "comment" {notification.data.issue_activity.field === "comment"

View File

@ -162,7 +162,7 @@ export const SinglePageDetailedItem: React.FC<TSingleStatProps> = ({
position="top-right" position="top-right"
tooltipContent={`Created by ${ tooltipContent={`Created by ${
people?.find((person) => person.member.id === page.created_by)?.member people?.find((person) => person.member.id === page.created_by)?.member
.first_name ?? "" .display_name ?? ""
} on ${renderLongDateFormat(`${page.created_at}`)}`} } on ${renderLongDateFormat(`${page.created_at}`)}`}
> >
<span> <span>

View File

@ -161,7 +161,7 @@ export const SinglePageListItem: React.FC<TSingleStatProps> = ({
position="top-right" position="top-right"
tooltipContent={`Created by ${ tooltipContent={`Created by ${
people?.find((person) => person.member.id === page.created_by)?.member people?.find((person) => person.member.id === page.created_by)?.member
.first_name ?? "" .display_name ?? ""
} on ${renderLongDateFormat(`${page.created_at}`)}`} } on ${renderLongDateFormat(`${page.created_at}`)}`}
> >
<span> <span>

View File

@ -38,21 +38,21 @@ export const ProfileActivity = () => {
{activity.actor_detail.avatar && activity.actor_detail.avatar !== "" ? ( {activity.actor_detail.avatar && activity.actor_detail.avatar !== "" ? (
<img <img
src={activity.actor_detail.avatar} src={activity.actor_detail.avatar}
alt={activity.actor_detail.first_name} alt={activity.actor_detail.display_name}
height={24} height={24}
width={24} width={24}
className="rounded" className="rounded"
/> />
) : ( ) : (
<div className="grid h-6 w-6 place-items-center rounded border-2 bg-gray-700 text-xs text-white"> <div className="grid h-6 w-6 place-items-center rounded border-2 bg-gray-700 text-xs text-white">
{activity.actor_detail.first_name.charAt(0)} {activity.actor_detail.display_name?.charAt(0)}
</div> </div>
)} )}
</div> </div>
<div className="-mt-1 w-4/5 break-words"> <div className="-mt-1 w-4/5 break-words">
<p className="text-sm text-custom-text-200"> <p className="text-sm text-custom-text-200">
<span className="font-medium text-custom-text-100"> <span className="font-medium text-custom-text-100">
{activity.actor_detail.first_name} {activity.actor_detail.last_name}{" "} {activity.actor_detail.display_name}{" "}
</span> </span>
{activity.field ? ( {activity.field ? (
<ActivityMessage activity={activity} showIssue /> <ActivityMessage activity={activity} showIssue />

View File

@ -279,10 +279,10 @@ export const ProfileIssuesView = () => {
dragDisabled={groupByProperty !== "priority"} dragDisabled={groupByProperty !== "priority"}
emptyState={{ emptyState={{
title: router.pathname.includes("assigned") title: router.pathname.includes("assigned")
? `Issues assigned to ${profileData?.user_data.first_name} ${profileData?.user_data.last_name} will appear here` ? `Issues assigned to ${profileData?.user_data.display_name} will appear here`
: router.pathname.includes("created") : router.pathname.includes("created")
? `Issues created by ${profileData?.user_data.first_name} ${profileData?.user_data.last_name} will appear here` ? `Issues created by ${profileData?.user_data.display_name} will appear here`
: `Issues subscribed by ${profileData?.user_data.first_name} ${profileData?.user_data.last_name} will appear here`, : `Issues subscribed by ${profileData?.user_data.display_name} will appear here`,
}} }}
handleOnDragEnd={handleOnDragEnd} handleOnDragEnd={handleOnDragEnd}
handleIssueAction={handleIssueAction} handleIssueAction={handleIssueAction}

View File

@ -86,29 +86,29 @@ export const ProfileSidebar = () => {
userProjectsData.user_data.cover_image ?? userProjectsData.user_data.cover_image ??
"https://images.unsplash.com/photo-1506383796573-caf02b4a79ab" "https://images.unsplash.com/photo-1506383796573-caf02b4a79ab"
} }
alt={userProjectsData.user_data.first_name} alt={userProjectsData.user_data.display_name}
className="h-32 w-full object-cover" className="h-32 w-full object-cover"
/> />
<div className="absolute -bottom-[26px] left-5 h-[52px] w-[52px] rounded"> <div className="absolute -bottom-[26px] left-5 h-[52px] w-[52px] rounded">
{userProjectsData.user_data.avatar && userProjectsData.user_data.avatar !== "" ? ( {userProjectsData.user_data.avatar && userProjectsData.user_data.avatar !== "" ? (
<img <img
src={userProjectsData.user_data.avatar} src={userProjectsData.user_data.avatar}
alt={userProjectsData.user_data.first_name} alt={userProjectsData.user_data.display_name}
className="rounded" className="rounded"
/> />
) : ( ) : (
<div className="bg-custom-background-90 flex justify-center items-center w-[52px] h-[52px] rounded text-custom-text-100"> <div className="bg-custom-background-90 flex justify-center items-center w-[52px] h-[52px] rounded text-custom-text-100">
{userProjectsData.user_data.first_name[0]} {userProjectsData.user_data.display_name?.[0]}
</div> </div>
)} )}
</div> </div>
</div> </div>
<div className="px-5"> <div className="px-5">
<div className="mt-[38px]"> <div className="mt-[38px]">
<h4 className="text-lg font-semibold"> <h4 className="text-lg font-semibold">{userProjectsData.user_data.display_name}</h4>
{userProjectsData.user_data.first_name} {userProjectsData.user_data.last_name} <h6 className="text-custom-text-200 text-sm">
</h4> {userProjectsData.user_data.display_name}
<h6 className="text-custom-text-200 text-sm">{userProjectsData.user_data.email}</h6> </h6>
</div> </div>
<div className="mt-6 space-y-5"> <div className="mt-6 space-y-5">
{userDetails.map((detail) => ( {userDetails.map((detail) => (

View File

@ -67,13 +67,13 @@ const ConfirmProjectMemberRemove: React.FC<Props> = ({ isOpen, onClose, data, ha
as="h3" as="h3"
className="text-lg font-medium leading-6 text-custom-text-100" className="text-lg font-medium leading-6 text-custom-text-100"
> >
Remove {data?.email}? Remove {data?.display_name}?
</Dialog.Title> </Dialog.Title>
<div className="mt-2"> <div className="mt-2">
<p className="text-sm text-custom-text-200"> <p className="text-sm text-custom-text-200">
Are you sure you want to remove member-{" "} Are you sure you want to remove member-{" "}
<span className="font-bold">{data?.email}</span>? They will no longer have <span className="font-bold">{data?.display_name}</span>? They will no
access to this project. This action cannot be undone. longer have access to this project. This action cannot be undone.
</p> </p>
</div> </div>
</div> </div>

View File

@ -163,20 +163,11 @@ export const CreateProjectModal: React.FC<Props> = ({ isOpen, setIsOpen, user })
const options = workspaceMembers?.map((member) => ({ const options = workspaceMembers?.map((member) => ({
value: member.member.id, value: member.member.id,
query: query: member.member.display_name,
(member.member.first_name && member.member.first_name !== ""
? member.member.first_name
: member.member.email) +
" " +
member.member.last_name ?? "",
content: ( content: (
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Avatar user={member.member} /> <Avatar user={member.member} />
{`${ {member.member.display_name}
member.member.first_name && member.member.first_name !== ""
? member.member.first_name
: member.member.email
} ${member.member.last_name ?? ""}`}
</div> </div>
), ),
})); }));
@ -376,10 +367,7 @@ export const CreateProjectModal: React.FC<Props> = ({ isOpen, setIsOpen, user })
{value ? ( {value ? (
<> <>
<Avatar user={selectedMember?.member} /> <Avatar user={selectedMember?.member} />
<span> <span>{selectedMember?.member.display_name} </span>
{selectedMember?.member.first_name}{" "}
{selectedMember?.member.last_name}
</span>
<span onClick={() => onChange(null)}> <span onClick={() => onChange(null)}>
<Icon <Icon
iconName="close" iconName="close"

View File

@ -82,7 +82,7 @@ const SendProjectInvitationModal: React.FC<Props> = ({ isOpen, setIsOpen, member
}); });
const uninvitedPeople = people?.filter((person) => { const uninvitedPeople = people?.filter((person) => {
const isInvited = members?.find((member) => member.email === person.member.email); const isInvited = members?.find((member) => member.display_name === person.member.display_name);
return !isInvited; return !isInvited;
}); });
@ -136,11 +136,11 @@ const SendProjectInvitationModal: React.FC<Props> = ({ isOpen, setIsOpen, member
const options = uninvitedPeople?.map((person) => ({ const options = uninvitedPeople?.map((person) => ({
value: person.member.id, value: person.member.id,
query: person.member.email, query: person.member.display_name,
content: ( content: (
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Avatar user={person.member} /> <Avatar user={person.member} />
{person.member.email} {person.member.display_name}
</div> </div>
), ),
})); }));
@ -209,7 +209,10 @@ const SendProjectInvitationModal: React.FC<Props> = ({ isOpen, setIsOpen, member
people?.find((p) => p.member.id === value)?.member people?.find((p) => p.member.id === value)?.member
} }
/> />
{people?.find((p) => p.member.id === value)?.member.email} {
people?.find((p) => p.member.id === value)?.member
.display_name
}
</div> </div>
) : ( ) : (
<div>Select co-worker&rsquo;s email</div> <div>Select co-worker&rsquo;s email</div>

View File

@ -71,9 +71,7 @@ const SearchListbox: React.FC<Props> = ({
} else } else
return ( return (
<div className="grid h-4 w-4 flex-shrink-0 place-items-center rounded-full bg-gray-700 capitalize text-white"> <div className="grid h-4 w-4 flex-shrink-0 place-items-center rounded-full bg-gray-700 capitalize text-white">
{user.member.first_name && user.member.first_name !== "" {user.member.display_name.charAt(0)}
? user.member.first_name.charAt(0)
: user.member.email.charAt(0)}
</div> </div>
); );
}; };

View File

@ -47,7 +47,7 @@ export const Avatar: React.FC<AvatarProps> = ({
<img <img
src={user.avatar} src={user.avatar}
className="absolute top-0 left-0 h-full w-full object-cover rounded-full" className="absolute top-0 left-0 h-full w-full object-cover rounded-full"
alt={user.first_name} alt={user.display_name}
/> />
</div> </div>
) : ( ) : (
@ -59,9 +59,7 @@ export const Avatar: React.FC<AvatarProps> = ({
fontSize: fontSize, fontSize: fontSize,
}} }}
> >
{user?.first_name && user.first_name !== "" {user?.display_name?.charAt(0)}
? user.first_name.charAt(0)
: user?.email?.charAt(0)}
</div> </div>
)} )}
</div> </div>

View File

@ -127,9 +127,7 @@ export const SelectFilters: React.FC<Props> = ({
label: ( label: (
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Avatar user={member.member} /> <Avatar user={member.member} />
{member.member.first_name && member.member.first_name !== "" {member.member.display_name}
? member.member.first_name
: member.member.email}
</div> </div>
), ),
value: { value: {
@ -149,9 +147,7 @@ export const SelectFilters: React.FC<Props> = ({
label: ( label: (
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Avatar user={member.member} /> <Avatar user={member.member} />
{member.member.first_name && member.member.first_name !== "" {member.member.display_name}
? member.member.first_name
: member.member.email}
</div> </div>
), ),
value: { value: {

View File

@ -67,13 +67,13 @@ const ConfirmWorkspaceMemberRemove: React.FC<Props> = ({ isOpen, onClose, data,
as="h3" as="h3"
className="text-lg font-medium leading-6 text-custom-text-100" className="text-lg font-medium leading-6 text-custom-text-100"
> >
Remove {data?.email}? Remove {data?.display_name}?
</Dialog.Title> </Dialog.Title>
<div className="mt-2"> <div className="mt-2">
<p className="text-sm text-custom-text-200"> <p className="text-sm text-custom-text-200">
Are you sure you want to remove member-{" "} Are you sure you want to remove member-{" "}
<span className="font-bold">{data?.email}</span>? They will no longer have <span className="font-bold">{data?.display_name}</span>? They will no
access to this workspace. This action cannot be undone. longer have access to this workspace. This action cannot be undone.
</p> </p>
</div> </div>
</div> </div>

View File

@ -149,7 +149,7 @@ export const WorkspaceSidebarDropdown = () => {
border border-custom-sidebar-border-200 bg-custom-sidebar-background-90 shadow-lg outline-none" border border-custom-sidebar-border-200 bg-custom-sidebar-background-90 shadow-lg outline-none"
> >
<div className="flex flex-col items-start justify-start gap-3 p-3"> <div className="flex flex-col items-start justify-start gap-3 p-3">
<div className="text-sm text-custom-sidebar-text-200">{user?.email}</div> <div className="text-sm text-custom-sidebar-text-200">{user?.display_name}</div>
<span className="text-sm font-semibold text-custom-sidebar-text-200">Workspace</span> <span className="text-sm font-semibold text-custom-sidebar-text-200">Workspace</span>
{workspaces ? ( {workspaces ? (
<div className="flex h-full w-full flex-col items-start justify-start gap-3.5"> <div className="flex h-full w-full flex-col items-start justify-start gap-3.5">

View File

@ -41,8 +41,8 @@ const SingleInvitation: React.FC<Props> = ({
<p className="text-sm text-custom-text-200"> <p className="text-sm text-custom-text-200">
Invited by{" "} Invited by{" "}
{invitation.created_by_detail {invitation.created_by_detail
? invitation.created_by_detail.first_name ? invitation.created_by_detail.display_name
: invitation.workspace.owner.first_name} : invitation.workspace.owner.display_name}
</p> </p>
</div> </div>
<div className="flex-shrink-0 self-center"> <div className="flex-shrink-0 self-center">

View File

@ -19,7 +19,7 @@ export const ANALYTICS_X_AXIS_VALUES: { value: TXAxisValues; label: string }[] =
label: "Label", label: "Label",
}, },
{ {
value: "assignees__email", value: "assignees__id",
label: "Assignee", label: "Assignee",
}, },
{ {

View File

@ -69,9 +69,13 @@ export const WORKSPACE_DETAILS = (workspaceSlug: string) =>
export const WORKSPACE_MEMBERS = (workspaceSlug: string) => export const WORKSPACE_MEMBERS = (workspaceSlug: string) =>
`WORKSPACE_MEMBERS_${workspaceSlug.toUpperCase()}`; `WORKSPACE_MEMBERS_${workspaceSlug.toUpperCase()}`;
export const WORKSPACE_MEMBERS_WITH_EMAIL = (workspaceSlug: string) =>
`WORKSPACE_MEMBERS_WITH_EMAIL_${workspaceSlug.toUpperCase()}`;
export const WORKSPACE_MEMBERS_ME = (workspaceSlug: string) => export const WORKSPACE_MEMBERS_ME = (workspaceSlug: string) =>
`WORKSPACE_MEMBERS_ME${workspaceSlug.toUpperCase()}`; `WORKSPACE_MEMBERS_ME${workspaceSlug.toUpperCase()}`;
export const WORKSPACE_INVITATIONS = "WORKSPACE_INVITATIONS"; export const WORKSPACE_INVITATIONS = "WORKSPACE_INVITATIONS";
export const WORKSPACE_INVITATION_WITH_EMAIL = (workspaceSlug: string) =>
`WORKSPACE_INVITATION_WITH_EMAIL_${workspaceSlug.toUpperCase()}`;
export const WORKSPACE_INVITATION = "WORKSPACE_INVITATION"; export const WORKSPACE_INVITATION = "WORKSPACE_INVITATION";
export const LAST_ACTIVE_WORKSPACE_AND_PROJECTS = "LAST_ACTIVE_WORKSPACE_AND_PROJECTS"; export const LAST_ACTIVE_WORKSPACE_AND_PROJECTS = "LAST_ACTIVE_WORKSPACE_AND_PROJECTS";
@ -90,7 +94,11 @@ export const PROJECTS_LIST = (
export const PROJECT_DETAILS = (projectId: string) => `PROJECT_DETAILS_${projectId.toUpperCase()}`; export const PROJECT_DETAILS = (projectId: string) => `PROJECT_DETAILS_${projectId.toUpperCase()}`;
export const PROJECT_MEMBERS = (projectId: string) => `PROJECT_MEMBERS_${projectId.toUpperCase()}`; export const PROJECT_MEMBERS = (projectId: string) => `PROJECT_MEMBERS_${projectId.toUpperCase()}`;
export const PROJECT_MEMBERS_WITH_EMAIL = (workspaceSlug: string, projectId: string) =>
`PROJECT_MEMBERS_WITH_EMAIL_${workspaceSlug}_${projectId.toUpperCase()}`;
export const PROJECT_INVITATIONS = "PROJECT_INVITATIONS"; export const PROJECT_INVITATIONS = "PROJECT_INVITATIONS";
export const PROJECT_INVITATIONS_WITH_EMAIL = (workspaceSlug: string, projectId: string) =>
`PROJECT_INVITATIONS_WITH_EMAIL_${workspaceSlug}_${projectId.toUpperCase()}`;
export const PROJECT_ISSUES_LIST = (workspaceSlug: string, projectId: string) => export const PROJECT_ISSUES_LIST = (workspaceSlug: string, projectId: string) =>
`PROJECT_ISSUES_LIST_${workspaceSlug.toUpperCase()}_${projectId.toUpperCase()}`; `PROJECT_ISSUES_LIST_${workspaceSlug.toUpperCase()}_${projectId.toUpperCase()}`;

View File

@ -32,8 +32,8 @@ export const SPREADSHEET_COLUMN = [
colName: "Assignees", colName: "Assignees",
colSize: "128px", colSize: "128px",
icon: UserGroupIcon, icon: UserGroupIcon,
ascendingOrder: "assignees__first_name", ascendingOrder: "assignees__id",
descendingOrder: "-assignees__first_name", descendingOrder: "-assignees__id",
}, },
{ {
propertyName: "labels", propertyName: "labels",

View File

@ -73,7 +73,7 @@ const ProfileActivity = () => {
activityItem.actor_detail.avatar !== "" ? ( activityItem.actor_detail.avatar !== "" ? (
<img <img
src={activityItem.actor_detail.avatar} src={activityItem.actor_detail.avatar}
alt={activityItem.actor_detail.first_name} alt={activityItem.actor_detail.display_name}
height={30} height={30}
width={30} width={30}
className="grid h-7 w-7 place-items-center rounded-full border-2 border-white bg-gray-500 text-white" className="grid h-7 w-7 place-items-center rounded-full border-2 border-white bg-gray-500 text-white"
@ -82,7 +82,7 @@ const ProfileActivity = () => {
<div <div
className={`grid h-7 w-7 place-items-center rounded-full border-2 border-white bg-gray-500 text-white`} className={`grid h-7 w-7 place-items-center rounded-full border-2 border-white bg-gray-500 text-white`}
> >
{activityItem.actor_detail.first_name.charAt(0)} {activityItem.actor_detail.display_name?.charAt(0)}
</div> </div>
)} )}
@ -96,10 +96,9 @@ const ProfileActivity = () => {
<div className="min-w-0 flex-1"> <div className="min-w-0 flex-1">
<div> <div>
<div className="text-xs"> <div className="text-xs">
{activityItem.actor_detail.first_name}
{activityItem.actor_detail.is_bot {activityItem.actor_detail.is_bot
? "Bot" ? activityItem.actor_detail.first_name + " Bot"
: " " + activityItem.actor_detail.last_name} : activityItem.actor_detail.display_name}
</div> </div>
<p className="mt-0.5 text-xs text-custom-text-200"> <p className="mt-0.5 text-xs text-custom-text-200">
Commented {timeAgo(activityItem.created_at)} Commented {timeAgo(activityItem.created_at)}
@ -176,7 +175,7 @@ const ProfileActivity = () => {
activityItem.actor_detail.avatar !== "" ? ( activityItem.actor_detail.avatar !== "" ? (
<img <img
src={activityItem.actor_detail.avatar} src={activityItem.actor_detail.avatar}
alt={activityItem.actor_detail.first_name} alt={activityItem.actor_detail.display_name}
height={24} height={24}
width={24} width={24}
className="rounded-full" className="rounded-full"
@ -185,7 +184,7 @@ const ProfileActivity = () => {
<div <div
className={`grid h-7 w-7 place-items-center rounded-full border-2 border-white bg-gray-700 text-xs text-white`} className={`grid h-7 w-7 place-items-center rounded-full border-2 border-white bg-gray-700 text-xs text-white`}
> >
{activityItem.actor_detail.first_name.charAt(0)} {activityItem.actor_detail.display_name?.charAt(0)}
</div> </div>
)} )}
</div> </div>
@ -206,8 +205,7 @@ const ProfileActivity = () => {
href={`/${workspaceSlug}/profile/${activityItem.actor_detail.id}`} href={`/${workspaceSlug}/profile/${activityItem.actor_detail.id}`}
> >
<a className="text-gray font-medium"> <a className="text-gray font-medium">
{activityItem.actor_detail.first_name}{" "} {activityItem.actor_detail.display_name}
{activityItem.actor_detail.last_name}
</a> </a>
</Link> </Link>
)}{" "} )}{" "}

View File

@ -176,7 +176,7 @@ const Profile: NextPage = () => {
src={watch("avatar")} src={watch("avatar")}
className="absolute top-0 left-0 h-full w-full object-cover rounded-md" className="absolute top-0 left-0 h-full w-full object-cover rounded-md"
onClick={() => setIsImageUploadModalOpen(true)} onClick={() => setIsImageUploadModalOpen(true)}
alt={myProfile.first_name} alt={myProfile.display_name}
/> />
</div> </div>
)} )}

View File

@ -131,7 +131,7 @@ const ControlSettings: NextPage = () => {
{...field} {...field}
label={ label={
people?.find((person) => person.member.id === field.value)?.member people?.find((person) => person.member.id === field.value)?.member
.first_name ?? <span className="text-custom-text-200">Select lead</span> .display_name ?? <span className="text-custom-text-200">Select lead</span>
} }
width="w-full" width="w-full"
input input
@ -153,14 +153,10 @@ const ControlSettings: NextPage = () => {
</div> </div>
) : ( ) : (
<div className="grid h-4 w-4 flex-shrink-0 place-items-center rounded-full bg-gray-700 capitalize text-white"> <div className="grid h-4 w-4 flex-shrink-0 place-items-center rounded-full bg-gray-700 capitalize text-white">
{person.member.first_name && person.member.first_name !== "" {person.member.display_name?.charAt(0)}
? person.member.first_name.charAt(0)
: person.member.email.charAt(0)}
</div> </div>
)} )}
{person.member.first_name !== "" {person.member.display_name}
? person.member.first_name
: person.member.email}
</div> </div>
</CustomSelect.Option> </CustomSelect.Option>
))} ))}
@ -190,7 +186,7 @@ const ControlSettings: NextPage = () => {
<CustomSelect <CustomSelect
{...field} {...field}
label={ label={
people?.find((p) => p.member.id === field.value)?.member.first_name ?? ( people?.find((p) => p.member.id === field.value)?.member.display_name ?? (
<span className="text-custom-text-200">Select default assignee</span> <span className="text-custom-text-200">Select default assignee</span>
) )
} }
@ -214,14 +210,10 @@ const ControlSettings: NextPage = () => {
</div> </div>
) : ( ) : (
<div className="grid h-4 w-4 flex-shrink-0 place-items-center rounded-full bg-gray-700 capitalize text-white"> <div className="grid h-4 w-4 flex-shrink-0 place-items-center rounded-full bg-gray-700 capitalize text-white">
{person.member.first_name && person.member.first_name !== "" {person.member.display_name?.charAt(0)}
? person.member.first_name.charAt(0)
: person.member.email.charAt(0)}
</div> </div>
)} )}
{person.member.first_name !== "" {person.member.display_name}
? person.member.first_name
: person.member.email}
</div> </div>
</CustomSelect.Option> </CustomSelect.Option>
))} ))}

View File

@ -26,7 +26,11 @@ import { PlusIcon, XMarkIcon } from "@heroicons/react/24/outline";
// types // types
import type { NextPage } from "next"; import type { NextPage } from "next";
// fetch-keys // fetch-keys
import { PROJECT_INVITATIONS, PROJECT_MEMBERS, WORKSPACE_DETAILS } from "constants/fetch-keys"; import {
PROJECT_INVITATIONS_WITH_EMAIL,
PROJECT_MEMBERS_WITH_EMAIL,
WORKSPACE_DETAILS,
} from "constants/fetch-keys";
// constants // constants
import { ROLE } from "constants/workspace"; import { ROLE } from "constants/workspace";
// helper // helper
@ -51,16 +55,21 @@ const MembersSettings: NextPage = () => {
); );
const { data: projectMembers, mutate: mutateMembers } = useSWR( const { data: projectMembers, mutate: mutateMembers } = useSWR(
workspaceSlug && projectId ? PROJECT_MEMBERS(projectId as string) : null,
workspaceSlug && projectId workspaceSlug && projectId
? () => projectService.projectMembers(workspaceSlug as string, projectId as string) ? PROJECT_MEMBERS_WITH_EMAIL(workspaceSlug.toString(), projectId.toString())
: null,
workspaceSlug && projectId
? () => projectService.projectMembersWithEmail(workspaceSlug as string, projectId as string)
: null : null
); );
const { data: projectInvitations, mutate: mutateInvitations } = useSWR( const { data: projectInvitations, mutate: mutateInvitations } = useSWR(
workspaceSlug && projectId ? PROJECT_INVITATIONS : null,
workspaceSlug && projectId workspaceSlug && projectId
? () => projectService.projectInvitations(workspaceSlug as string, projectId as string) ? PROJECT_INVITATIONS_WITH_EMAIL(workspaceSlug.toString(), projectId.toString())
: null,
workspaceSlug && projectId
? () =>
projectService.projectInvitationsWithEmail(workspaceSlug as string, projectId as string)
: null : null
); );
@ -71,7 +80,7 @@ const MembersSettings: NextPage = () => {
avatar: item.member?.avatar, avatar: item.member?.avatar,
first_name: item.member?.first_name, first_name: item.member?.first_name,
last_name: item.member?.last_name, last_name: item.member?.last_name,
email: item.member?.email, display_name: item.member?.display_name,
role: item.role, role: item.role,
status: true, status: true,
member: true, member: true,
@ -82,7 +91,7 @@ const MembersSettings: NextPage = () => {
avatar: item.avatar ?? "", avatar: item.avatar ?? "",
first_name: item.first_name ?? item.email, first_name: item.first_name ?? item.email,
last_name: item.last_name ?? "", last_name: item.last_name ?? "",
email: item.email, display_name: item.email,
role: item.role, role: item.role,
status: item.accepted, status: item.accepted,
member: false, member: false,
@ -181,28 +190,24 @@ const MembersSettings: NextPage = () => {
{member.avatar && member.avatar !== "" ? ( {member.avatar && member.avatar !== "" ? (
<img <img
src={member.avatar} src={member.avatar}
alt={member.first_name} alt={member.display_name}
className="absolute top-0 left-0 h-full w-full object-cover rounded-lg" className="absolute top-0 left-0 h-full w-full object-cover rounded-lg"
/> />
) : member.first_name !== "" ? (
member.first_name.charAt(0)
) : ( ) : (
member.email.charAt(0) member.display_name.charAt(0)
)} )}
</div> </div>
<div> <div>
{member.member ? ( {member.member ? (
<Link href={`/${workspaceSlug}/profile/${member.memberId}`}> <Link href={`/${workspaceSlug}/profile/${member.memberId}`}>
<a className="text-sm"> <a className="text-sm">{member.display_name}</a>
{member.first_name} {member.last_name}
</a>
</Link> </Link>
) : ( ) : (
<h4 className="text-sm"> <h4 className="text-sm">{member.display_name}</h4>
{member.first_name} {member.last_name}
</h4>
)} )}
<p className="mt-0.5 text-xs text-custom-text-200">{member.email}</p> <p className="mt-0.5 text-xs text-custom-text-200">
{member.display_name}
</p>
</div> </div>
</div> </div>
<div className="flex items-center gap-2 text-xs"> <div className="flex items-center gap-2 text-xs">

View File

@ -24,7 +24,11 @@ import { PlusIcon } from "@heroicons/react/24/outline";
// types // types
import type { NextPage } from "next"; import type { NextPage } from "next";
// fetch-keys // fetch-keys
import { WORKSPACE_DETAILS, WORKSPACE_INVITATIONS, WORKSPACE_MEMBERS } from "constants/fetch-keys"; import {
WORKSPACE_DETAILS,
WORKSPACE_INVITATION_WITH_EMAIL,
WORKSPACE_MEMBERS_WITH_EMAIL,
} from "constants/fetch-keys";
// constants // constants
import { ROLE } from "constants/workspace"; import { ROLE } from "constants/workspace";
// helper // helper
@ -48,13 +52,17 @@ const MembersSettings: NextPage = () => {
); );
const { data: workspaceMembers, mutate: mutateMembers } = useSWR( const { data: workspaceMembers, mutate: mutateMembers } = useSWR(
workspaceSlug ? WORKSPACE_MEMBERS(workspaceSlug.toString()) : null, workspaceSlug ? WORKSPACE_MEMBERS_WITH_EMAIL(workspaceSlug.toString()) : null,
workspaceSlug ? () => workspaceService.workspaceMembers(workspaceSlug.toString()) : null workspaceSlug
? () => workspaceService.workspaceMembersWithEmail(workspaceSlug.toString())
: null
); );
const { data: workspaceInvitations, mutate: mutateInvitations } = useSWR( const { data: workspaceInvitations, mutate: mutateInvitations } = useSWR(
workspaceSlug ? WORKSPACE_INVITATIONS : null, workspaceSlug ? WORKSPACE_INVITATION_WITH_EMAIL(workspaceSlug.toString()) : null,
workspaceSlug ? () => workspaceService.workspaceInvitations(workspaceSlug.toString()) : null workspaceSlug
? () => workspaceService.workspaceInvitationsWithEmail(workspaceSlug.toString())
: null
); );
const members = [ const members = [
@ -65,6 +73,7 @@ const MembersSettings: NextPage = () => {
first_name: item.member?.first_name, first_name: item.member?.first_name,
last_name: item.member?.last_name, last_name: item.member?.last_name,
email: item.member?.email, email: item.member?.email,
display_name: item.member?.display_name,
role: item.role, role: item.role,
status: true, status: true,
member: true, member: true,
@ -77,6 +86,7 @@ const MembersSettings: NextPage = () => {
first_name: item.email, first_name: item.email,
last_name: "", last_name: "",
email: item.email, email: item.email,
display_name: item.email,
role: item.role, role: item.role,
status: item.accepted, status: item.accepted,
member: false, member: false,
@ -199,27 +209,23 @@ const MembersSettings: NextPage = () => {
<img <img
src={member.avatar} src={member.avatar}
className="absolute top-0 left-0 h-full w-full object-cover rounded-lg" className="absolute top-0 left-0 h-full w-full object-cover rounded-lg"
alt={member.first_name} alt={member.display_name || member.email}
/> />
) : member.first_name !== "" ? (
member.first_name.charAt(0)
) : ( ) : (
member.email.charAt(0) (member.display_name || member.email).charAt(0)
)} )}
</div> </div>
<div> <div>
{member.member ? ( {member.member ? (
<Link href={`/${workspaceSlug}/profile/${member.memberId}`}> <Link href={`/${workspaceSlug}/profile/${member.memberId}`}>
<a className="text-sm"> <a className="text-sm">{member.display_name || member.email}</a>
{member.first_name} {member.last_name}
</a>
</Link> </Link>
) : ( ) : (
<h4 className="text-sm"> <h4 className="text-sm">{member.display_name}</h4>
{member.first_name} {member.last_name}
</h4>
)} )}
<p className="text-xs text-custom-text-200">{member.email}</p> <p className="text-xs text-custom-text-200">
{member.display_name || member.email}
</p>
</div> </div>
</div> </div>
<div className="flex items-center gap-2 text-xs"> <div className="flex items-center gap-2 text-xs">

View File

@ -26,6 +26,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
email: user.email, email: user.email,
first_name: user.first_name, first_name: user.first_name,
last_name: user.last_name, last_name: user.last_name,
display_name: user?.display_name,
}) })
.then(() => { .then(() => {
jitsu.track(eventName, { jitsu.track(eventName, {

View File

@ -151,6 +151,17 @@ class ProjectServices extends APIService {
} }
async projectMembers(workspaceSlug: string, projectId: string): Promise<IProjectMember[]> { async projectMembers(workspaceSlug: string, projectId: string): Promise<IProjectMember[]> {
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/project-members/`)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
});
}
async projectMembersWithEmail(
workspaceSlug: string,
projectId: string
): Promise<IProjectMember[]> {
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/members/`) return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/members/`)
.then((response) => response?.data) .then((response) => response?.data)
.catch((error) => { .catch((error) => {
@ -219,6 +230,17 @@ class ProjectServices extends APIService {
}); });
} }
async projectInvitationsWithEmail(
workspaceSlug: string,
projectId: string
): Promise<IProjectMemberInvitation[]> {
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/invitations/`)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
});
}
async updateProjectInvitation( async updateProjectInvitation(
workspaceSlug: string, workspaceSlug: string,
projectId: string, projectId: string,

View File

@ -155,6 +155,14 @@ class WorkspaceService extends APIService {
} }
async workspaceMembers(workspaceSlug: string): Promise<IWorkspaceMember[]> { async workspaceMembers(workspaceSlug: string): Promise<IWorkspaceMember[]> {
return this.get(`/api/workspaces/${workspaceSlug}/workspace-members/`)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
});
}
async workspaceMembersWithEmail(workspaceSlug: string): Promise<IWorkspaceMember[]> {
return this.get(`/api/workspaces/${workspaceSlug}/members/`) return this.get(`/api/workspaces/${workspaceSlug}/members/`)
.then((response) => response?.data) .then((response) => response?.data)
.catch((error) => { .catch((error) => {
@ -209,6 +217,16 @@ class WorkspaceService extends APIService {
}); });
} }
async workspaceInvitationsWithEmail(
workspaceSlug: string
): Promise<IWorkspaceMemberInvitation[]> {
return this.get(`/api/workspaces/${workspaceSlug}/invitations/`)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
});
}
async getWorkspaceInvitation(invitationId: string): Promise<IWorkspaceMemberInvitation> { async getWorkspaceInvitation(invitationId: string): Promise<IWorkspaceMemberInvitation> {
return this.get(`/api/users/me/invitations/${invitationId}/`, { headers: {} }) return this.get(`/api/users/me/invitations/${invitationId}/`, { headers: {} })
.then((response) => response?.data) .then((response) => response?.data)

View File

@ -4,8 +4,8 @@ export interface IAnalyticsResponse {
extras: { extras: {
colors: IAnalyticsExtra[]; colors: IAnalyticsExtra[];
assignee_details: { assignee_details: {
assignees__display_name: string | null;
assignees__avatar: string | null; assignees__avatar: string | null;
assignees__email: string;
assignees__first_name: string; assignees__first_name: string;
assignees__last_name: string; assignees__last_name: string;
}[]; }[];
@ -30,7 +30,7 @@ export type TXAxisValues =
| "state__name" | "state__name"
| "state__group" | "state__group"
| "labels__name" | "labels__name"
| "assignees__email" | "assignees__id"
| "estimate_point" | "estimate_point"
| "issue_cycle__cycle__name" | "issue_cycle__cycle__name"
| "issue_module__module__name" | "issue_module__module__name"
@ -65,9 +65,9 @@ export interface IExportAnalyticsFormData {
export interface IDefaultAnalyticsUser { export interface IDefaultAnalyticsUser {
assignees__avatar: string | null; assignees__avatar: string | null;
assignees__email: string | null;
assignees__first_name: string; assignees__first_name: string;
assignees__last_name: string; assignees__last_name: string;
assignees__display_name: string;
count: number; count: number;
} }
@ -76,9 +76,9 @@ export interface IDefaultAnalyticsResponse {
most_issue_closed_user: IDefaultAnalyticsUser[]; most_issue_closed_user: IDefaultAnalyticsUser[];
most_issue_created_user: { most_issue_created_user: {
created_by__avatar: string | null; created_by__avatar: string | null;
created_by__email: string | null;
created_by__first_name: string; created_by__first_name: string;
created_by__last_name: string; created_by__last_name: string;
created_by__display_name: string;
count: number; count: number;
}[]; }[];
open_estimate_sum: number; open_estimate_sum: number;

View File

@ -49,6 +49,7 @@ export type TAssigneesDistribution = {
completed_issues: number; completed_issues: number;
first_name: string | null; first_name: string | null;
last_name: string | null; last_name: string | null;
display_name: string | null;
pending_issues: number; pending_issues: number;
total_issues: number; total_issues: number;
}; };

View File

@ -3,6 +3,7 @@ import type {
IUserLite, IUserLite,
IWorkspace, IWorkspace,
IWorkspaceLite, IWorkspaceLite,
IUserMemberLite,
TIssueGroupByOptions, TIssueGroupByOptions,
TIssueOrderByOptions, TIssueOrderByOptions,
TIssueViewOptions, TIssueViewOptions,
@ -78,7 +79,7 @@ type ProjectPreferences = {
export interface IProjectMember { export interface IProjectMember {
id: string; id: string;
member: IUserLite; member: IUserMemberLite;
project: IProjectLite; project: IProjectLite;
workspace: IWorkspaceLite; workspace: IWorkspaceLite;
comment: string; comment: string;

View File

@ -15,6 +15,7 @@ export interface IUser {
created_location: readonly string; created_location: readonly string;
date_joined: readonly Date; date_joined: readonly Date;
email: string; email: string;
display_name: string;
first_name: string; first_name: string;
id: readonly string; id: readonly string;
is_email_verified: boolean; is_email_verified: boolean;
@ -53,13 +54,17 @@ export interface ICurrentUserResponse extends IUser {
export interface IUserLite { export interface IUserLite {
avatar: string; avatar: string;
created_at: Date; created_at: Date;
email: string; display_name: string;
first_name: string; first_name: string;
readonly id: string; readonly id: string;
is_bot: boolean; is_bot: boolean;
last_name: string; last_name: string;
} }
export interface IUserMemberLite extends IUserLite {
email: string;
}
export interface IUserActivity { export interface IUserActivity {
created_date: string; created_date: string;
activity_count: number; activity_count: number;
@ -141,7 +146,7 @@ export interface IUserProfileProjectSegregation {
avatar: string; avatar: string;
cover_image: string | null; cover_image: string | null;
date_joined: Date; date_joined: Date;
email: string; display_name: string;
first_name: string; first_name: string;
last_name: string; last_name: string;
user_timezone: string; user_timezone: string;

View File

@ -2,7 +2,7 @@ import type {
IIssueFilterOptions, IIssueFilterOptions,
IProjectMember, IProjectMember,
IUser, IUser,
IUserLite, IUserMemberLite,
TIssueGroupByOptions, TIssueGroupByOptions,
TIssueOrderByOptions, TIssueOrderByOptions,
TIssueViewOptions, TIssueViewOptions,
@ -73,9 +73,8 @@ export interface IWorkspaceViewProps {
export interface IWorkspaceMember { export interface IWorkspaceMember {
readonly id: string; readonly id: string;
user: IUserLite;
workspace: IWorkspace; workspace: IWorkspace;
member: IUserLite; member: IUserMemberLite;
role: 5 | 10 | 15 | 20; role: 5 | 10 | 15 | 20;
company_role: string | null; company_role: string | null;
view_props: IWorkspaceViewProps; view_props: IWorkspaceViewProps;