[WEB-3792, 3823] fix: intake form version history (#6898)

* chore: intake form version history

* fix: remove autofocus from the copy markdown button

* chore: add logic to display deactivated user
This commit is contained in:
Aaryan Khandelwal 2025-04-09 19:56:59 +05:30 committed by GitHub
parent 14914e8716
commit ef20b5814e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 159 additions and 112 deletions

View file

@ -1,91 +1,97 @@
import { TInboxDuplicateIssueDetails, TIssue } from "@plane/types"; import { TInboxDuplicateIssueDetails, TIssue } from "@plane/types";
export enum EInboxIssueCurrentTab { export enum EInboxIssueCurrentTab {
OPEN = "open", OPEN = "open",
CLOSED = "closed", CLOSED = "closed",
} }
export enum EInboxIssueStatus { export enum EInboxIssueStatus {
PENDING = -2, PENDING = -2,
DECLINED = -1, DECLINED = -1,
SNOOZED = 0, SNOOZED = 0,
ACCEPTED = 1, ACCEPTED = 1,
DUPLICATE = 2, DUPLICATE = 2,
}
export enum EInboxIssueSource {
IN_APP = "IN_APP",
FORMS = "FORMS",
EMAIL = "EMAIL",
} }
export type TInboxIssueCurrentTab = EInboxIssueCurrentTab; export type TInboxIssueCurrentTab = EInboxIssueCurrentTab;
export type TInboxIssueStatus = EInboxIssueStatus; export type TInboxIssueStatus = EInboxIssueStatus;
export type TInboxIssue = { export type TInboxIssue = {
id: string; id: string;
status: TInboxIssueStatus; status: TInboxIssueStatus;
snoozed_till: Date | null; snoozed_till: Date | null;
duplicate_to: string | undefined; duplicate_to: string | undefined;
source: string; source: EInboxIssueSource | undefined;
issue: TIssue; issue: TIssue;
created_by: string; created_by: string;
duplicate_issue_detail: TInboxDuplicateIssueDetails | undefined; duplicate_issue_detail: TInboxDuplicateIssueDetails | undefined;
}; };
export const INBOX_STATUS: { export const INBOX_STATUS: {
key: string; key: string;
status: TInboxIssueStatus; status: TInboxIssueStatus;
i18n_title: string; i18n_title: string;
i18n_description: () => string; i18n_description: () => string;
}[] = [ }[] = [
{ {
key: "pending", key: "pending",
i18n_title: "inbox_issue.status.pending.title", i18n_title: "inbox_issue.status.pending.title",
status: EInboxIssueStatus.PENDING, status: EInboxIssueStatus.PENDING,
i18n_description: () => `inbox_issue.status.pending.description`, i18n_description: () => `inbox_issue.status.pending.description`,
}, },
{ {
key: "declined", key: "declined",
i18n_title: "inbox_issue.status.declined.title", i18n_title: "inbox_issue.status.declined.title",
status: EInboxIssueStatus.DECLINED, status: EInboxIssueStatus.DECLINED,
i18n_description: () => `inbox_issue.status.declined.description`, i18n_description: () => `inbox_issue.status.declined.description`,
}, },
{ {
key: "snoozed", key: "snoozed",
i18n_title: "inbox_issue.status.snoozed.title", i18n_title: "inbox_issue.status.snoozed.title",
status: EInboxIssueStatus.SNOOZED, status: EInboxIssueStatus.SNOOZED,
i18n_description: () => `inbox_issue.status.snoozed.description`, i18n_description: () => `inbox_issue.status.snoozed.description`,
}, },
{ {
key: "accepted", key: "accepted",
i18n_title: "inbox_issue.status.accepted.title", i18n_title: "inbox_issue.status.accepted.title",
status: EInboxIssueStatus.ACCEPTED, status: EInboxIssueStatus.ACCEPTED,
i18n_description: () => `inbox_issue.status.accepted.description`, i18n_description: () => `inbox_issue.status.accepted.description`,
}, },
{ {
key: "duplicate", key: "duplicate",
i18n_title: "inbox_issue.status.duplicate.title", i18n_title: "inbox_issue.status.duplicate.title",
status: EInboxIssueStatus.DUPLICATE, status: EInboxIssueStatus.DUPLICATE,
i18n_description: () => `inbox_issue.status.duplicate.description`, i18n_description: () => `inbox_issue.status.duplicate.description`,
}, },
]; ];
export const INBOX_ISSUE_ORDER_BY_OPTIONS = [ export const INBOX_ISSUE_ORDER_BY_OPTIONS = [
{ {
key: "issue__created_at", key: "issue__created_at",
i18n_label: "inbox_issue.order_by.created_at", i18n_label: "inbox_issue.order_by.created_at",
}, },
{ {
key: "issue__updated_at", key: "issue__updated_at",
i18n_label: "inbox_issue.order_by.updated_at", i18n_label: "inbox_issue.order_by.updated_at",
}, },
{ {
key: "issue__sequence_id", key: "issue__sequence_id",
i18n_label: "inbox_issue.order_by.id", i18n_label: "inbox_issue.order_by.id",
}, },
]; ];
export const INBOX_ISSUE_SORT_BY_OPTIONS = [ export const INBOX_ISSUE_SORT_BY_OPTIONS = [
{ {
key: "asc", key: "asc",
i18n_label: "common.sort.asc", i18n_label: "common.sort.asc",
}, },
{ {
key: "desc", key: "desc",
i18n_label: "common.sort.desc", i18n_label: "common.sort.desc",
}, },
]; ];

View file

@ -867,7 +867,8 @@
"deleting": "Mazání", "deleting": "Mazání",
"pending": "Čekající", "pending": "Čekající",
"invite": "Pozvat", "invite": "Pozvat",
"view": "Pohled" "view": "Pohled",
"deactivated_user": "Deaktivovaný uživatel"
}, },
"chart": { "chart": {

View file

@ -862,7 +862,8 @@
"deleting": "Wird gelöscht", "deleting": "Wird gelöscht",
"pending": "Ausstehend", "pending": "Ausstehend",
"invite": "Einladen", "invite": "Einladen",
"view": "Ansicht" "view": "Ansicht",
"deactivated_user": "Deaktivierter Benutzer"
}, },
"chart": { "chart": {
"x_axis": "X-Achse", "x_axis": "X-Achse",

View file

@ -702,7 +702,8 @@
"deleting": "Deleting", "deleting": "Deleting",
"pending": "Pending", "pending": "Pending",
"invite": "Invite", "invite": "Invite",
"view": "View" "view": "View",
"deactivated_user": "Deactivated user"
}, },
"chart": { "chart": {

View file

@ -872,7 +872,8 @@
"deleting": "Eliminando", "deleting": "Eliminando",
"pending": "Pendiente", "pending": "Pendiente",
"invite": "Invitar", "invite": "Invitar",
"view": "Ver" "view": "Ver",
"deactivated_user": "Usuario desactivado"
}, },
"chart": { "chart": {

View file

@ -870,7 +870,8 @@
"deleting": "Suppression", "deleting": "Suppression",
"pending": "En attente", "pending": "En attente",
"invite": "Inviter", "invite": "Inviter",
"view": "Afficher" "view": "Afficher",
"deactivated_user": "Utilisateur désactivé"
}, },
"chart": { "chart": {

View file

@ -869,7 +869,8 @@
"deleting": "Menghapus", "deleting": "Menghapus",
"pending": "Tertunda", "pending": "Tertunda",
"invite": "Undang", "invite": "Undang",
"view": "Lihat" "view": "Lihat",
"deactivated_user": "Pengguna dinonaktifkan"
}, },
"chart": { "chart": {

View file

@ -868,7 +868,8 @@
"deleting": "Eliminazione in corso", "deleting": "Eliminazione in corso",
"pending": "In sospeso", "pending": "In sospeso",
"invite": "Invita", "invite": "Invita",
"view": "Visualizza" "view": "Visualizza",
"deactivated_user": "Utente disattivato"
}, },
"chart": { "chart": {

View file

@ -870,7 +870,8 @@
"deleting": "デリーティング", "deleting": "デリーティング",
"pending": "保留中", "pending": "保留中",
"invite": "招待", "invite": "招待",
"view": "ビュー" "view": "ビュー",
"deactivated_user": "無効化されたユーザー"
}, },
"chart": { "chart": {

View file

@ -871,7 +871,8 @@
"deleting": "삭제 중", "deleting": "삭제 중",
"pending": "보류 중", "pending": "보류 중",
"invite": "초대", "invite": "초대",
"view": "보기" "view": "보기",
"deactivated_user": "비활성화된 사용자"
}, },
"chart": { "chart": {

View file

@ -865,7 +865,8 @@
"deleting": "Usuwanie", "deleting": "Usuwanie",
"pending": "Oczekujące", "pending": "Oczekujące",
"invite": "Zaproś", "invite": "Zaproś",
"view": "Widok" "view": "Widok",
"deactivated_user": "Dezaktywowany użytkownik"
}, },
"chart": { "chart": {
"x_axis": "Oś X", "x_axis": "Oś X",

View file

@ -871,7 +871,8 @@
"deleting": "Excluindo", "deleting": "Excluindo",
"pending": "Pendente", "pending": "Pendente",
"invite": "Convidar", "invite": "Convidar",
"view": "Visualizar" "view": "Visualizar",
"deactivated_user": "Usuário desativado"
}, },
"chart": { "chart": {

View file

@ -869,7 +869,8 @@
"deleting": "Se șterge", "deleting": "Se șterge",
"pending": "În așteptare", "pending": "În așteptare",
"invite": "Invită", "invite": "Invită",
"view": "Vizualizează" "view": "Vizualizează",
"deactivated_user": "Utilizator dezactivat"
}, },
"chart": { "chart": {

View file

@ -869,7 +869,8 @@
"deleting": "Удаление", "deleting": "Удаление",
"pending": "Ожидание", "pending": "Ожидание",
"invite": "Пригласить", "invite": "Пригласить",
"view": "Просмотр" "view": "Просмотр",
"deactivated_user": "Деактивированный пользователь"
}, },
"chart": { "chart": {

View file

@ -869,7 +869,8 @@
"deleting": "Mazanie", "deleting": "Mazanie",
"pending": "Čakajúce", "pending": "Čakajúce",
"invite": "Pozvať", "invite": "Pozvať",
"view": "Zobraziť" "view": "Zobraziť",
"deactivated_user": "Deaktivovaný používateľ"
}, },
"chart": { "chart": {

View file

@ -864,7 +864,8 @@
"deleting": "Видалення", "deleting": "Видалення",
"pending": "Очікує", "pending": "Очікує",
"invite": "Запросити", "invite": "Запросити",
"view": "Подання" "view": "Подання",
"deactivated_user": "Деактивований користувач"
}, },
"chart": { "chart": {
"x_axis": "Вісь X", "x_axis": "Вісь X",

View file

@ -863,7 +863,8 @@
"deleting": "Đang xóa", "deleting": "Đang xóa",
"pending": "Đang chờ xử lý", "pending": "Đang chờ xử lý",
"invite": "Mời", "invite": "Mời",
"view": "Xem" "view": "Xem",
"deactivated_user": "Người dùng bị vô hiệu hóa"
}, },
"chart": { "chart": {
"x_axis": "Trục X", "x_axis": "Trục X",

View file

@ -870,7 +870,8 @@
"deleting": "删除中", "deleting": "删除中",
"pending": "待处理", "pending": "待处理",
"invite": "邀请", "invite": "邀请",
"view": "查看" "view": "查看",
"deactivated_user": "已停用用户"
}, },
"chart": { "chart": {

View file

@ -871,7 +871,8 @@
"deleting": "刪除中", "deleting": "刪除中",
"pending": "待處理", "pending": "待處理",
"invite": "邀請", "invite": "邀請",
"view": "檢視" "view": "檢視",
"deactivated_user": "已停用用戶"
}, },
"chart": { "chart": {

View file

@ -1,3 +1,6 @@
// plane imports
import { EInboxIssueSource } from "@plane/constants";
// local imports
import { import {
TIssueActivityWorkspaceDetail, TIssueActivityWorkspaceDetail,
TIssueActivityProjectDetail, TIssueActivityProjectDetail,
@ -31,7 +34,7 @@ export type TIssueActivity = {
epoch: number; epoch: number;
issue_comment: string | null; issue_comment: string | null;
source_data: { source_data: {
source: "IN_APP" | "FORM" | "EMAIL"; source: EInboxIssueSource;
source_email?: string; source_email?: string;
extra: { extra: {
username?: string; username?: string;

View file

@ -1,5 +1,6 @@
import { observer } from "mobx-react"; import { observer } from "mobx-react";
// plane imports // plane imports
import { useTranslation } from "@plane/i18n";
import { TDescriptionVersion } from "@plane/types"; import { TDescriptionVersion } from "@plane/types";
import { Avatar, CustomMenu } from "@plane/ui"; import { Avatar, CustomMenu } from "@plane/ui";
import { calculateTimeAgo, getFileURL } from "@plane/utils"; import { calculateTimeAgo, getFileURL } from "@plane/utils";
@ -17,11 +18,17 @@ export const DescriptionVersionsDropdownItem: React.FC<Props> = observer((props)
const { getUserDetails } = useMember(); const { getUserDetails } = useMember();
// derived values // derived values
const versionCreator = version.owned_by ? getUserDetails(version.owned_by) : null; const versionCreator = version.owned_by ? getUserDetails(version.owned_by) : null;
// translation
const { t } = useTranslation();
return ( return (
<CustomMenu.MenuItem key={version.id} className="flex items-center gap-1" onClick={() => onClick(version.id)}> <CustomMenu.MenuItem key={version.id} className="flex items-center gap-1" onClick={() => onClick(version.id)}>
<span className="flex-shrink-0"> <span className="flex-shrink-0">
<Avatar name={versionCreator?.display_name} size="sm" src={getFileURL(versionCreator?.avatar_url ?? "")} /> <Avatar
name={versionCreator?.display_name ?? t("common.deactivated_user")}
size="sm"
src={getFileURL(versionCreator?.avatar_url ?? "")}
/>
</span> </span>
<p className="text-xs text-custom-text-200 flex items-center gap-1.5"> <p className="text-xs text-custom-text-200 flex items-center gap-1.5">
<span className="font-medium">{versionCreator?.display_name}</span> <span className="font-medium">{versionCreator?.display_name}</span>

View file

@ -25,7 +25,9 @@ export const DescriptionVersionsDropdown: React.FC<Props> = observer((props) =>
// derived values // derived values
const latestVersion = versions?.[0]; const latestVersion = versions?.[0];
const lastUpdatedAt = latestVersion?.created_at ?? entityInformation.createdAt; const lastUpdatedAt = latestVersion?.created_at ?? entityInformation.createdAt;
const lastUpdatedByUserDetails = getUserDetails(latestVersion?.owned_by ?? entityInformation.createdBy); const lastUpdatedByUserDisplayName = latestVersion?.owned_by
? getUserDetails(latestVersion?.owned_by)?.display_name
: entityInformation.createdByDisplayName;
// translation // translation
const { t } = useTranslation(); const { t } = useTranslation();
@ -38,8 +40,7 @@ export const DescriptionVersionsDropdown: React.FC<Props> = observer((props) =>
</span> </span>
<p className="text-xs"> <p className="text-xs">
{t("description_versions.last_edited_by")}{" "} {t("description_versions.last_edited_by")}{" "}
<span className="font-medium">{lastUpdatedByUserDetails?.display_name}</span>{" "} <span className="font-medium">{lastUpdatedByUserDisplayName}</span> {calculateTimeAgo(lastUpdatedAt)}
{calculateTimeAgo(lastUpdatedAt)}
</p> </p>
</div> </div>
} }

View file

@ -175,7 +175,7 @@ export const DescriptionVersionsModal: React.FC<Props> = observer((props) => {
</button> </button>
</Tooltip> </Tooltip>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Button variant="neutral-primary" size="sm" onClick={handleClose}> <Button variant="neutral-primary" size="sm" onClick={handleClose} tabIndex={1}>
{t("common.cancel")} {t("common.cancel")}
</Button> </Button>
{!isRestoreDisabled && ( {!isRestoreDisabled && (

View file

@ -10,7 +10,7 @@ import { DescriptionVersionsModal } from "./modal";
export type TDescriptionVersionEntityInformation = { export type TDescriptionVersionEntityInformation = {
createdAt: Date; createdAt: Date;
createdBy: string; createdByDisplayName: string;
id: string; id: string;
isRestoreDisabled: boolean; isRestoreDisabled: boolean;
}; };

View file

@ -4,7 +4,7 @@ import { Dispatch, SetStateAction, useEffect, useMemo, useRef } from "react";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import { usePathname } from "next/navigation"; import { usePathname } from "next/navigation";
// plane imports // plane imports
import { ISSUE_ARCHIVED, ISSUE_DELETED } from "@plane/constants"; import { EInboxIssueSource, ISSUE_ARCHIVED, ISSUE_DELETED } from "@plane/constants";
import { EditorRefApi } from "@plane/editor"; import { EditorRefApi } from "@plane/editor";
import { TIssue, TNameDescriptionLoader } from "@plane/types"; import { TIssue, TNameDescriptionLoader } from "@plane/types";
import { Loader, TOAST_TYPE, setToast } from "@plane/ui"; import { Loader, TOAST_TYPE, setToast } from "@plane/ui";
@ -22,7 +22,7 @@ import {
// helpers // helpers
import { getTextContent } from "@/helpers/editor.helper"; import { getTextContent } from "@/helpers/editor.helper";
// hooks // hooks
import { useEventTracker, useIssueDetail, useProject, useProjectInbox, useUser } from "@/hooks/store"; import { useEventTracker, useIssueDetail, useMember, useProject, useProjectInbox, useUser } from "@/hooks/store";
import useReloadConfirmations from "@/hooks/use-reload-confirmation"; import useReloadConfirmations from "@/hooks/use-reload-confirmation";
// store types // store types
import { DeDupeIssuePopoverRoot } from "@/plane-web/components/de-dupe"; import { DeDupeIssuePopoverRoot } from "@/plane-web/components/de-dupe";
@ -51,6 +51,7 @@ export const InboxIssueMainContent: React.FC<Props> = observer((props) => {
const editorRef = useRef<EditorRefApi>(null); const editorRef = useRef<EditorRefApi>(null);
// store hooks // store hooks
const { data: currentUser } = useUser(); const { data: currentUser } = useUser();
const { getUserDetails } = useMember();
const { loader } = useProjectInbox(); const { loader } = useProjectInbox();
const { getProjectById } = useProject(); const { getProjectById } = useProject();
const { removeIssue, archiveIssue } = useIssueDetail(); const { removeIssue, archiveIssue } = useIssueDetail();
@ -232,7 +233,10 @@ export const InboxIssueMainContent: React.FC<Props> = observer((props) => {
className="flex-shrink-0" className="flex-shrink-0"
entityInformation={{ entityInformation={{
createdAt: new Date(issue.created_at ?? ""), createdAt: new Date(issue.created_at ?? ""),
createdBy: issue.created_by ?? "", createdByDisplayName:
inboxIssue.source === EInboxIssueSource.FORMS
? "Intake Form user"
: (getUserDetails(issue.created_by ?? "")?.display_name ?? ""),
id: issue.id, id: issue.id,
isRestoreDisabled: !isEditable, isRestoreDisabled: !isEditable,
}} }}

View file

@ -2,12 +2,13 @@
import { FC } from "react"; import { FC } from "react";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
// hooks // plane imports
import { EInboxIssueSource } from "@plane/constants";
import { LayersIcon } from "@plane/ui"; import { LayersIcon } from "@plane/ui";
// hooks
import { useIssueDetail } from "@/hooks/store"; import { useIssueDetail } from "@/hooks/store";
// components // local imports
import { IssueActivityBlockComponent } from "./"; import { IssueActivityBlockComponent } from "./";
// icons
type TIssueDefaultActivity = { activityId: string; ends: "top" | "bottom" | undefined }; type TIssueDefaultActivity = { activityId: string; ends: "top" | "bottom" | undefined };
@ -31,7 +32,7 @@ export const IssueDefaultActivity: FC<TIssueDefaultActivity> = observer((props)
> >
<> <>
{activity.verb === "created" ? ( {activity.verb === "created" ? (
source && source !== "IN_APP" ? ( source && source !== EInboxIssueSource.IN_APP ? (
<span> <span>
created the work item via <span className="font-medium">{source.toLowerCase()}</span>. created the work item via <span className="font-medium">{source.toLowerCase()}</span>.
</span> </span>

View file

@ -20,7 +20,7 @@ import {
// helpers // helpers
import { getTextContent } from "@/helpers/editor.helper"; import { getTextContent } from "@/helpers/editor.helper";
// hooks // hooks
import { useIssueDetail, useProject, useUser } from "@/hooks/store"; import { useIssueDetail, useMember, useProject, useUser } from "@/hooks/store";
import useReloadConfirmations from "@/hooks/use-reload-confirmation"; import useReloadConfirmations from "@/hooks/use-reload-confirmation";
import useSize from "@/hooks/use-window-size"; import useSize from "@/hooks/use-window-size";
// plane web components // plane web components
@ -52,6 +52,7 @@ export const IssueMainContent: React.FC<Props> = observer((props) => {
// hooks // hooks
const windowSize = useSize(); const windowSize = useSize();
const { data: currentUser } = useUser(); const { data: currentUser } = useUser();
const { getUserDetails } = useMember();
const { const {
issue: { getIssueById }, issue: { getIssueById },
peekIssue, peekIssue,
@ -154,7 +155,7 @@ export const IssueMainContent: React.FC<Props> = observer((props) => {
className="flex-shrink-0" className="flex-shrink-0"
entityInformation={{ entityInformation={{
createdAt: new Date(issue.created_at), createdAt: new Date(issue.created_at),
createdBy: issue.created_by, createdByDisplayName: getUserDetails(issue.created_by ?? "")?.display_name ?? "",
id: issueId, id: issueId,
isRestoreDisabled: !isEditable || isArchived, isRestoreDisabled: !isEditable || isArchived,
}} }}

View file

@ -10,7 +10,7 @@ import { IssueParentDetail, TIssueOperations } from "@/components/issues";
// helpers // helpers
import { getTextContent } from "@/helpers/editor.helper"; import { getTextContent } from "@/helpers/editor.helper";
// hooks // hooks
import { useIssueDetail, useProject, useUser } from "@/hooks/store"; import { useIssueDetail, useMember, useProject, useUser } from "@/hooks/store";
import useReloadConfirmations from "@/hooks/use-reload-confirmation"; import useReloadConfirmations from "@/hooks/use-reload-confirmation";
// plane web components // plane web components
import { DeDupeIssuePopoverRoot } from "@/plane-web/components/de-dupe"; import { DeDupeIssuePopoverRoot } from "@/plane-web/components/de-dupe";
@ -47,7 +47,8 @@ export const PeekOverviewIssueDetails: FC<IPeekOverviewIssueDetails> = observer(
issue: { getIssueById }, issue: { getIssueById },
} = useIssueDetail(); } = useIssueDetail();
const { getProjectById } = useProject(); const { getProjectById } = useProject();
// hooks const { getUserDetails } = useMember();
// reload confirmation
const { setShowAlert } = useReloadConfirmations(isSubmitting === "submitting"); const { setShowAlert } = useReloadConfirmations(isSubmitting === "submitting");
useEffect(() => { useEffect(() => {
@ -147,7 +148,7 @@ export const PeekOverviewIssueDetails: FC<IPeekOverviewIssueDetails> = observer(
className="flex-shrink-0" className="flex-shrink-0"
entityInformation={{ entityInformation={{
createdAt: new Date(issue.created_at), createdAt: new Date(issue.created_at),
createdBy: issue.created_by, createdByDisplayName: getUserDetails(issue.created_by ?? "")?.display_name ?? "",
id: issueId, id: issueId,
isRestoreDisabled: disabled || isArchived, isRestoreDisabled: disabled || isArchived,
}} }}

View file

@ -1,9 +1,10 @@
// types // plane imports
import { TInboxIssue } from "@plane/constants"; import { EInboxIssueSource, TInboxIssue } from "@plane/constants";
import type { TIssue, TInboxIssueWithPagination } from "@plane/types"; import type { TIssue, TInboxIssueWithPagination } from "@plane/types";
import { API_BASE_URL } from "@/helpers/common.helper";
import { APIService } from "@/services/api.service";
// helpers // helpers
import { API_BASE_URL } from "@/helpers/common.helper";
// services
import { APIService } from "@/services/api.service";
export class InboxIssueService extends APIService { export class InboxIssueService extends APIService {
constructor() { constructor() {
@ -32,7 +33,7 @@ export class InboxIssueService extends APIService {
async create(workspaceSlug: string, projectId: string, data: Partial<TIssue>): Promise<TInboxIssue> { async create(workspaceSlug: string, projectId: string, data: Partial<TIssue>): Promise<TInboxIssue> {
return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/inbox-issues/`, { return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/inbox-issues/`, {
source: "IN_APP", source: EInboxIssueSource.IN_APP,
issue: data, issue: data,
}) })
.then((response) => response?.data) .then((response) => response?.data)

View file

@ -1,7 +1,7 @@
import clone from "lodash/clone"; import clone from "lodash/clone";
import set from "lodash/set"; import set from "lodash/set";
import { makeObservable, observable, runInAction, action } from "mobx"; import { makeObservable, observable, runInAction, action } from "mobx";
import { TInboxIssue, TInboxIssueStatus } from "@plane/constants"; import { TInboxIssue, TInboxIssueStatus, EInboxIssueSource } from "@plane/constants";
import { TIssue, TInboxDuplicateIssueDetails } from "@plane/types"; import { TIssue, TInboxDuplicateIssueDetails } from "@plane/types";
// helpers // helpers
import { EInboxIssueStatus } from "@/helpers/inbox.helper"; import { EInboxIssueStatus } from "@/helpers/inbox.helper";
@ -19,6 +19,7 @@ export interface IInboxIssueStore {
status: TInboxIssueStatus; status: TInboxIssueStatus;
issue: Partial<TIssue>; issue: Partial<TIssue>;
snoozed_till: Date | undefined; snoozed_till: Date | undefined;
source: EInboxIssueSource | undefined;
duplicate_to: string | undefined; duplicate_to: string | undefined;
created_by: string | undefined; created_by: string | undefined;
duplicate_issue_detail: TInboxDuplicateIssueDetails | undefined; duplicate_issue_detail: TInboxDuplicateIssueDetails | undefined;
@ -38,6 +39,7 @@ export class InboxIssueStore implements IInboxIssueStore {
status: TInboxIssueStatus = EInboxIssueStatus.PENDING; status: TInboxIssueStatus = EInboxIssueStatus.PENDING;
issue: Partial<TIssue> = {}; issue: Partial<TIssue> = {};
snoozed_till: Date | undefined; snoozed_till: Date | undefined;
source: EInboxIssueSource | undefined;
duplicate_to: string | undefined; duplicate_to: string | undefined;
created_by: string | undefined; created_by: string | undefined;
duplicate_issue_detail: TInboxDuplicateIssueDetails | undefined = undefined; duplicate_issue_detail: TInboxDuplicateIssueDetails | undefined = undefined;
@ -59,6 +61,7 @@ export class InboxIssueStore implements IInboxIssueStore {
this.snoozed_till = data?.snoozed_till || undefined; this.snoozed_till = data?.snoozed_till || undefined;
this.duplicate_to = data?.duplicate_to || undefined; this.duplicate_to = data?.duplicate_to || undefined;
this.created_by = data?.created_by || undefined; this.created_by = data?.created_by || undefined;
this.source = data?.source || undefined;
this.duplicate_issue_detail = data?.duplicate_issue_detail || undefined; this.duplicate_issue_detail = data?.duplicate_issue_detail || undefined;
this.workspaceSlug = workspaceSlug; this.workspaceSlug = workspaceSlug;
this.projectId = projectId; this.projectId = projectId;
@ -74,6 +77,7 @@ export class InboxIssueStore implements IInboxIssueStore {
duplicate_to: observable, duplicate_to: observable,
duplicate_issue_detail: observable, duplicate_issue_detail: observable,
created_by: observable, created_by: observable,
source: observable,
// actions // actions
updateInboxIssueStatus: action, updateInboxIssueStatus: action,
updateInboxIssueDuplicateTo: action, updateInboxIssueDuplicateTo: action,