ФУНКЦИИ - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: отказ от open-closed табов и стабилизация фильтров внешних контуров
This commit is contained in:
parent
c6645bb4fc
commit
91906e917e
|
|
@ -6,20 +6,19 @@
|
|||
|
||||
import { observer } from "mobx-react";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import type { TExternalContourBoardDirection, TInboxIssueCurrentTab } from "@plane/types";
|
||||
import type { TExternalContourBoardDirection } from "@plane/types";
|
||||
import { useProjectExternalContoursBoard } from "@/hooks/store/use-project-external-contours-board";
|
||||
import { ExternalContoursBoardItem } from "./board-item";
|
||||
import { ExternalContoursEmptyState } from "./empty-state";
|
||||
|
||||
type Props = {
|
||||
currentTab: TInboxIssueCurrentTab;
|
||||
direction: TExternalContourBoardDirection;
|
||||
projectId: string;
|
||||
workspaceSlug: string;
|
||||
};
|
||||
|
||||
export const ExternalContoursBoardColumn = observer(function ExternalContoursBoardColumn(props: Props) {
|
||||
const { currentTab, direction, projectId, workspaceSlug } = props;
|
||||
const { direction, projectId, workspaceSlug } = props;
|
||||
const { t } = useTranslation();
|
||||
const { getColumnRequestIds, getColumnTotalCount, getRequestById } = useProjectExternalContoursBoard();
|
||||
const requestIds = getColumnRequestIds(direction);
|
||||
|
|
@ -57,7 +56,6 @@ export const ExternalContoursBoardColumn = observer(function ExternalContoursBoa
|
|||
return (
|
||||
<ExternalContoursBoardItem
|
||||
key={requestId}
|
||||
currentTab={currentTab}
|
||||
direction={direction}
|
||||
projectId={projectId}
|
||||
request={request}
|
||||
|
|
|
|||
|
|
@ -431,14 +431,7 @@ const buildOptionsWithSelectedFallback = (
|
|||
};
|
||||
|
||||
visibleRequests.forEach(upsertOption);
|
||||
|
||||
if (selectedIds.length > 0) {
|
||||
cachedRequests.forEach((request) => {
|
||||
const option = getOption(request);
|
||||
if (!option?.id || !selectedIds.includes(option.id) || optionMap.has(option.id)) return;
|
||||
optionMap.set(option.id, option);
|
||||
});
|
||||
}
|
||||
cachedRequests.forEach(upsertOption);
|
||||
|
||||
return sortFilterOptions(Array.from(optionMap.values())).map((option) => ({
|
||||
data: option,
|
||||
|
|
@ -526,19 +519,7 @@ const getAssigneeOptions = (
|
|||
};
|
||||
|
||||
visibleRequests.forEach(upsertAssignees);
|
||||
|
||||
if (selectedIds.length > 0) {
|
||||
cachedRequests.forEach((request) => {
|
||||
request.issue.assignee_details?.forEach((assignee) => {
|
||||
if (!assignee?.id || !selectedIds.includes(assignee.id) || assigneeMap.has(assignee.id)) return;
|
||||
assigneeMap.set(assignee.id, {
|
||||
id: assignee.id,
|
||||
label: assignee.display_name || "NODE.DC",
|
||||
avatarUrl: assignee.avatar_url || "",
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
cachedRequests.forEach(upsertAssignees);
|
||||
|
||||
return sortFilterOptions(Array.from(assigneeMap.values())).map((option) => ({ data: option, value: option.id }));
|
||||
};
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ import type {
|
|||
IState,
|
||||
TExternalContourBoardDirection,
|
||||
TExternalContourRequest,
|
||||
TInboxIssueCurrentTab,
|
||||
TIssue,
|
||||
} from "@plane/types";
|
||||
import { Avatar } from "@plane/ui";
|
||||
|
|
@ -37,7 +36,6 @@ import { useUserPermissions } from "@/hooks/store/user";
|
|||
import { IssueService } from "@/services/issue/issue.service";
|
||||
|
||||
type Props = {
|
||||
currentTab: TInboxIssueCurrentTab;
|
||||
direction: TExternalContourBoardDirection;
|
||||
projectId: string;
|
||||
request: TExternalContourRequest;
|
||||
|
|
@ -78,7 +76,7 @@ const resolveRequestStatus = (issue: TExternalContourRequest["issue"], fallbackS
|
|||
};
|
||||
|
||||
export const ExternalContoursBoardItem = observer(function ExternalContoursBoardItem(props: Props) {
|
||||
const { currentTab, direction, projectId, request, workspaceSlug } = props;
|
||||
const { direction, projectId, request, workspaceSlug } = props;
|
||||
const router = useAppRouter();
|
||||
const searchParams = useSearchParams();
|
||||
const { t } = useTranslation();
|
||||
|
|
@ -86,7 +84,6 @@ export const ExternalContoursBoardItem = observer(function ExternalContoursBoard
|
|||
const { getProjectRoleByWorkspaceSlugAndProjectId } = useUserPermissions();
|
||||
const { getStateById, getProjectStateIds } = useProjectState();
|
||||
const {
|
||||
currentTab: boardCurrentTab,
|
||||
fetchBoard,
|
||||
upsertBoardItems,
|
||||
} = useProjectExternalContoursBoard();
|
||||
|
|
@ -116,7 +113,7 @@ export const ExternalContoursBoardItem = observer(function ExternalContoursBoard
|
|||
direction === "incoming" && !!targetProjectId && projectRole !== undefined && projectRole !== EUserPermissions.GUEST;
|
||||
const canEditSourceRequest = direction === "outgoing" && !!request.capabilities?.can_edit_request && !!targetProjectId;
|
||||
const canEditCard = canEditTargetIssue || canEditSourceRequest;
|
||||
const requestLink = `/${workspaceSlug}/projects/${projectId}/external-contours?currentTab=${currentTab}&inboxIssueId=${request.id}`;
|
||||
const requestLink = `/${workspaceSlug}/projects/${projectId}/external-contours?inboxIssueId=${request.id}`;
|
||||
const targetOptions = getTargetOptionsByProjectId(targetProjectId);
|
||||
const sourceStateMap = useMemo(
|
||||
() => buildSourceStateMap(targetOptions?.states, targetProjectId),
|
||||
|
|
@ -145,7 +142,7 @@ export const ExternalContoursBoardItem = observer(function ExternalContoursBoard
|
|||
};
|
||||
|
||||
const syncBoardAfterMutation = async () => {
|
||||
await fetchBoard(workspaceSlug, projectId, boardCurrentTab ?? currentTab);
|
||||
await fetchBoard(workspaceSlug, projectId);
|
||||
};
|
||||
|
||||
const ensureSourceOptions = async () => {
|
||||
|
|
|
|||
|
|
@ -6,11 +6,8 @@
|
|||
|
||||
import { observer } from "mobx-react";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import type { TInboxIssueCurrentTab } from "@plane/types";
|
||||
import { EInboxIssueCurrentTab } from "@plane/types";
|
||||
import { cn } from "@plane/utils";
|
||||
import { useProjectExternalContoursBoard } from "@/hooks/store/use-project-external-contours-board";
|
||||
import { useAppRouter } from "@/hooks/use-app-router";
|
||||
import { ExternalContoursBoardFiltersRow } from "./board-filters-row";
|
||||
import { ExternalContoursBoardColumn } from "./board-column";
|
||||
|
||||
|
|
@ -19,51 +16,14 @@ type Props = {
|
|||
workspaceSlug: string;
|
||||
};
|
||||
|
||||
const tabNavigationOptions: { key: TInboxIssueCurrentTab; i18nLabel: string }[] = [
|
||||
{ key: EInboxIssueCurrentTab.OPEN, i18nLabel: "external_contours_page.tabs.open" },
|
||||
{ key: EInboxIssueCurrentTab.CLOSED, i18nLabel: "external_contours_page.tabs.closed" },
|
||||
];
|
||||
|
||||
export const ExternalContoursBoardRoot = observer(function ExternalContoursBoardRoot(props: Props) {
|
||||
const { projectId, workspaceSlug } = props;
|
||||
const { t } = useTranslation();
|
||||
const router = useAppRouter();
|
||||
const { currentTab, hasAnyItems, isFiltering, loader, tabCountMap, handleCurrentTab } = useProjectExternalContoursBoard();
|
||||
const { hasAnyItems, isFiltering, loader } = useProjectExternalContoursBoard();
|
||||
|
||||
return (
|
||||
<div className="flex h-full min-h-0 flex-col overflow-hidden px-8 pb-6">
|
||||
<div className="flex shrink-0 items-center gap-2 py-4">
|
||||
<div className="nodedc-filter-row-shell flex items-center gap-2 p-1">
|
||||
{tabNavigationOptions.map((option) => {
|
||||
const count = tabCountMap[option.key] ?? 0;
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
key={option.key}
|
||||
data-active={currentTab === option.key}
|
||||
className={cn("nodedc-external-tab flex min-w-[10rem] items-center justify-center gap-2 text-13 font-medium transition-all")}
|
||||
onClick={() => {
|
||||
if (currentTab === option.key) return;
|
||||
void handleCurrentTab(workspaceSlug, projectId, option.key);
|
||||
router.push(`/${workspaceSlug}/projects/${projectId}/external-contours?currentTab=${option.key}`);
|
||||
}}
|
||||
>
|
||||
<div>{t(option.i18nLabel)}</div>
|
||||
<div
|
||||
className={cn(
|
||||
"rounded-full px-1.5 py-0.5 text-11 font-semibold",
|
||||
currentTab === option.key ? "bg-accent-primary/15 text-accent-primary" : "bg-white/5 text-secondary"
|
||||
)}
|
||||
>
|
||||
{count}
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="shrink-0 pb-4">
|
||||
<div className="shrink-0 py-4">
|
||||
<ExternalContoursBoardFiltersRow workspaceSlug={workspaceSlug} projectId={projectId} />
|
||||
</div>
|
||||
|
||||
|
|
@ -84,13 +44,11 @@ export const ExternalContoursBoardRoot = observer(function ExternalContoursBoard
|
|||
)}
|
||||
>
|
||||
<ExternalContoursBoardColumn
|
||||
currentTab={currentTab}
|
||||
direction="outgoing"
|
||||
projectId={projectId}
|
||||
workspaceSlug={workspaceSlug}
|
||||
/>
|
||||
<ExternalContoursBoardColumn
|
||||
currentTab={currentTab}
|
||||
direction="incoming"
|
||||
projectId={projectId}
|
||||
workspaceSlug={workspaceSlug}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ export const ExternalContoursContentRoot = observer(function ExternalContoursCon
|
|||
const [isSubmitting, setIsSubmitting] = useState<TNameDescriptionLoader>("saved");
|
||||
const [isDetailResolved, setIsDetailResolved] = useState(false);
|
||||
const { data: currentUser } = useUser();
|
||||
const { currentTab, fetchRequestById, getRequestById } = useProjectExternalContours();
|
||||
const { fetchRequestById, getRequestById } = useProjectExternalContours();
|
||||
const contourRequest = getRequestById(inboxIssueId);
|
||||
const issue = contourRequest?.issue;
|
||||
const targetProjectId = issue?.project_id || projectId;
|
||||
|
|
@ -46,10 +46,10 @@ export const ExternalContoursContentRoot = observer(function ExternalContoursCon
|
|||
|
||||
useEffect(() => {
|
||||
if (isDetailResolved && !contourRequest && inboxIssueId) {
|
||||
router.replace(`/${workspaceSlug}/projects/${projectId}/external-contours?currentTab=${currentTab}`);
|
||||
router.replace(`/${workspaceSlug}/projects/${projectId}/external-contours`);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [contourRequest, currentTab, inboxIssueId, isDetailResolved, projectId, router, workspaceSlug]);
|
||||
}, [contourRequest, inboxIssueId, isDetailResolved, projectId, router, workspaceSlug]);
|
||||
|
||||
useSWR(
|
||||
workspaceSlug && projectId && inboxIssueId
|
||||
|
|
@ -96,7 +96,7 @@ export const ExternalContoursContentRoot = observer(function ExternalContoursCon
|
|||
isSubmitting={isSubmitting}
|
||||
embedIssue={embedIssue}
|
||||
embedRemoveCurrentNotification={embedRemoveCurrentNotification}
|
||||
onClose={() => router.replace(`/${workspaceSlug}/projects/${projectId}/external-contours?currentTab=${currentTab}`)}
|
||||
onClose={() => router.replace(`/${workspaceSlug}/projects/${projectId}/external-contours`)}
|
||||
>
|
||||
<ExternalContoursIssueMainContent
|
||||
workspaceSlug={workspaceSlug}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import { useTranslation } from "@plane/i18n";
|
|||
import { Button } from "@plane/propel/button";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
import type { TIssue } from "@plane/types";
|
||||
import { EInboxIssueCurrentTab } from "@plane/types";
|
||||
import { ToggleSwitch } from "@plane/ui";
|
||||
import { useProject } from "@/hooks/store/use-project";
|
||||
import { useProjectExternalContours } from "@/hooks/store/use-project-external-contours";
|
||||
|
|
@ -110,7 +109,7 @@ export const ExternalContoursCreateRoot = observer(function ExternalContoursCrea
|
|||
}
|
||||
|
||||
if (createdRequest?.id) {
|
||||
router.push(`/${workspaceSlug}/projects/${projectId}/external-contours?currentTab=${EInboxIssueCurrentTab.OPEN}&inboxIssueId=${createdRequest.id}`);
|
||||
router.push(`/${workspaceSlug}/projects/${projectId}/external-contours?inboxIssueId=${createdRequest.id}`);
|
||||
}
|
||||
} catch (error: any) {
|
||||
setToast({
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import {
|
|||
} from "@plane/propel/icons";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
import type { TExternalContourRequest, TNameDescriptionLoader } from "@plane/types";
|
||||
import { EInboxIssueCurrentTab } from "@plane/types";
|
||||
import { ControlLink, CustomSelect, Header, Row, Tooltip } from "@plane/ui";
|
||||
import { copyUrlToClipboard, generateWorkItemLink } from "@plane/utils";
|
||||
import { NameDescriptionUpdateStatus } from "@/components/issues/issue-update-status";
|
||||
|
|
@ -68,7 +67,6 @@ type Props = {
|
|||
removeRoutePeekId: () => void;
|
||||
peekMode: TExternalContourPeekMode;
|
||||
setPeekMode: (value: TExternalContourPeekMode) => void;
|
||||
currentTab: TInboxIssueCurrentTab;
|
||||
embedIssue?: boolean;
|
||||
};
|
||||
|
||||
|
|
@ -82,20 +80,18 @@ export const ExternalContoursIssueActionsHeader = observer(function ExternalCont
|
|||
removeRoutePeekId,
|
||||
peekMode,
|
||||
setPeekMode,
|
||||
currentTab,
|
||||
embedIssue = false,
|
||||
} = props;
|
||||
const { t } = useTranslation();
|
||||
const router = useAppRouter();
|
||||
const [isDeclineModalOpen, setIsDeclineModalOpen] = useState(false);
|
||||
const { decideRequest, filteredRequestIds, handleCurrentTab, loader } = useProjectExternalContours();
|
||||
const { currentTab: boardCurrentTab, columnIdsMap } = useProjectExternalContoursBoard();
|
||||
const { decideRequest, filteredRequestIds, loader } = useProjectExternalContours();
|
||||
const { columnIdsMap } = useProjectExternalContoursBoard();
|
||||
const { getProjectById } = useProject();
|
||||
|
||||
const issue = contourRequest.issue;
|
||||
const currentRequestId = contourRequest.id;
|
||||
const boardRequestIds =
|
||||
boardCurrentTab === currentTab ? [...(columnIdsMap.outgoing ?? []), ...(columnIdsMap.incoming ?? [])] : [];
|
||||
const boardRequestIds = [...(columnIdsMap.outgoing ?? []), ...(columnIdsMap.incoming ?? [])];
|
||||
const relativeRequestIds = boardRequestIds.includes(currentRequestId) ? boardRequestIds : filteredRequestIds;
|
||||
const currentMode = PEEK_OPTIONS.find((mode) => mode.key === peekMode);
|
||||
const hasRelativeNavigation = !!currentRequestId && relativeRequestIds.includes(currentRequestId);
|
||||
|
|
@ -115,9 +111,9 @@ export const ExternalContoursIssueActionsHeader = observer(function ExternalCont
|
|||
: (currentIssueIndex - 1 + relativeRequestIds.length) % relativeRequestIds.length;
|
||||
const nextIssueId = relativeRequestIds[nextIssueIndex];
|
||||
if (!nextIssueId) return;
|
||||
router.push(`/${workspaceSlug}/projects/${sourceProjectId}/external-contours?currentTab=${currentTab}&inboxIssueId=${nextIssueId}`);
|
||||
router.push(`/${workspaceSlug}/projects/${sourceProjectId}/external-contours?inboxIssueId=${nextIssueId}`);
|
||||
},
|
||||
[currentRequestId, currentTab, hasRelativeNavigation, relativeRequestIds, router, sourceProjectId, workspaceSlug]
|
||||
[currentRequestId, hasRelativeNavigation, relativeRequestIds, router, sourceProjectId, workspaceSlug]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -131,8 +127,7 @@ export const ExternalContoursIssueActionsHeader = observer(function ExternalCont
|
|||
}, [redirectToRelativeIssue]);
|
||||
|
||||
const targetProjectIdentifier = issue.project_detail?.identifier || getProjectById(issue.project_id || "")?.identifier;
|
||||
const requestTab = contourRequest.status === "closed" ? EInboxIssueCurrentTab.CLOSED : EInboxIssueCurrentTab.OPEN;
|
||||
const requestLink = `/${workspaceSlug}/projects/${sourceProjectId}/external-contours?currentTab=${requestTab}&inboxIssueId=${contourRequest.id}`;
|
||||
const requestLink = `/${workspaceSlug}/projects/${sourceProjectId}/external-contours?inboxIssueId=${contourRequest.id}`;
|
||||
const workItemLink = generateWorkItemLink({
|
||||
workspaceSlug: workspaceSlug?.toString(),
|
||||
projectId: issue.project_id,
|
||||
|
|
@ -183,10 +178,7 @@ export const ExternalContoursIssueActionsHeader = observer(function ExternalCont
|
|||
await decideRequest(workspaceSlug, sourceProjectId, contourRequest.id, action, comment);
|
||||
if (action === "decline") {
|
||||
setIsDeclineModalOpen(false);
|
||||
await handleCurrentTab(workspaceSlug, sourceProjectId, EInboxIssueCurrentTab.OPEN);
|
||||
router.push(
|
||||
`/${workspaceSlug}/projects/${sourceProjectId}/external-contours?currentTab=${EInboxIssueCurrentTab.OPEN}&inboxIssueId=${contourRequest.id}`
|
||||
);
|
||||
router.push(`/${workspaceSlug}/projects/${sourceProjectId}/external-contours?inboxIssueId=${contourRequest.id}`);
|
||||
}
|
||||
setToast({
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import { useCallback, useEffect, useRef, useState, type MouseEvent as ReactMouse
|
|||
import { observer } from "mobx-react";
|
||||
import { cn } from "@plane/utils";
|
||||
import type { TExternalContourRequest, TNameDescriptionLoader } from "@plane/types";
|
||||
import { useProjectExternalContours } from "@/hooks/store/use-project-external-contours";
|
||||
import useKeypress from "@/hooks/use-keypress";
|
||||
import usePeekOverviewOutsideClickDetector from "@/hooks/use-peek-overview-outside-click";
|
||||
import { ExternalContoursIssueActionsHeader, type TExternalContourPeekMode } from "./issue-header";
|
||||
|
|
@ -55,7 +54,6 @@ export const ExternalContoursPeekShell = observer(function ExternalContoursPeekS
|
|||
const issuePeekOverviewRef = useRef<HTMLDivElement>(null);
|
||||
const initialPeekWidthRef = useRef<number>(0);
|
||||
const initialMouseXRef = useRef<number>(0);
|
||||
const { currentTab } = useProjectExternalContours();
|
||||
|
||||
const removeRoutePeekId = useCallback(() => {
|
||||
if (embedIssue) {
|
||||
|
|
@ -190,7 +188,6 @@ export const ExternalContoursPeekShell = observer(function ExternalContoursPeekS
|
|||
removeRoutePeekId={removeRoutePeekId}
|
||||
peekMode={peekMode}
|
||||
setPeekMode={setPeekMode}
|
||||
currentTab={currentTab}
|
||||
embedIssue={embedIssue}
|
||||
/>
|
||||
<div className="vertical-scrollbar relative scrollbar-md h-full w-full overflow-hidden overflow-y-auto">
|
||||
|
|
|
|||
|
|
@ -28,9 +28,7 @@ export const ExternalContoursRoot = observer(function ExternalContoursRoot(props
|
|||
const {
|
||||
error: boardError,
|
||||
currentProjectId: boardProjectId,
|
||||
currentTab: boardCurrentTab,
|
||||
fetchBoard,
|
||||
handleCurrentTab: handleBoardCurrentTab,
|
||||
loader: boardLoader,
|
||||
} = useProjectExternalContoursBoard();
|
||||
|
||||
|
|
@ -61,20 +59,11 @@ export const ExternalContoursRoot = observer(function ExternalContoursRoot(props
|
|||
|
||||
useEffect(() => {
|
||||
if (!workspaceSlug || !projectId) return;
|
||||
if (boardProjectId === projectId && boardLoader === "init-loading") return;
|
||||
|
||||
const resolvedTab = navigationTab || EInboxIssueCurrentTab.OPEN;
|
||||
const hasProjectChanged = boardProjectId && boardProjectId !== projectId;
|
||||
|
||||
if (boardProjectId === projectId && boardCurrentTab === resolvedTab && boardLoader === "init-loading") return;
|
||||
|
||||
if (hasProjectChanged || boardCurrentTab !== resolvedTab) {
|
||||
void handleBoardCurrentTab(workspaceSlug, projectId, resolvedTab);
|
||||
return;
|
||||
}
|
||||
|
||||
void fetchBoard(workspaceSlug.toString(), projectId.toString(), resolvedTab);
|
||||
void fetchBoard(workspaceSlug.toString(), projectId.toString());
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [workspaceSlug, projectId, navigationTab]);
|
||||
}, [workspaceSlug, projectId]);
|
||||
|
||||
if (error && error?.status === "init-error" && !!inboxIssueId) {
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ export class ProjectExternalContoursBoardStore implements IProjectExternalContou
|
|||
currentProjectId = "";
|
||||
currentTab: TInboxIssueCurrentTab = EInboxIssueCurrentTab.OPEN;
|
||||
error: { message: string; status: "init-error" } | undefined = undefined;
|
||||
filters: Partial<TExternalContourBoardFilter> = { status: [EInboxIssueCurrentTab.OPEN] };
|
||||
filters: Partial<TExternalContourBoardFilter> = {};
|
||||
items: Record<string, TExternalContourRequest> = {};
|
||||
loader: TLoader = "init-loading";
|
||||
sorting: TExternalContourBoardSorting = DEFAULT_SORTING;
|
||||
|
|
@ -145,10 +145,6 @@ export class ProjectExternalContoursBoardStore implements IProjectExternalContou
|
|||
|
||||
handleCurrentTab = async (workspaceSlug: string, projectId: string, tab: TInboxIssueCurrentTab) => {
|
||||
this.currentTab = tab;
|
||||
this.filters = sanitizeBoardFilters({
|
||||
...this.filters,
|
||||
status: [tab],
|
||||
});
|
||||
await this.fetchBoard(workspaceSlug, projectId, tab);
|
||||
};
|
||||
|
||||
|
|
@ -160,30 +156,26 @@ export class ProjectExternalContoursBoardStore implements IProjectExternalContou
|
|||
this.filters = sanitizeBoardFilters({
|
||||
...this.filters,
|
||||
...filters,
|
||||
status: [this.currentTab],
|
||||
});
|
||||
|
||||
await this.fetchBoard(workspaceSlug, projectId, this.currentTab);
|
||||
await this.fetchBoard(workspaceSlug, projectId);
|
||||
};
|
||||
|
||||
updateSorting = async (workspaceSlug: string, projectId: string, sorting: TExternalContourBoardSorting) => {
|
||||
this.sorting = sorting;
|
||||
await this.fetchBoard(workspaceSlug, projectId, this.currentTab);
|
||||
await this.fetchBoard(workspaceSlug, projectId);
|
||||
};
|
||||
|
||||
clearFilters = async (workspaceSlug: string, projectId: string) => {
|
||||
this.filters = { status: [this.currentTab] };
|
||||
this.filters = {};
|
||||
this.sorting = DEFAULT_SORTING;
|
||||
await this.fetchBoard(workspaceSlug, projectId, this.currentTab);
|
||||
await this.fetchBoard(workspaceSlug, projectId);
|
||||
};
|
||||
|
||||
fetchBoard = async (workspaceSlug: string, projectId: string, tab = this.currentTab) => {
|
||||
const hasProjectChanged = !!this.currentProjectId && this.currentProjectId !== projectId;
|
||||
const isInitialLoad = this.hydratedProjectId !== projectId;
|
||||
const nextFilters = sanitizeBoardFilters({
|
||||
...(hasProjectChanged ? {} : this.filters),
|
||||
status: [tab],
|
||||
});
|
||||
const nextFilters = sanitizeBoardFilters(hasProjectChanged ? {} : this.filters);
|
||||
const nextSorting = hasProjectChanged ? DEFAULT_SORTING : this.sorting;
|
||||
const requestId = ++this.lastIssuedRequestId;
|
||||
|
||||
|
|
@ -213,16 +205,22 @@ export class ProjectExternalContoursBoardStore implements IProjectExternalContou
|
|||
this.filters = sanitizeBoardFilters(response.filters || nextFilters);
|
||||
this.sorting = response.sorting || nextSorting;
|
||||
this.hydratedProjectId = projectId;
|
||||
let openCount = 0;
|
||||
let closedCount = 0;
|
||||
|
||||
response.columns.forEach((column) => {
|
||||
this.columnIdsMap[column.key] = column.results.map((request) => request.id);
|
||||
this.columnCountMap[column.key] = column.total_count;
|
||||
column.results.forEach((request) => {
|
||||
if (request.status === EInboxIssueCurrentTab.CLOSED) closedCount += 1;
|
||||
else openCount += 1;
|
||||
});
|
||||
this.upsertBoardItems(column.results);
|
||||
});
|
||||
|
||||
this.tabCountMap = {
|
||||
...this.tabCountMap,
|
||||
[tab]: response.columns.reduce((total, column) => total + column.total_count, 0),
|
||||
[EInboxIssueCurrentTab.OPEN]: openCount,
|
||||
[EInboxIssueCurrentTab.CLOSED]: closedCount,
|
||||
};
|
||||
|
||||
this.loader = undefined;
|
||||
|
|
|
|||
Loading…
Reference in New Issue