mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
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 (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";
|
||||||
|
@ -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 !== "")
|
||||||
|
@ -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>
|
||||||
|
@ -21,115 +21,96 @@ 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 => {
|
<div className="flow-root">
|
||||||
const assignee = analytics.extras.assignee_details.find((a) => a.assignees__email === email);
|
<div className="overflow-x-auto">
|
||||||
|
<div className="inline-block min-w-full align-middle">
|
||||||
if (!assignee) return "No assignee";
|
<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">
|
||||||
if (assignee.assignees__first_name !== "")
|
<tr className="divide-x divide-custom-border-200 text-sm text-custom-text-100">
|
||||||
return assignee.assignees__first_name + " " + assignee.assignees__last_name;
|
<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}
|
||||||
return email;
|
</th>
|
||||||
};
|
{params.segment ? (
|
||||||
|
barGraphData.xAxisKeys.map((key) => (
|
||||||
return (
|
<th
|
||||||
<div className="flow-root">
|
key={`segment-${key}`}
|
||||||
<div className="overflow-x-auto">
|
scope="col"
|
||||||
<div className="inline-block min-w-full align-middle">
|
className={`px-2.5 py-3 text-left font-medium ${
|
||||||
<table className="min-w-full divide-y divide-custom-border-200 whitespace-nowrap border-y border-custom-border-200">
|
params.segment === "priority" || params.segment === "state__group"
|
||||||
<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"
|
|
||||||
? "capitalize"
|
? "capitalize"
|
||||||
: ""
|
: ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{params.x_axis === "priority" ? (
|
<div className="flex items-center gap-2">
|
||||||
getPriorityIcon(`${item.name}`)
|
{params.segment === "priority" ? (
|
||||||
) : (
|
getPriorityIcon(key)
|
||||||
<span
|
) : (
|
||||||
className="h-3 w-3 rounded"
|
<span
|
||||||
style={{
|
className="h-3 w-3 flex-shrink-0 rounded"
|
||||||
backgroundColor: generateBarColor(
|
style={{
|
||||||
`${item.name}`,
|
backgroundColor: generateBarColor(key, analytics, params, "segment"),
|
||||||
analytics,
|
}}
|
||||||
params,
|
/>
|
||||||
"x_axis"
|
)}
|
||||||
),
|
{DATE_KEYS.includes(params.segment ?? "") ? renderMonthAndYear(key) : key}
|
||||||
}}
|
</div>
|
||||||
/>
|
</th>
|
||||||
)}
|
))
|
||||||
{params.x_axis === "assignees__email"
|
) : (
|
||||||
? renderAssigneeName(`${item.name}`)
|
<th scope="col" className="py-3 px-2.5 text-left font-medium sm:pr-0">
|
||||||
: addSpaceIfCamelCase(`${item.name}`)}
|
{ANALYTICS_Y_AXIS_VALUES.find((v) => v.value === params.y_axis)?.label}
|
||||||
</td>
|
</th>
|
||||||
{params.segment ? (
|
)}
|
||||||
barGraphData.xAxisKeys.map((key, index) => (
|
</tr>
|
||||||
<td
|
</thead>
|
||||||
key={`segment-value-${index}`}
|
<tbody className="divide-y divide-custom-border-200">
|
||||||
className="whitespace-nowrap py-2 px-2.5 sm:pr-0"
|
{barGraphData.data.map((item, index) => (
|
||||||
>
|
<tr
|
||||||
{item[key] ?? 0}
|
key={`table-row-${index}`}
|
||||||
</td>
|
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>
|
{addSpaceIfCamelCase(`${item.name}`)}
|
||||||
))}
|
</td>
|
||||||
</tbody>
|
{params.segment ? (
|
||||||
</table>
|
barGraphData.xAxisKeys.map((key, index) => (
|
||||||
</div>
|
<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>
|
</div>
|
||||||
);
|
</div>
|
||||||
};
|
);
|
||||||
|
@ -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>
|
||||||
|
@ -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"
|
||||||
|
@ -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>
|
||||||
|
@ -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>
|
||||||
|
@ -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={() =>
|
||||||
|
@ -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>
|
||||||
|
@ -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}
|
||||||
|
@ -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",
|
||||||
}}
|
}}
|
||||||
|
@ -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>
|
||||||
) : (
|
) : (
|
||||||
|
@ -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 && (
|
||||||
|
@ -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}
|
||||||
|
@ -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>
|
||||||
|
|
||||||
|
@ -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">
|
||||||
|
@ -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>
|
||||||
|
@ -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>
|
||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
|
@ -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>
|
||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
|
@ -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>
|
||||||
|
@ -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>
|
||||||
)}{" "}
|
)}{" "}
|
||||||
|
@ -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>
|
||||||
|
@ -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)}
|
||||||
|
@ -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>
|
||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
|
@ -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>
|
||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
|
@ -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"
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
@ -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>
|
||||||
)}
|
)}
|
||||||
|
@ -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>
|
||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
|
@ -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>
|
||||||
)}
|
)}
|
||||||
|
@ -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>
|
||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
|
@ -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"
|
||||||
|
@ -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>
|
||||||
|
@ -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>
|
||||||
|
@ -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 />
|
||||||
|
@ -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}
|
||||||
|
@ -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) => (
|
||||||
|
@ -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>
|
||||||
|
@ -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"
|
||||||
|
@ -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’s email</div>
|
<div>Select co-worker’s email</div>
|
||||||
|
@ -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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -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>
|
||||||
|
@ -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: {
|
||||||
|
@ -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>
|
||||||
|
@ -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">
|
||||||
|
@ -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">
|
||||||
|
@ -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",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -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()}`;
|
||||||
|
@ -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",
|
||||||
|
@ -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>
|
||||||
)}{" "}
|
)}{" "}
|
||||||
|
@ -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>
|
||||||
)}
|
)}
|
||||||
|
@ -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>
|
||||||
))}
|
))}
|
||||||
|
@ -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">
|
||||||
|
@ -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">
|
||||||
|
@ -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, {
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
|
8
apps/app/types/analytics.d.ts
vendored
8
apps/app/types/analytics.d.ts
vendored
@ -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;
|
||||||
|
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;
|
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;
|
||||||
};
|
};
|
||||||
|
3
apps/app/types/projects.d.ts
vendored
3
apps/app/types/projects.d.ts
vendored
@ -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;
|
||||||
|
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;
|
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;
|
||||||
|
5
apps/app/types/workspace.d.ts
vendored
5
apps/app/types/workspace.d.ts
vendored
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user