forked from github/plane
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:
parent
cf306ee605
commit
981acc81c1
@ -16,15 +16,7 @@ export const CustomTooltip: React.FC<Props> = ({ datum, analytics, params }) =>
|
||||
|
||||
if (params.segment) {
|
||||
if (DATE_KEYS.includes(params.segment)) tooltipValue = renderMonthAndYear(datum.id);
|
||||
else if (params.segment === "assignees__email") {
|
||||
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 tooltipValue = datum.id;
|
||||
} else {
|
||||
if (DATE_KEYS.includes(params.x_axis)) tooltipValue = datum.indexValue;
|
||||
else tooltipValue = datum.id === "count" ? "Issue count" : "Estimate";
|
||||
|
@ -70,17 +70,17 @@ export const AnalyticsGraph: React.FC<Props> = ({
|
||||
height={fullScreen ? "400px" : "300px"}
|
||||
margin={{
|
||||
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={{
|
||||
tickSize: 0,
|
||||
tickPadding: 10,
|
||||
tickRotation: barGraphData.data.length > 7 ? -45 : 0,
|
||||
renderTick:
|
||||
params.x_axis === "assignees__email"
|
||||
params.x_axis === "assignees__id"
|
||||
? (datum) => {
|
||||
const avatar = analytics.extras.assignee_details?.find(
|
||||
(a) => a?.assignees__email === datum?.value
|
||||
(a) => a?.assignees__display_name === datum?.value
|
||||
)?.assignees__avatar;
|
||||
|
||||
if (avatar && avatar !== "")
|
||||
|
@ -277,9 +277,7 @@ export const AnalyticsSidebar: React.FC<Props> = ({
|
||||
<div className="space-y-4 mt-4">
|
||||
<div className="flex items-center gap-2 text-xs">
|
||||
<h6 className="text-custom-text-200">Lead</h6>
|
||||
<span>
|
||||
{cycleDetails.owned_by?.first_name} {cycleDetails.owned_by?.last_name}
|
||||
</span>
|
||||
<span>{cycleDetails.owned_by?.display_name}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 text-xs">
|
||||
<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="flex items-center gap-2 text-xs">
|
||||
<h6 className="text-custom-text-200">Lead</h6>
|
||||
<span>
|
||||
{moduleDetails.lead_detail?.first_name}{" "}
|
||||
{moduleDetails.lead_detail?.last_name}
|
||||
</span>
|
||||
<span>{moduleDetails.lead_detail?.display_name}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 text-xs">
|
||||
<h6 className="text-custom-text-200">Start Date</h6>
|
||||
|
@ -21,115 +21,96 @@ type Props = {
|
||||
yAxisKey: "count" | "estimate";
|
||||
};
|
||||
|
||||
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="overflow-x-auto">
|
||||
<div className="inline-block min-w-full align-middle">
|
||||
<table className="min-w-full divide-y divide-custom-border-200 whitespace-nowrap border-y border-custom-border-200">
|
||||
<thead className="bg-custom-background-80">
|
||||
<tr className="divide-x divide-custom-border-200 text-sm text-custom-text-100">
|
||||
<th scope="col" className="py-3 px-2.5 text-left font-medium">
|
||||
{ANALYTICS_X_AXIS_VALUES.find((v) => v.value === params.x_axis)?.label}
|
||||
</th>
|
||||
{params.segment ? (
|
||||
barGraphData.xAxisKeys.map((key) => (
|
||||
<th
|
||||
key={`segment-${key}`}
|
||||
scope="col"
|
||||
className={`px-2.5 py-3 text-left font-medium ${
|
||||
params.segment === "priority" || params.segment === "state__group"
|
||||
? "capitalize"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
{params.segment === "priority" ? (
|
||||
getPriorityIcon(key)
|
||||
) : (
|
||||
<span
|
||||
className="h-3 w-3 flex-shrink-0 rounded"
|
||||
style={{
|
||||
backgroundColor: generateBarColor(key, analytics, params, "segment"),
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{DATE_KEYS.includes(params.segment ?? "")
|
||||
? renderMonthAndYear(key)
|
||||
: params.segment === "assignees__email"
|
||||
? renderAssigneeName(key)
|
||||
: key}
|
||||
</div>
|
||||
</th>
|
||||
))
|
||||
) : (
|
||||
<th scope="col" className="py-3 px-2.5 text-left font-medium sm:pr-0">
|
||||
{ANALYTICS_Y_AXIS_VALUES.find((v) => v.value === params.y_axis)?.label}
|
||||
</th>
|
||||
)}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-custom-border-200">
|
||||
{barGraphData.data.map((item, index) => (
|
||||
<tr
|
||||
key={`table-row-${index}`}
|
||||
className="divide-x divide-custom-border-200 text-xs text-custom-text-200"
|
||||
>
|
||||
<td
|
||||
className={`flex items-center gap-2 whitespace-nowrap py-2 px-2.5 font-medium ${
|
||||
params.x_axis === "priority" || params.x_axis === "state__group"
|
||||
export const AnalyticsTable: React.FC<Props> = ({ analytics, barGraphData, params, yAxisKey }) => (
|
||||
<div className="flow-root">
|
||||
<div className="overflow-x-auto">
|
||||
<div className="inline-block min-w-full align-middle">
|
||||
<table className="min-w-full divide-y divide-custom-border-200 whitespace-nowrap border-y border-custom-border-200">
|
||||
<thead className="bg-custom-background-80">
|
||||
<tr className="divide-x divide-custom-border-200 text-sm text-custom-text-100">
|
||||
<th scope="col" className="py-3 px-2.5 text-left font-medium">
|
||||
{ANALYTICS_X_AXIS_VALUES.find((v) => v.value === params.x_axis)?.label}
|
||||
</th>
|
||||
{params.segment ? (
|
||||
barGraphData.xAxisKeys.map((key) => (
|
||||
<th
|
||||
key={`segment-${key}`}
|
||||
scope="col"
|
||||
className={`px-2.5 py-3 text-left font-medium ${
|
||||
params.segment === "priority" || params.segment === "state__group"
|
||||
? "capitalize"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
{params.x_axis === "priority" ? (
|
||||
getPriorityIcon(`${item.name}`)
|
||||
) : (
|
||||
<span
|
||||
className="h-3 w-3 rounded"
|
||||
style={{
|
||||
backgroundColor: generateBarColor(
|
||||
`${item.name}`,
|
||||
analytics,
|
||||
params,
|
||||
"x_axis"
|
||||
),
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{params.x_axis === "assignees__email"
|
||||
? renderAssigneeName(`${item.name}`)
|
||||
: addSpaceIfCamelCase(`${item.name}`)}
|
||||
</td>
|
||||
{params.segment ? (
|
||||
barGraphData.xAxisKeys.map((key, index) => (
|
||||
<td
|
||||
key={`segment-value-${index}`}
|
||||
className="whitespace-nowrap py-2 px-2.5 sm:pr-0"
|
||||
>
|
||||
{item[key] ?? 0}
|
||||
</td>
|
||||
))
|
||||
<div className="flex items-center gap-2">
|
||||
{params.segment === "priority" ? (
|
||||
getPriorityIcon(key)
|
||||
) : (
|
||||
<span
|
||||
className="h-3 w-3 flex-shrink-0 rounded"
|
||||
style={{
|
||||
backgroundColor: generateBarColor(key, analytics, params, "segment"),
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{DATE_KEYS.includes(params.segment ?? "") ? renderMonthAndYear(key) : key}
|
||||
</div>
|
||||
</th>
|
||||
))
|
||||
) : (
|
||||
<th scope="col" className="py-3 px-2.5 text-left font-medium sm:pr-0">
|
||||
{ANALYTICS_Y_AXIS_VALUES.find((v) => v.value === params.y_axis)?.label}
|
||||
</th>
|
||||
)}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-custom-border-200">
|
||||
{barGraphData.data.map((item, index) => (
|
||||
<tr
|
||||
key={`table-row-${index}`}
|
||||
className="divide-x divide-custom-border-200 text-xs text-custom-text-200"
|
||||
>
|
||||
<td
|
||||
className={`flex items-center gap-2 whitespace-nowrap py-2 px-2.5 font-medium ${
|
||||
params.x_axis === "priority" || params.x_axis === "state__group"
|
||||
? "capitalize"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
{params.x_axis === "priority" ? (
|
||||
getPriorityIcon(`${item.name}`)
|
||||
) : (
|
||||
<td className="whitespace-nowrap py-2 px-2.5 sm:pr-0">{item[yAxisKey]}</td>
|
||||
<span
|
||||
className="h-3 w-3 rounded"
|
||||
style={{
|
||||
backgroundColor: generateBarColor(
|
||||
`${item.name}`,
|
||||
analytics,
|
||||
params,
|
||||
"x_axis"
|
||||
),
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{addSpaceIfCamelCase(`${item.name}`)}
|
||||
</td>
|
||||
{params.segment ? (
|
||||
barGraphData.xAxisKeys.map((key, index) => (
|
||||
<td
|
||||
key={`segment-value-${index}`}
|
||||
className="whitespace-nowrap py-2 px-2.5 sm:pr-0"
|
||||
>
|
||||
{item[key] ?? 0}
|
||||
</td>
|
||||
))
|
||||
) : (
|
||||
<td className="whitespace-nowrap py-2 px-2.5 sm:pr-0">{item[yAxisKey]}</td>
|
||||
)}
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
</div>
|
||||
);
|
||||
|
@ -1,7 +1,7 @@
|
||||
type Props = {
|
||||
users: {
|
||||
avatar: string | null;
|
||||
email: string | null;
|
||||
display_name: string | null;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
count: number;
|
||||
@ -16,7 +16,7 @@ export const AnalyticsLeaderboard: React.FC<Props> = ({ users, title }) => (
|
||||
<div className="mt-3 space-y-3">
|
||||
{users.map((user) => (
|
||||
<div
|
||||
key={user.email ?? "None"}
|
||||
key={user.display_name ?? "None"}
|
||||
className="flex items-start justify-between gap-4 text-xs"
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
@ -25,16 +25,16 @@ export const AnalyticsLeaderboard: React.FC<Props> = ({ users, title }) => (
|
||||
<img
|
||||
src={user.avatar}
|
||||
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 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>
|
||||
)}
|
||||
<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>
|
||||
</div>
|
||||
<span className="flex-shrink-0">{user.count}</span>
|
||||
|
@ -56,9 +56,9 @@ export const ScopeAndDemand: React.FC<Props> = ({ fullScreen = true }) => {
|
||||
<AnalyticsLeaderboard
|
||||
users={defaultAnalytics.most_issue_created_user?.map((user) => ({
|
||||
avatar: user?.created_by__avatar,
|
||||
email: user?.created_by__email,
|
||||
firstName: user?.created_by__first_name,
|
||||
lastName: user?.created_by__last_name,
|
||||
display_name: user?.created_by__display_name,
|
||||
count: user?.count,
|
||||
}))}
|
||||
title="Most issues created"
|
||||
@ -66,9 +66,9 @@ export const ScopeAndDemand: React.FC<Props> = ({ fullScreen = true }) => {
|
||||
<AnalyticsLeaderboard
|
||||
users={defaultAnalytics.most_issue_closed_user?.map((user) => ({
|
||||
avatar: user?.assignees__avatar,
|
||||
email: user?.assignees__email,
|
||||
firstName: user?.assignees__first_name,
|
||||
lastName: user?.assignees__last_name,
|
||||
display_name: user?.assignees__display_name,
|
||||
count: user?.count,
|
||||
}))}
|
||||
title="Most issues closed"
|
||||
|
@ -16,23 +16,20 @@ export const AnalyticsScope: React.FC<Props> = ({ defaultAnalytics }) => (
|
||||
{defaultAnalytics.pending_issue_user.length > 0 ? (
|
||||
<BarGraph
|
||||
data={defaultAnalytics.pending_issue_user}
|
||||
indexBy="assignees__email"
|
||||
indexBy="assignees__display_name"
|
||||
keys={["count"]}
|
||||
height="250px"
|
||||
colors={() => `#f97316`}
|
||||
customYAxisTickValues={defaultAnalytics.pending_issue_user.map((d) => d.count)}
|
||||
tooltip={(datum) => {
|
||||
const assignee = defaultAnalytics.pending_issue_user.find(
|
||||
(a) => a.assignees__email === `${datum.indexValue}`
|
||||
(a) => a.assignees__display_name === `${datum.indexValue}`
|
||||
);
|
||||
|
||||
return (
|
||||
<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">
|
||||
{assignee
|
||||
? assignee.assignees__first_name + " " + assignee.assignees__last_name
|
||||
: "No assignee"}
|
||||
:{" "}
|
||||
{assignee ? assignee.assignees__display_name : "No assignee"}:{" "}
|
||||
</span>
|
||||
{datum.value}
|
||||
</div>
|
||||
|
@ -34,15 +34,12 @@ export const ChangeIssueAssignee: React.FC<Props> = ({ setIsPaletteOpen, issue,
|
||||
const options =
|
||||
members?.map(({ member }) => ({
|
||||
value: member.id,
|
||||
query:
|
||||
(member.first_name && member.first_name !== "" ? member.first_name : member.email) +
|
||||
" " +
|
||||
member.last_name ?? "",
|
||||
query: member.display_name,
|
||||
content: (
|
||||
<>
|
||||
<div className="flex items-center gap-2">
|
||||
<Avatar user={member} />
|
||||
{member.first_name && member.first_name !== "" ? member.first_name : member.email}
|
||||
{member.display_name}
|
||||
</div>
|
||||
{issue.assignees.includes(member.id) && (
|
||||
<div>
|
||||
|
@ -157,10 +157,10 @@ export const FiltersList: React.FC<Props> = ({
|
||||
return (
|
||||
<div
|
||||
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} />
|
||||
<span>{member?.first_name}</span>
|
||||
<span>{member?.display_name}</span>
|
||||
<span
|
||||
className="cursor-pointer"
|
||||
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"
|
||||
>
|
||||
<Avatar user={member} />
|
||||
<span>{member?.first_name}</span>
|
||||
<span>{member?.display_name}</span>
|
||||
<span
|
||||
className="cursor-pointer"
|
||||
onClick={() =>
|
||||
|
@ -62,7 +62,7 @@ export const LinksList: React.FC<Props> = ({ links, handleDeleteLink, userAuth }
|
||||
by{" "}
|
||||
{link.created_by_detail.is_bot
|
||||
? link.created_by_detail.first_name + " Bot"
|
||||
: link.created_by_detail.email}
|
||||
: link.created_by_detail.display_name}
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
|
@ -133,9 +133,10 @@ export const SidebarProgressStats: React.FC<Props> = ({
|
||||
avatar: assignee.avatar ?? "",
|
||||
first_name: assignee.first_name ?? "",
|
||||
last_name: assignee.last_name ?? "",
|
||||
display_name: assignee.display_name ?? "",
|
||||
}}
|
||||
/>
|
||||
<span>{assignee.first_name}</span>
|
||||
<span>{assignee.display_name}</span>
|
||||
</div>
|
||||
}
|
||||
completed={assignee.completed_issues}
|
||||
|
@ -81,10 +81,7 @@ export const BoardHeader: React.FC<Props> = ({
|
||||
break;
|
||||
case "created_by":
|
||||
const member = members?.find((member) => member.member.id === groupTitle)?.member;
|
||||
title =
|
||||
member?.first_name && member.first_name !== ""
|
||||
? `${member.first_name} ${member.last_name}`
|
||||
: member?.email ?? "";
|
||||
title = member?.display_name ?? "";
|
||||
break;
|
||||
}
|
||||
|
||||
@ -149,7 +146,9 @@ export const BoardHeader: React.FC<Props> = ({
|
||||
>
|
||||
<span className="flex items-center">{getGroupIcon()}</span>
|
||||
<h2
|
||||
className="text-lg font-semibold capitalize truncate"
|
||||
className={`text-lg font-semibold truncate ${
|
||||
selectedGroup === "created_by" ? "" : "capitalize"
|
||||
}`}
|
||||
style={{
|
||||
writingMode: isCollapsed ? "horizontal-tb" : "vertical-rl",
|
||||
}}
|
||||
|
@ -96,10 +96,7 @@ export const SingleList: React.FC<Props> = ({
|
||||
break;
|
||||
case "created_by":
|
||||
const member = members?.find((member) => member.member.id === groupTitle)?.member;
|
||||
title =
|
||||
member?.first_name && member.first_name !== ""
|
||||
? `${member.first_name} ${member.last_name}`
|
||||
: member?.email ?? "";
|
||||
title = member?.display_name ?? "";
|
||||
break;
|
||||
}
|
||||
|
||||
@ -163,7 +160,11 @@ export const SingleList: React.FC<Props> = ({
|
||||
<div className="flex items-center">{getGroupIcon()}</div>
|
||||
)}
|
||||
{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()}
|
||||
</h2>
|
||||
) : (
|
||||
|
@ -361,14 +361,14 @@ export const ActiveCycleDetails: React.FC = () => {
|
||||
height={16}
|
||||
width={16}
|
||||
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">
|
||||
{cycle.owned_by.first_name.charAt(0)}
|
||||
{cycle.owned_by.display_name.charAt(0)}
|
||||
</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>
|
||||
|
||||
{cycle.assignees.length > 0 && (
|
||||
|
@ -88,9 +88,10 @@ export const ActiveCycleProgressStats: React.FC<Props> = ({ cycle }) => {
|
||||
avatar: assignee.avatar ?? "",
|
||||
first_name: assignee.first_name ?? "",
|
||||
last_name: assignee.last_name ?? "",
|
||||
display_name: assignee.display_name ?? "",
|
||||
}}
|
||||
/>
|
||||
<span>{assignee.first_name}</span>
|
||||
<span>{assignee.display_name}</span>
|
||||
</div>
|
||||
}
|
||||
completed={assignee.completed_issues}
|
||||
|
@ -450,14 +450,14 @@ export const CycleDetailsSidebar: React.FC<Props> = ({
|
||||
height={12}
|
||||
width={12}
|
||||
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">
|
||||
{cycle.owned_by.first_name.charAt(0)}
|
||||
{cycle.owned_by.display_name.charAt(0)}
|
||||
</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>
|
||||
|
||||
|
@ -250,14 +250,14 @@ export const SingleCycleCard: React.FC<TSingleStatProps> = ({
|
||||
height={16}
|
||||
width={16}
|
||||
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">
|
||||
{cycle.owned_by.first_name.charAt(0)}
|
||||
{cycle.owned_by.display_name.charAt(0)}
|
||||
</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 className="flex h-5 items-center gap-2">
|
||||
|
@ -254,11 +254,11 @@ export const SingleCycleList: React.FC<TSingleStatProps> = ({
|
||||
height={16}
|
||||
width={16}
|
||||
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">
|
||||
{cycle.owned_by.first_name.charAt(0)}
|
||||
{cycle.owned_by.display_name.charAt(0)}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
@ -44,19 +44,12 @@ export const SingleUserSelect: React.FC<Props> = ({ collaborator, index, users,
|
||||
);
|
||||
|
||||
const options = members?.map((member) => ({
|
||||
value: member.member.email,
|
||||
query:
|
||||
(member.member.first_name && member.member.first_name !== ""
|
||||
? member.member.first_name
|
||||
: member.member.email) +
|
||||
" " +
|
||||
member.member.last_name ?? "",
|
||||
value: member.member.display_name,
|
||||
query: member.member.display_name ?? "",
|
||||
content: (
|
||||
<div className="flex items-center gap-2">
|
||||
<Avatar user={member.member} />
|
||||
{member.member.first_name && member.member.first_name !== ""
|
||||
? member.member.first_name + "(" + member.member.email + ")"
|
||||
: member.member.email}
|
||||
{member.member.display_name}
|
||||
</div>
|
||||
),
|
||||
}));
|
||||
|
@ -34,18 +34,11 @@ export const JiraImportUsers: FC = () => {
|
||||
|
||||
const options = members?.map((member) => ({
|
||||
value: member.member.email,
|
||||
query:
|
||||
(member.member.first_name && member.member.first_name !== ""
|
||||
? member.member.first_name
|
||||
: member.member.email) +
|
||||
" " +
|
||||
member.member.last_name ?? "",
|
||||
query: member.member.display_name ?? "",
|
||||
content: (
|
||||
<div className="flex items-center gap-2">
|
||||
<Avatar user={member.member} />
|
||||
{member.member.first_name && member.member.first_name !== ""
|
||||
? member.member.first_name + " (" + member.member.email + ")"
|
||||
: member.member.email}
|
||||
{member.member.display_name}
|
||||
</div>
|
||||
),
|
||||
}));
|
||||
|
@ -42,12 +42,7 @@ export const SingleImport: React.FC<Props> = ({ service, refreshing, handleDelet
|
||||
</h4>
|
||||
<div className="mt-2 flex items-center gap-2 text-xs text-custom-text-200">
|
||||
<span>{renderShortDateWithYearFormat(service.created_at)}</span>|
|
||||
<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>
|
||||
<span>Imported by {service.initiated_by_detail.display_name}</span>
|
||||
</div>
|
||||
</div>
|
||||
<CustomMenu ellipsis>
|
||||
|
@ -122,7 +122,7 @@ export const IssueActivitySection: React.FC<Props> = ({ issueId, user }) => {
|
||||
activityItem.actor_detail.avatar !== "" ? (
|
||||
<img
|
||||
src={activityItem.actor_detail.avatar}
|
||||
alt={activityItem.actor_detail.first_name}
|
||||
alt={activityItem.actor_detail.display_name}
|
||||
height={24}
|
||||
width={24}
|
||||
className="rounded-full"
|
||||
@ -131,7 +131,7 @@ export const IssueActivitySection: React.FC<Props> = ({ issueId, user }) => {
|
||||
<div
|
||||
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>
|
||||
@ -150,8 +150,7 @@ export const IssueActivitySection: React.FC<Props> = ({ issueId, user }) => {
|
||||
) : (
|
||||
<Link href={`/${workspaceSlug}/profile/${activityItem.actor_detail.id}`}>
|
||||
<a className="text-gray font-medium">
|
||||
{activityItem.actor_detail.first_name}{" "}
|
||||
{activityItem.actor_detail.last_name}
|
||||
{activityItem.actor_detail.display_name}
|
||||
</a>
|
||||
</Link>
|
||||
)}{" "}
|
||||
|
@ -77,7 +77,7 @@ export const IssueAttachments = () => {
|
||||
<Tooltip
|
||||
tooltipContent={`${
|
||||
people?.find((person) => person.member.id === file.updated_by)?.member
|
||||
.first_name ?? ""
|
||||
.display_name ?? ""
|
||||
} uploaded on ${renderLongDateFormat(file.updated_at)}`}
|
||||
>
|
||||
<span>
|
||||
|
@ -70,7 +70,7 @@ export const CommentCard: React.FC<Props> = ({ comment, onSubmit, handleCommentD
|
||||
{comment.actor_detail.avatar && comment.actor_detail.avatar !== "" ? (
|
||||
<img
|
||||
src={comment.actor_detail.avatar}
|
||||
alt={comment.actor_detail.first_name}
|
||||
alt={comment.actor_detail.display_name}
|
||||
height={30}
|
||||
width={30}
|
||||
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
|
||||
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>
|
||||
)}
|
||||
|
||||
@ -93,8 +93,9 @@ export const CommentCard: React.FC<Props> = ({ comment, onSubmit, handleCommentD
|
||||
<div className="min-w-0 flex-1">
|
||||
<div>
|
||||
<div className="text-xs">
|
||||
{comment.actor_detail.first_name}
|
||||
{comment.actor_detail.is_bot ? "Bot" : " " + comment.actor_detail.last_name}
|
||||
{comment.actor_detail.is_bot
|
||||
? comment.actor_detail.first_name + " Bot"
|
||||
: comment.actor_detail.display_name}
|
||||
</div>
|
||||
<p className="mt-0.5 text-xs text-custom-text-200">
|
||||
Commented {timeAgo(comment.created_at)}
|
||||
|
@ -30,20 +30,11 @@ export const IssueAssigneeSelect: React.FC<Props> = ({ projectId, value = [], on
|
||||
|
||||
const options = members?.map((member) => ({
|
||||
value: member.member.id,
|
||||
query:
|
||||
(member.member.first_name && member.member.first_name !== ""
|
||||
? member.member.first_name
|
||||
: member.member.email) +
|
||||
" " +
|
||||
member.member.last_name ?? "",
|
||||
query: member.member.display_name ?? "",
|
||||
content: (
|
||||
<div className="flex items-center gap-2">
|
||||
<Avatar user={member.member} />
|
||||
{`${
|
||||
member.member.first_name && member.member.first_name !== ""
|
||||
? member.member.first_name
|
||||
: member.member.email
|
||||
} ${member.member.last_name ?? ""}`}
|
||||
{member.member.display_name}
|
||||
</div>
|
||||
),
|
||||
}));
|
||||
|
@ -41,20 +41,11 @@ export const SidebarAssigneeSelect: React.FC<Props> = ({
|
||||
|
||||
const options = members?.map((member) => ({
|
||||
value: member.member.id,
|
||||
query:
|
||||
(member.member.first_name && member.member.first_name !== ""
|
||||
? member.member.first_name
|
||||
: member.member.email) +
|
||||
" " +
|
||||
member.member.last_name ?? "",
|
||||
query: member.member.display_name,
|
||||
content: (
|
||||
<div className="flex items-center gap-2">
|
||||
<Avatar user={member.member} />
|
||||
{`${
|
||||
member.member.first_name && member.member.first_name !== ""
|
||||
? member.member.first_name
|
||||
: member.member.email
|
||||
} ${member.member.last_name ?? ""}`}
|
||||
{member.member.display_name}
|
||||
</div>
|
||||
),
|
||||
}));
|
||||
|
@ -47,20 +47,11 @@ export const ViewAssigneeSelect: React.FC<Props> = ({
|
||||
|
||||
const options = members?.map((member) => ({
|
||||
value: member.member.id,
|
||||
query:
|
||||
(member.member.first_name && member.member.first_name !== ""
|
||||
? member.member.first_name
|
||||
: member.member.email) +
|
||||
" " +
|
||||
member.member.last_name ?? "",
|
||||
query: member.member.display_name,
|
||||
content: (
|
||||
<div className="flex items-center gap-2">
|
||||
<Avatar user={member.member} />
|
||||
{`${
|
||||
member.member.first_name && member.member.first_name !== ""
|
||||
? member.member.first_name
|
||||
: member.member.email
|
||||
} ${member.member.last_name ?? ""}`}
|
||||
{member.member.display_name}
|
||||
</div>
|
||||
),
|
||||
}));
|
||||
@ -71,11 +62,7 @@ export const ViewAssigneeSelect: React.FC<Props> = ({
|
||||
tooltipHeading="Assignees"
|
||||
tooltipContent={
|
||||
issue.assignee_details.length > 0
|
||||
? issue.assignee_details
|
||||
.map((assignee) =>
|
||||
assignee?.first_name !== "" ? assignee?.first_name : assignee?.email
|
||||
)
|
||||
.join(", ")
|
||||
? issue.assignee_details.map((assignee) => assignee?.display_name).join(", ")
|
||||
: "No Assignee"
|
||||
}
|
||||
>
|
||||
|
@ -32,18 +32,11 @@ export const ModuleLeadSelect: React.FC<Props> = ({ value, onChange }) => {
|
||||
|
||||
const options = members?.map((member) => ({
|
||||
value: member.member.id,
|
||||
query:
|
||||
(member.member.first_name && member.member.first_name !== ""
|
||||
? member.member.first_name
|
||||
: member.member.email) +
|
||||
" " +
|
||||
member.member.last_name ?? "",
|
||||
query: member.member.display_name,
|
||||
content: (
|
||||
<div className="flex items-center gap-2">
|
||||
<Avatar user={member.member} />
|
||||
{member.member.first_name && member.member.first_name !== ""
|
||||
? member.member.first_name
|
||||
: member.member.email}
|
||||
{member.member.display_name}
|
||||
</div>
|
||||
),
|
||||
}));
|
||||
@ -62,11 +55,7 @@ export const ModuleLeadSelect: React.FC<Props> = ({ value, onChange }) => {
|
||||
<UserCircleIcon className="h-4 w-4 text-custom-text-200" />
|
||||
)}
|
||||
{selectedOption ? (
|
||||
selectedOption?.first_name && selectedOption.first_name !== "" ? (
|
||||
selectedOption?.first_name
|
||||
) : (
|
||||
selectedOption?.email
|
||||
)
|
||||
selectedOption?.display_name
|
||||
) : (
|
||||
<span className="text-custom-text-200">Lead</span>
|
||||
)}
|
||||
|
@ -30,18 +30,11 @@ export const ModuleMembersSelect: React.FC<Props> = ({ value, onChange }) => {
|
||||
);
|
||||
const options = members?.map((member) => ({
|
||||
value: member.member.id,
|
||||
query:
|
||||
(member.member.first_name && member.member.first_name !== ""
|
||||
? member.member.first_name
|
||||
: member.member.email) +
|
||||
" " +
|
||||
member.member.last_name ?? "",
|
||||
query: member.member.display_name,
|
||||
content: (
|
||||
<div className="flex items-center gap-2">
|
||||
<Avatar user={member.member} />
|
||||
{member.member.first_name && member.member.first_name !== ""
|
||||
? member.member.first_name
|
||||
: member.member.email}
|
||||
{member.member.display_name}
|
||||
</div>
|
||||
),
|
||||
}));
|
||||
|
@ -33,18 +33,11 @@ export const SidebarLeadSelect: React.FC<Props> = ({ value, onChange }) => {
|
||||
|
||||
const options = members?.map((member) => ({
|
||||
value: member.member.id,
|
||||
query:
|
||||
(member.member.first_name && member.member.first_name !== ""
|
||||
? member.member.first_name
|
||||
: member.member.email) +
|
||||
" " +
|
||||
member.member.last_name ?? "",
|
||||
query: member.member.display_name,
|
||||
content: (
|
||||
<div className="flex items-center gap-2">
|
||||
<Avatar user={member.member} />
|
||||
{member.member.first_name && member.member.first_name !== ""
|
||||
? member.member.first_name
|
||||
: member.member.email}
|
||||
{member.member.display_name}
|
||||
</div>
|
||||
),
|
||||
}));
|
||||
@ -64,11 +57,7 @@ export const SidebarLeadSelect: React.FC<Props> = ({ value, onChange }) => {
|
||||
<div className="flex items-center gap-2">
|
||||
{selectedOption && <Avatar user={selectedOption} />}
|
||||
{selectedOption ? (
|
||||
selectedOption?.first_name && selectedOption.first_name !== "" ? (
|
||||
selectedOption?.first_name
|
||||
) : (
|
||||
selectedOption?.email
|
||||
)
|
||||
selectedOption?.display_name
|
||||
) : (
|
||||
<span className="text-custom-text-200">No lead</span>
|
||||
)}
|
||||
|
@ -31,18 +31,11 @@ export const SidebarMembersSelect: React.FC<Props> = ({ value, onChange }) => {
|
||||
|
||||
const options = members?.map((member) => ({
|
||||
value: member.member.id,
|
||||
query:
|
||||
(member.member.first_name && member.member.first_name !== ""
|
||||
? member.member.first_name
|
||||
: member.member.email) +
|
||||
" " +
|
||||
member.member.last_name ?? "",
|
||||
query: member.member.display_name,
|
||||
content: (
|
||||
<div className="flex items-center gap-2">
|
||||
<Avatar user={member.member} />
|
||||
{member.member.first_name && member.member.first_name !== ""
|
||||
? member.member.first_name
|
||||
: member.member.email}
|
||||
{member.member.display_name}
|
||||
</div>
|
||||
),
|
||||
}));
|
||||
|
@ -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">
|
||||
<span className="text-custom-text-100 font-medium text-lg">
|
||||
{notification.triggered_by_details.first_name?.[0] ? (
|
||||
notification.triggered_by_details.first_name?.[0]?.toUpperCase()
|
||||
{notification.triggered_by_details.display_name?.[0] ? (
|
||||
notification.triggered_by_details.display_name?.[0]?.toUpperCase()
|
||||
) : (
|
||||
<Icon iconName="person" className="h-6 w-6" />
|
||||
)}
|
||||
@ -89,10 +89,7 @@ export const NotificationCard: React.FC<NotificationCardProps> = (props) => {
|
||||
</div>
|
||||
<div className="space-y-2.5 w-full overflow-hidden">
|
||||
<div className="text-sm w-full break-words">
|
||||
<span className="font-semibold">
|
||||
{notification.triggered_by_details.first_name}{" "}
|
||||
{notification.triggered_by_details.last_name}{" "}
|
||||
</span>
|
||||
<span className="font-semibold">{notification.triggered_by_details.display_name} </span>
|
||||
{notification.data.issue_activity.field !== "comment" &&
|
||||
notification.data.issue_activity.verb}{" "}
|
||||
{notification.data.issue_activity.field === "comment"
|
||||
|
@ -162,7 +162,7 @@ export const SinglePageDetailedItem: React.FC<TSingleStatProps> = ({
|
||||
position="top-right"
|
||||
tooltipContent={`Created by ${
|
||||
people?.find((person) => person.member.id === page.created_by)?.member
|
||||
.first_name ?? ""
|
||||
.display_name ?? ""
|
||||
} on ${renderLongDateFormat(`${page.created_at}`)}`}
|
||||
>
|
||||
<span>
|
||||
|
@ -161,7 +161,7 @@ export const SinglePageListItem: React.FC<TSingleStatProps> = ({
|
||||
position="top-right"
|
||||
tooltipContent={`Created by ${
|
||||
people?.find((person) => person.member.id === page.created_by)?.member
|
||||
.first_name ?? ""
|
||||
.display_name ?? ""
|
||||
} on ${renderLongDateFormat(`${page.created_at}`)}`}
|
||||
>
|
||||
<span>
|
||||
|
@ -38,21 +38,21 @@ export const ProfileActivity = () => {
|
||||
{activity.actor_detail.avatar && activity.actor_detail.avatar !== "" ? (
|
||||
<img
|
||||
src={activity.actor_detail.avatar}
|
||||
alt={activity.actor_detail.first_name}
|
||||
alt={activity.actor_detail.display_name}
|
||||
height={24}
|
||||
width={24}
|
||||
className="rounded"
|
||||
/>
|
||||
) : (
|
||||
<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 className="-mt-1 w-4/5 break-words">
|
||||
<p className="text-sm text-custom-text-200">
|
||||
<span className="font-medium text-custom-text-100">
|
||||
{activity.actor_detail.first_name} {activity.actor_detail.last_name}{" "}
|
||||
{activity.actor_detail.display_name}{" "}
|
||||
</span>
|
||||
{activity.field ? (
|
||||
<ActivityMessage activity={activity} showIssue />
|
||||
|
@ -279,10 +279,10 @@ export const ProfileIssuesView = () => {
|
||||
dragDisabled={groupByProperty !== "priority"}
|
||||
emptyState={{
|
||||
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")
|
||||
? `Issues created by ${profileData?.user_data.first_name} ${profileData?.user_data.last_name} will appear here`
|
||||
: `Issues subscribed 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.display_name} will appear here`,
|
||||
}}
|
||||
handleOnDragEnd={handleOnDragEnd}
|
||||
handleIssueAction={handleIssueAction}
|
||||
|
@ -86,29 +86,29 @@ export const ProfileSidebar = () => {
|
||||
userProjectsData.user_data.cover_image ??
|
||||
"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"
|
||||
/>
|
||||
<div className="absolute -bottom-[26px] left-5 h-[52px] w-[52px] rounded">
|
||||
{userProjectsData.user_data.avatar && userProjectsData.user_data.avatar !== "" ? (
|
||||
<img
|
||||
src={userProjectsData.user_data.avatar}
|
||||
alt={userProjectsData.user_data.first_name}
|
||||
alt={userProjectsData.user_data.display_name}
|
||||
className="rounded"
|
||||
/>
|
||||
) : (
|
||||
<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 className="px-5">
|
||||
<div className="mt-[38px]">
|
||||
<h4 className="text-lg font-semibold">
|
||||
{userProjectsData.user_data.first_name} {userProjectsData.user_data.last_name}
|
||||
</h4>
|
||||
<h6 className="text-custom-text-200 text-sm">{userProjectsData.user_data.email}</h6>
|
||||
<h4 className="text-lg font-semibold">{userProjectsData.user_data.display_name}</h4>
|
||||
<h6 className="text-custom-text-200 text-sm">
|
||||
{userProjectsData.user_data.display_name}
|
||||
</h6>
|
||||
</div>
|
||||
<div className="mt-6 space-y-5">
|
||||
{userDetails.map((detail) => (
|
||||
|
@ -67,13 +67,13 @@ const ConfirmProjectMemberRemove: React.FC<Props> = ({ isOpen, onClose, data, ha
|
||||
as="h3"
|
||||
className="text-lg font-medium leading-6 text-custom-text-100"
|
||||
>
|
||||
Remove {data?.email}?
|
||||
Remove {data?.display_name}?
|
||||
</Dialog.Title>
|
||||
<div className="mt-2">
|
||||
<p className="text-sm text-custom-text-200">
|
||||
Are you sure you want to remove member-{" "}
|
||||
<span className="font-bold">{data?.email}</span>? They will no longer have
|
||||
access to this project. This action cannot be undone.
|
||||
<span className="font-bold">{data?.display_name}</span>? They will no
|
||||
longer have access to this project. This action cannot be undone.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -163,20 +163,11 @@ export const CreateProjectModal: React.FC<Props> = ({ isOpen, setIsOpen, user })
|
||||
|
||||
const options = workspaceMembers?.map((member) => ({
|
||||
value: member.member.id,
|
||||
query:
|
||||
(member.member.first_name && member.member.first_name !== ""
|
||||
? member.member.first_name
|
||||
: member.member.email) +
|
||||
" " +
|
||||
member.member.last_name ?? "",
|
||||
query: member.member.display_name,
|
||||
content: (
|
||||
<div className="flex items-center gap-2">
|
||||
<Avatar user={member.member} />
|
||||
{`${
|
||||
member.member.first_name && member.member.first_name !== ""
|
||||
? member.member.first_name
|
||||
: member.member.email
|
||||
} ${member.member.last_name ?? ""}`}
|
||||
{member.member.display_name}
|
||||
</div>
|
||||
),
|
||||
}));
|
||||
@ -376,10 +367,7 @@ export const CreateProjectModal: React.FC<Props> = ({ isOpen, setIsOpen, user })
|
||||
{value ? (
|
||||
<>
|
||||
<Avatar user={selectedMember?.member} />
|
||||
<span>
|
||||
{selectedMember?.member.first_name}{" "}
|
||||
{selectedMember?.member.last_name}
|
||||
</span>
|
||||
<span>{selectedMember?.member.display_name} </span>
|
||||
<span onClick={() => onChange(null)}>
|
||||
<Icon
|
||||
iconName="close"
|
||||
|
@ -82,7 +82,7 @@ const SendProjectInvitationModal: React.FC<Props> = ({ isOpen, setIsOpen, member
|
||||
});
|
||||
|
||||
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;
|
||||
});
|
||||
|
||||
@ -136,11 +136,11 @@ const SendProjectInvitationModal: React.FC<Props> = ({ isOpen, setIsOpen, member
|
||||
|
||||
const options = uninvitedPeople?.map((person) => ({
|
||||
value: person.member.id,
|
||||
query: person.member.email,
|
||||
query: person.member.display_name,
|
||||
content: (
|
||||
<div className="flex items-center gap-2">
|
||||
<Avatar user={person.member} />
|
||||
{person.member.email}
|
||||
{person.member.display_name}
|
||||
</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.email}
|
||||
{
|
||||
people?.find((p) => p.member.id === value)?.member
|
||||
.display_name
|
||||
}
|
||||
</div>
|
||||
) : (
|
||||
<div>Select co-worker’s email</div>
|
||||
|
@ -71,9 +71,7 @@ const SearchListbox: React.FC<Props> = ({
|
||||
} else
|
||||
return (
|
||||
<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.first_name.charAt(0)
|
||||
: user.member.email.charAt(0)}
|
||||
{user.member.display_name.charAt(0)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -47,7 +47,7 @@ export const Avatar: React.FC<AvatarProps> = ({
|
||||
<img
|
||||
src={user.avatar}
|
||||
className="absolute top-0 left-0 h-full w-full object-cover rounded-full"
|
||||
alt={user.first_name}
|
||||
alt={user.display_name}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
@ -59,9 +59,7 @@ export const Avatar: React.FC<AvatarProps> = ({
|
||||
fontSize: fontSize,
|
||||
}}
|
||||
>
|
||||
{user?.first_name && user.first_name !== ""
|
||||
? user.first_name.charAt(0)
|
||||
: user?.email?.charAt(0)}
|
||||
{user?.display_name?.charAt(0)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
@ -127,9 +127,7 @@ export const SelectFilters: React.FC<Props> = ({
|
||||
label: (
|
||||
<div className="flex items-center gap-2">
|
||||
<Avatar user={member.member} />
|
||||
{member.member.first_name && member.member.first_name !== ""
|
||||
? member.member.first_name
|
||||
: member.member.email}
|
||||
{member.member.display_name}
|
||||
</div>
|
||||
),
|
||||
value: {
|
||||
@ -149,9 +147,7 @@ export const SelectFilters: React.FC<Props> = ({
|
||||
label: (
|
||||
<div className="flex items-center gap-2">
|
||||
<Avatar user={member.member} />
|
||||
{member.member.first_name && member.member.first_name !== ""
|
||||
? member.member.first_name
|
||||
: member.member.email}
|
||||
{member.member.display_name}
|
||||
</div>
|
||||
),
|
||||
value: {
|
||||
|
@ -67,13 +67,13 @@ const ConfirmWorkspaceMemberRemove: React.FC<Props> = ({ isOpen, onClose, data,
|
||||
as="h3"
|
||||
className="text-lg font-medium leading-6 text-custom-text-100"
|
||||
>
|
||||
Remove {data?.email}?
|
||||
Remove {data?.display_name}?
|
||||
</Dialog.Title>
|
||||
<div className="mt-2">
|
||||
<p className="text-sm text-custom-text-200">
|
||||
Are you sure you want to remove member-{" "}
|
||||
<span className="font-bold">{data?.email}</span>? They will no longer have
|
||||
access to this workspace. This action cannot be undone.
|
||||
<span className="font-bold">{data?.display_name}</span>? They will no
|
||||
longer have access to this workspace. This action cannot be undone.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -149,7 +149,7 @@ export const WorkspaceSidebarDropdown = () => {
|
||||
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="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>
|
||||
{workspaces ? (
|
||||
<div className="flex h-full w-full flex-col items-start justify-start gap-3.5">
|
||||
|
@ -41,8 +41,8 @@ const SingleInvitation: React.FC<Props> = ({
|
||||
<p className="text-sm text-custom-text-200">
|
||||
Invited by{" "}
|
||||
{invitation.created_by_detail
|
||||
? invitation.created_by_detail.first_name
|
||||
: invitation.workspace.owner.first_name}
|
||||
? invitation.created_by_detail.display_name
|
||||
: invitation.workspace.owner.display_name}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex-shrink-0 self-center">
|
||||
|
@ -19,7 +19,7 @@ export const ANALYTICS_X_AXIS_VALUES: { value: TXAxisValues; label: string }[] =
|
||||
label: "Label",
|
||||
},
|
||||
{
|
||||
value: "assignees__email",
|
||||
value: "assignees__id",
|
||||
label: "Assignee",
|
||||
},
|
||||
{
|
||||
|
@ -69,9 +69,13 @@ export const WORKSPACE_DETAILS = (workspaceSlug: string) =>
|
||||
|
||||
export const WORKSPACE_MEMBERS = (workspaceSlug: string) =>
|
||||
`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) =>
|
||||
`WORKSPACE_MEMBERS_ME${workspaceSlug.toUpperCase()}`;
|
||||
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 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_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_WITH_EMAIL = (workspaceSlug: string, projectId: string) =>
|
||||
`PROJECT_INVITATIONS_WITH_EMAIL_${workspaceSlug}_${projectId.toUpperCase()}`;
|
||||
|
||||
export const PROJECT_ISSUES_LIST = (workspaceSlug: string, projectId: string) =>
|
||||
`PROJECT_ISSUES_LIST_${workspaceSlug.toUpperCase()}_${projectId.toUpperCase()}`;
|
||||
|
@ -32,8 +32,8 @@ export const SPREADSHEET_COLUMN = [
|
||||
colName: "Assignees",
|
||||
colSize: "128px",
|
||||
icon: UserGroupIcon,
|
||||
ascendingOrder: "assignees__first_name",
|
||||
descendingOrder: "-assignees__first_name",
|
||||
ascendingOrder: "assignees__id",
|
||||
descendingOrder: "-assignees__id",
|
||||
},
|
||||
{
|
||||
propertyName: "labels",
|
||||
|
@ -73,7 +73,7 @@ const ProfileActivity = () => {
|
||||
activityItem.actor_detail.avatar !== "" ? (
|
||||
<img
|
||||
src={activityItem.actor_detail.avatar}
|
||||
alt={activityItem.actor_detail.first_name}
|
||||
alt={activityItem.actor_detail.display_name}
|
||||
height={30}
|
||||
width={30}
|
||||
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
|
||||
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>
|
||||
)}
|
||||
|
||||
@ -96,10 +96,9 @@ const ProfileActivity = () => {
|
||||
<div className="min-w-0 flex-1">
|
||||
<div>
|
||||
<div className="text-xs">
|
||||
{activityItem.actor_detail.first_name}
|
||||
{activityItem.actor_detail.is_bot
|
||||
? "Bot"
|
||||
: " " + activityItem.actor_detail.last_name}
|
||||
? activityItem.actor_detail.first_name + " Bot"
|
||||
: activityItem.actor_detail.display_name}
|
||||
</div>
|
||||
<p className="mt-0.5 text-xs text-custom-text-200">
|
||||
Commented {timeAgo(activityItem.created_at)}
|
||||
@ -176,7 +175,7 @@ const ProfileActivity = () => {
|
||||
activityItem.actor_detail.avatar !== "" ? (
|
||||
<img
|
||||
src={activityItem.actor_detail.avatar}
|
||||
alt={activityItem.actor_detail.first_name}
|
||||
alt={activityItem.actor_detail.display_name}
|
||||
height={24}
|
||||
width={24}
|
||||
className="rounded-full"
|
||||
@ -185,7 +184,7 @@ const ProfileActivity = () => {
|
||||
<div
|
||||
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>
|
||||
@ -206,8 +205,7 @@ const ProfileActivity = () => {
|
||||
href={`/${workspaceSlug}/profile/${activityItem.actor_detail.id}`}
|
||||
>
|
||||
<a className="text-gray font-medium">
|
||||
{activityItem.actor_detail.first_name}{" "}
|
||||
{activityItem.actor_detail.last_name}
|
||||
{activityItem.actor_detail.display_name}
|
||||
</a>
|
||||
</Link>
|
||||
)}{" "}
|
||||
|
@ -176,7 +176,7 @@ const Profile: NextPage = () => {
|
||||
src={watch("avatar")}
|
||||
className="absolute top-0 left-0 h-full w-full object-cover rounded-md"
|
||||
onClick={() => setIsImageUploadModalOpen(true)}
|
||||
alt={myProfile.first_name}
|
||||
alt={myProfile.display_name}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
@ -131,7 +131,7 @@ const ControlSettings: NextPage = () => {
|
||||
{...field}
|
||||
label={
|
||||
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"
|
||||
input
|
||||
@ -153,14 +153,10 @@ const ControlSettings: NextPage = () => {
|
||||
</div>
|
||||
) : (
|
||||
<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.first_name.charAt(0)
|
||||
: person.member.email.charAt(0)}
|
||||
{person.member.display_name?.charAt(0)}
|
||||
</div>
|
||||
)}
|
||||
{person.member.first_name !== ""
|
||||
? person.member.first_name
|
||||
: person.member.email}
|
||||
{person.member.display_name}
|
||||
</div>
|
||||
</CustomSelect.Option>
|
||||
))}
|
||||
@ -190,7 +186,7 @@ const ControlSettings: NextPage = () => {
|
||||
<CustomSelect
|
||||
{...field}
|
||||
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>
|
||||
)
|
||||
}
|
||||
@ -214,14 +210,10 @@ const ControlSettings: NextPage = () => {
|
||||
</div>
|
||||
) : (
|
||||
<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.first_name.charAt(0)
|
||||
: person.member.email.charAt(0)}
|
||||
{person.member.display_name?.charAt(0)}
|
||||
</div>
|
||||
)}
|
||||
{person.member.first_name !== ""
|
||||
? person.member.first_name
|
||||
: person.member.email}
|
||||
{person.member.display_name}
|
||||
</div>
|
||||
</CustomSelect.Option>
|
||||
))}
|
||||
|
@ -26,7 +26,11 @@ import { PlusIcon, XMarkIcon } from "@heroicons/react/24/outline";
|
||||
// types
|
||||
import type { NextPage } from "next";
|
||||
// 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
|
||||
import { ROLE } from "constants/workspace";
|
||||
// helper
|
||||
@ -51,16 +55,21 @@ const MembersSettings: NextPage = () => {
|
||||
);
|
||||
|
||||
const { data: projectMembers, mutate: mutateMembers } = useSWR(
|
||||
workspaceSlug && projectId ? PROJECT_MEMBERS(projectId as string) : null,
|
||||
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
|
||||
);
|
||||
|
||||
const { data: projectInvitations, mutate: mutateInvitations } = useSWR(
|
||||
workspaceSlug && projectId ? PROJECT_INVITATIONS : null,
|
||||
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
|
||||
);
|
||||
|
||||
@ -71,7 +80,7 @@ const MembersSettings: NextPage = () => {
|
||||
avatar: item.member?.avatar,
|
||||
first_name: item.member?.first_name,
|
||||
last_name: item.member?.last_name,
|
||||
email: item.member?.email,
|
||||
display_name: item.member?.display_name,
|
||||
role: item.role,
|
||||
status: true,
|
||||
member: true,
|
||||
@ -82,7 +91,7 @@ const MembersSettings: NextPage = () => {
|
||||
avatar: item.avatar ?? "",
|
||||
first_name: item.first_name ?? item.email,
|
||||
last_name: item.last_name ?? "",
|
||||
email: item.email,
|
||||
display_name: item.email,
|
||||
role: item.role,
|
||||
status: item.accepted,
|
||||
member: false,
|
||||
@ -181,28 +190,24 @@ const MembersSettings: NextPage = () => {
|
||||
{member.avatar && member.avatar !== "" ? (
|
||||
<img
|
||||
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"
|
||||
/>
|
||||
) : member.first_name !== "" ? (
|
||||
member.first_name.charAt(0)
|
||||
) : (
|
||||
member.email.charAt(0)
|
||||
member.display_name.charAt(0)
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
{member.member ? (
|
||||
<Link href={`/${workspaceSlug}/profile/${member.memberId}`}>
|
||||
<a className="text-sm">
|
||||
{member.first_name} {member.last_name}
|
||||
</a>
|
||||
<a className="text-sm">{member.display_name}</a>
|
||||
</Link>
|
||||
) : (
|
||||
<h4 className="text-sm">
|
||||
{member.first_name} {member.last_name}
|
||||
</h4>
|
||||
<h4 className="text-sm">{member.display_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 className="flex items-center gap-2 text-xs">
|
||||
|
@ -24,7 +24,11 @@ import { PlusIcon } from "@heroicons/react/24/outline";
|
||||
// types
|
||||
import type { NextPage } from "next";
|
||||
// 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
|
||||
import { ROLE } from "constants/workspace";
|
||||
// helper
|
||||
@ -48,13 +52,17 @@ const MembersSettings: NextPage = () => {
|
||||
);
|
||||
|
||||
const { data: workspaceMembers, mutate: mutateMembers } = useSWR(
|
||||
workspaceSlug ? WORKSPACE_MEMBERS(workspaceSlug.toString()) : null,
|
||||
workspaceSlug ? () => workspaceService.workspaceMembers(workspaceSlug.toString()) : null
|
||||
workspaceSlug ? WORKSPACE_MEMBERS_WITH_EMAIL(workspaceSlug.toString()) : null,
|
||||
workspaceSlug
|
||||
? () => workspaceService.workspaceMembersWithEmail(workspaceSlug.toString())
|
||||
: null
|
||||
);
|
||||
|
||||
const { data: workspaceInvitations, mutate: mutateInvitations } = useSWR(
|
||||
workspaceSlug ? WORKSPACE_INVITATIONS : null,
|
||||
workspaceSlug ? () => workspaceService.workspaceInvitations(workspaceSlug.toString()) : null
|
||||
workspaceSlug ? WORKSPACE_INVITATION_WITH_EMAIL(workspaceSlug.toString()) : null,
|
||||
workspaceSlug
|
||||
? () => workspaceService.workspaceInvitationsWithEmail(workspaceSlug.toString())
|
||||
: null
|
||||
);
|
||||
|
||||
const members = [
|
||||
@ -65,6 +73,7 @@ const MembersSettings: NextPage = () => {
|
||||
first_name: item.member?.first_name,
|
||||
last_name: item.member?.last_name,
|
||||
email: item.member?.email,
|
||||
display_name: item.member?.display_name,
|
||||
role: item.role,
|
||||
status: true,
|
||||
member: true,
|
||||
@ -77,6 +86,7 @@ const MembersSettings: NextPage = () => {
|
||||
first_name: item.email,
|
||||
last_name: "",
|
||||
email: item.email,
|
||||
display_name: item.email,
|
||||
role: item.role,
|
||||
status: item.accepted,
|
||||
member: false,
|
||||
@ -199,27 +209,23 @@ const MembersSettings: NextPage = () => {
|
||||
<img
|
||||
src={member.avatar}
|
||||
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>
|
||||
{member.member ? (
|
||||
<Link href={`/${workspaceSlug}/profile/${member.memberId}`}>
|
||||
<a className="text-sm">
|
||||
{member.first_name} {member.last_name}
|
||||
</a>
|
||||
<a className="text-sm">{member.display_name || member.email}</a>
|
||||
</Link>
|
||||
) : (
|
||||
<h4 className="text-sm">
|
||||
{member.first_name} {member.last_name}
|
||||
</h4>
|
||||
<h4 className="text-sm">{member.display_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 className="flex items-center gap-2 text-xs">
|
||||
|
@ -26,6 +26,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
email: user.email,
|
||||
first_name: user.first_name,
|
||||
last_name: user.last_name,
|
||||
display_name: user?.display_name,
|
||||
})
|
||||
.then(() => {
|
||||
jitsu.track(eventName, {
|
||||
|
@ -151,6 +151,17 @@ class ProjectServices extends APIService {
|
||||
}
|
||||
|
||||
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/`)
|
||||
.then((response) => response?.data)
|
||||
.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(
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
|
@ -155,6 +155,14 @@ class WorkspaceService extends APIService {
|
||||
}
|
||||
|
||||
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/`)
|
||||
.then((response) => response?.data)
|
||||
.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> {
|
||||
return this.get(`/api/users/me/invitations/${invitationId}/`, { headers: {} })
|
||||
.then((response) => response?.data)
|
||||
|
8
apps/app/types/analytics.d.ts
vendored
8
apps/app/types/analytics.d.ts
vendored
@ -4,8 +4,8 @@ export interface IAnalyticsResponse {
|
||||
extras: {
|
||||
colors: IAnalyticsExtra[];
|
||||
assignee_details: {
|
||||
assignees__display_name: string | null;
|
||||
assignees__avatar: string | null;
|
||||
assignees__email: string;
|
||||
assignees__first_name: string;
|
||||
assignees__last_name: string;
|
||||
}[];
|
||||
@ -30,7 +30,7 @@ export type TXAxisValues =
|
||||
| "state__name"
|
||||
| "state__group"
|
||||
| "labels__name"
|
||||
| "assignees__email"
|
||||
| "assignees__id"
|
||||
| "estimate_point"
|
||||
| "issue_cycle__cycle__name"
|
||||
| "issue_module__module__name"
|
||||
@ -65,9 +65,9 @@ export interface IExportAnalyticsFormData {
|
||||
|
||||
export interface IDefaultAnalyticsUser {
|
||||
assignees__avatar: string | null;
|
||||
assignees__email: string | null;
|
||||
assignees__first_name: string;
|
||||
assignees__last_name: string;
|
||||
assignees__display_name: string;
|
||||
count: number;
|
||||
}
|
||||
|
||||
@ -76,9 +76,9 @@ export interface IDefaultAnalyticsResponse {
|
||||
most_issue_closed_user: IDefaultAnalyticsUser[];
|
||||
most_issue_created_user: {
|
||||
created_by__avatar: string | null;
|
||||
created_by__email: string | null;
|
||||
created_by__first_name: string;
|
||||
created_by__last_name: string;
|
||||
created_by__display_name: string;
|
||||
count: number;
|
||||
}[];
|
||||
open_estimate_sum: number;
|
||||
|
1
apps/app/types/cycles.d.ts
vendored
1
apps/app/types/cycles.d.ts
vendored
@ -49,6 +49,7 @@ export type TAssigneesDistribution = {
|
||||
completed_issues: number;
|
||||
first_name: string | null;
|
||||
last_name: string | null;
|
||||
display_name: string | null;
|
||||
pending_issues: number;
|
||||
total_issues: number;
|
||||
};
|
||||
|
3
apps/app/types/projects.d.ts
vendored
3
apps/app/types/projects.d.ts
vendored
@ -3,6 +3,7 @@ import type {
|
||||
IUserLite,
|
||||
IWorkspace,
|
||||
IWorkspaceLite,
|
||||
IUserMemberLite,
|
||||
TIssueGroupByOptions,
|
||||
TIssueOrderByOptions,
|
||||
TIssueViewOptions,
|
||||
@ -78,7 +79,7 @@ type ProjectPreferences = {
|
||||
|
||||
export interface IProjectMember {
|
||||
id: string;
|
||||
member: IUserLite;
|
||||
member: IUserMemberLite;
|
||||
project: IProjectLite;
|
||||
workspace: IWorkspaceLite;
|
||||
comment: string;
|
||||
|
9
apps/app/types/users.d.ts
vendored
9
apps/app/types/users.d.ts
vendored
@ -15,6 +15,7 @@ export interface IUser {
|
||||
created_location: readonly string;
|
||||
date_joined: readonly Date;
|
||||
email: string;
|
||||
display_name: string;
|
||||
first_name: string;
|
||||
id: readonly string;
|
||||
is_email_verified: boolean;
|
||||
@ -53,13 +54,17 @@ export interface ICurrentUserResponse extends IUser {
|
||||
export interface IUserLite {
|
||||
avatar: string;
|
||||
created_at: Date;
|
||||
email: string;
|
||||
display_name: string;
|
||||
first_name: string;
|
||||
readonly id: string;
|
||||
is_bot: boolean;
|
||||
last_name: string;
|
||||
}
|
||||
|
||||
export interface IUserMemberLite extends IUserLite {
|
||||
email: string;
|
||||
}
|
||||
|
||||
export interface IUserActivity {
|
||||
created_date: string;
|
||||
activity_count: number;
|
||||
@ -141,7 +146,7 @@ export interface IUserProfileProjectSegregation {
|
||||
avatar: string;
|
||||
cover_image: string | null;
|
||||
date_joined: Date;
|
||||
email: string;
|
||||
display_name: string;
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
user_timezone: string;
|
||||
|
5
apps/app/types/workspace.d.ts
vendored
5
apps/app/types/workspace.d.ts
vendored
@ -2,7 +2,7 @@ import type {
|
||||
IIssueFilterOptions,
|
||||
IProjectMember,
|
||||
IUser,
|
||||
IUserLite,
|
||||
IUserMemberLite,
|
||||
TIssueGroupByOptions,
|
||||
TIssueOrderByOptions,
|
||||
TIssueViewOptions,
|
||||
@ -73,9 +73,8 @@ export interface IWorkspaceViewProps {
|
||||
|
||||
export interface IWorkspaceMember {
|
||||
readonly id: string;
|
||||
user: IUserLite;
|
||||
workspace: IWorkspace;
|
||||
member: IUserLite;
|
||||
member: IUserMemberLite;
|
||||
role: 5 | 10 | 15 | 20;
|
||||
company_role: string | null;
|
||||
view_props: IWorkspaceViewProps;
|
||||
|
Loading…
Reference in New Issue
Block a user