NODEDC_TASKMANAGER/plane-src/apps/web/ce/components/projects/external-contours/root.tsx

114 lines
4.1 KiB
TypeScript

/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useEffect } from "react";
import { observer } from "mobx-react";
import { TransferIcon } from "@plane/propel/icons";
import type { TInboxIssueCurrentTab } from "@plane/types";
import { EInboxIssueCurrentTab } from "@plane/types";
import { FiltersRow } from "@/components/rich-filters/filters-row";
import { useExternalContoursRealtimeEvents } from "@/hooks/use-external-contours-realtime-events";
import { useProjectExternalContoursBoard } from "@/hooks/store/use-project-external-contours-board";
import { useProjectExternalContours } from "@/hooks/store/use-project-external-contours";
import { ExternalContoursBoardRoot } from "./board-root";
import { ExternalContoursContentRoot } from "./content-root";
import { useExternalContoursFilter } from "./filters/provider";
type TExternalContoursRoot = {
workspaceSlug: string;
projectId: string;
inboxIssueId: string | undefined;
navigationTab?: TInboxIssueCurrentTab | undefined;
};
export const ExternalContoursRoot = observer(function ExternalContoursRoot(props: TExternalContoursRoot) {
const { workspaceSlug, projectId, inboxIssueId, navigationTab } = props;
const { loader, error, currentTab, currentProjectId, requestIds, handleCurrentTab, fetchRequests } =
useProjectExternalContours();
const {
error: boardError,
currentProjectId: boardProjectId,
fetchBoard,
loader: boardLoader,
syncBoard,
} = useProjectExternalContoursBoard();
const filter = useExternalContoursFilter();
useExternalContoursRealtimeEvents(workspaceSlug?.toString(), projectId?.toString(), syncBoard);
useEffect(() => {
if (!workspaceSlug || !projectId) return;
const resolvedTab = navigationTab || EInboxIssueCurrentTab.OPEN;
const hasProjectChanged = currentProjectId && currentProjectId !== projectId;
if (hasProjectChanged) {
void handleCurrentTab(workspaceSlug, projectId, EInboxIssueCurrentTab.OPEN);
return;
}
if (currentProjectId === projectId && currentTab === resolvedTab) {
if (loader === "init-loading") return;
if (requestIds.length > 0) return;
}
if (currentTab !== resolvedTab) {
void handleCurrentTab(workspaceSlug, projectId, resolvedTab);
return;
}
void fetchRequests(workspaceSlug.toString(), projectId.toString(), resolvedTab);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [workspaceSlug, projectId, navigationTab]);
useEffect(() => {
if (!workspaceSlug || !projectId) return;
if (boardProjectId === projectId && boardLoader === "init-loading") return;
void fetchBoard(workspaceSlug.toString(), projectId.toString());
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [workspaceSlug, projectId]);
if (error && error?.status === "init-error" && !!inboxIssueId) {
return (
<div className="relative flex h-full w-full flex-col items-center justify-center gap-3">
<TransferIcon className="size-[60px]" strokeWidth={1.5} />
<div className="text-secondary">{error?.message}</div>
</div>
);
}
if (boardError && boardError?.status === "init-error" && !inboxIssueId) {
return (
<div className="relative flex h-full w-full flex-col items-center justify-center gap-3">
<TransferIcon className="size-[60px]" strokeWidth={1.5} />
<div className="text-secondary">{boardError?.message}</div>
</div>
);
}
return (
<div className="flex h-full w-full flex-col overflow-hidden bg-surface-1">
{filter && (
<div className="w-full shrink-0 px-4 py-4">
<FiltersRow filter={filter} />
</div>
)}
<div className="flex min-h-0 flex-1 overflow-hidden">
<ExternalContoursBoardRoot workspaceSlug={workspaceSlug.toString()} projectId={projectId.toString()} />
{inboxIssueId && (
<ExternalContoursContentRoot
workspaceSlug={workspaceSlug.toString()}
projectId={projectId.toString()}
inboxIssueId={inboxIssueId.toString()}
/>
)}
</div>
</div>
);
});