base
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
export * from "./root";
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { observer } from "mobx-react";
|
||||
// components
|
||||
import { BulkOperationsUpgradeBanner } from "@/components/issues/bulk-operations/upgrade-banner";
|
||||
// hooks
|
||||
import { useMultipleSelectStore } from "@/hooks/store/use-multiple-select-store";
|
||||
import type { TSelectionHelper } from "@/hooks/use-multiple-select";
|
||||
|
||||
type Props = {
|
||||
className?: string;
|
||||
selectionHelpers: TSelectionHelper;
|
||||
};
|
||||
|
||||
export const IssueBulkOperationsRoot = observer(function IssueBulkOperationsRoot(props: Props) {
|
||||
const { className, selectionHelpers } = props;
|
||||
// store hooks
|
||||
const { isSelectionActive } = useMultipleSelectStore();
|
||||
|
||||
if (!isSelectionActive || selectionHelpers.isSelectionDisabled) return null;
|
||||
|
||||
return <BulkOperationsUpgradeBanner className={className} />;
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { observer } from "mobx-react";
|
||||
|
||||
type Props = {
|
||||
handleRemove: (val: string) => void;
|
||||
values: string[];
|
||||
editable: boolean | undefined;
|
||||
};
|
||||
|
||||
export const AppliedIssueTypeFilters = observer(function AppliedIssueTypeFilters(_props: Props) {
|
||||
return null;
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { observer } from "mobx-react";
|
||||
|
||||
type Props = {
|
||||
appliedFilters: string[] | null;
|
||||
handleUpdate: (val: string) => void;
|
||||
searchQuery: string;
|
||||
};
|
||||
|
||||
export const FilterIssueTypes = observer(function FilterIssueTypes(_props: Props) {
|
||||
return null;
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { observer } from "mobx-react";
|
||||
|
||||
type Props = {
|
||||
appliedFilters: string[] | null;
|
||||
handleUpdate: (val: string) => void;
|
||||
searchQuery: string;
|
||||
};
|
||||
|
||||
export const FilterTeamProjects = observer(function FilterTeamProjects(_props: Props) {
|
||||
return null;
|
||||
});
|
||||
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { observer } from "mobx-react";
|
||||
import { useParams } from "next/navigation";
|
||||
// icons
|
||||
import { Circle } from "lucide-react";
|
||||
// plane imports
|
||||
import {
|
||||
EUserPermissions,
|
||||
EUserPermissionsLevel,
|
||||
SPACE_BASE_PATH,
|
||||
SPACE_BASE_URL,
|
||||
WORK_ITEM_TRACKER_ELEMENTS,
|
||||
} from "@plane/constants";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { Button } from "@plane/propel/button";
|
||||
import { NewTabIcon, WorkItemsIcon } from "@plane/propel/icons";
|
||||
import { Tooltip } from "@plane/propel/tooltip";
|
||||
import { EIssuesStoreType } from "@plane/types";
|
||||
import { Breadcrumbs, Header } from "@plane/ui";
|
||||
// components
|
||||
import { BreadcrumbLink } from "@/components/common/breadcrumb-link";
|
||||
import { CountChip } from "@/components/common/count-chip";
|
||||
// constants
|
||||
import { HeaderFilters } from "@/components/issues/filters";
|
||||
// helpers
|
||||
// hooks
|
||||
import { useCommandPalette } from "@/hooks/store/use-command-palette";
|
||||
import { useIssues } from "@/hooks/store/use-issues";
|
||||
import { useProject } from "@/hooks/store/use-project";
|
||||
import { useUserPermissions } from "@/hooks/store/user";
|
||||
import { useAppRouter } from "@/hooks/use-app-router";
|
||||
import { usePlatformOS } from "@/hooks/use-platform-os";
|
||||
// plane web imports
|
||||
import { CommonProjectBreadcrumbs } from "@/plane-web/components/breadcrumbs/common";
|
||||
|
||||
export const IssuesHeader = observer(function IssuesHeader() {
|
||||
// router
|
||||
const router = useAppRouter();
|
||||
const { workspaceSlug, projectId } = useParams();
|
||||
// store hooks
|
||||
const {
|
||||
issues: { getGroupIssueCount },
|
||||
} = useIssues(EIssuesStoreType.PROJECT);
|
||||
// i18n
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { currentProjectDetails, loader } = useProject();
|
||||
|
||||
const { toggleCreateIssueModal } = useCommandPalette();
|
||||
const { allowPermissions } = useUserPermissions();
|
||||
const { isMobile } = usePlatformOS();
|
||||
|
||||
const SPACE_APP_URL = (SPACE_BASE_URL.trim() === "" ? window.location.origin : SPACE_BASE_URL) + SPACE_BASE_PATH;
|
||||
const publishedURL = `${SPACE_APP_URL}/issues/${currentProjectDetails?.anchor}`;
|
||||
|
||||
const issuesCount = getGroupIssueCount(undefined, undefined, false);
|
||||
const canUserCreateIssue = allowPermissions(
|
||||
[EUserPermissions.ADMIN, EUserPermissions.MEMBER],
|
||||
EUserPermissionsLevel.PROJECT
|
||||
);
|
||||
|
||||
return (
|
||||
<Header>
|
||||
<Header.LeftItem>
|
||||
<div className="flex items-center gap-2.5">
|
||||
<Breadcrumbs onBack={() => router.back()} isLoading={loader === "init-loader"} className="flex-grow-0">
|
||||
<CommonProjectBreadcrumbs workspaceSlug={workspaceSlug?.toString()} projectId={projectId?.toString()} />
|
||||
<Breadcrumbs.Item
|
||||
component={
|
||||
<BreadcrumbLink
|
||||
label={t("work_items")}
|
||||
href={`/${workspaceSlug}/projects/${projectId}/issues/`}
|
||||
icon={<WorkItemsIcon className="h-4 w-4 text-tertiary" />}
|
||||
isLast
|
||||
/>
|
||||
}
|
||||
isLast
|
||||
/>
|
||||
</Breadcrumbs>
|
||||
{issuesCount && issuesCount > 0 ? (
|
||||
<Tooltip
|
||||
isMobile={isMobile}
|
||||
tooltipContent={t("issues_header.count_tooltip", { count: issuesCount })}
|
||||
position="bottom"
|
||||
>
|
||||
<CountChip count={issuesCount} />
|
||||
</Tooltip>
|
||||
) : null}
|
||||
</div>
|
||||
{currentProjectDetails?.anchor ? (
|
||||
<a
|
||||
href={publishedURL}
|
||||
className="group flex items-center gap-1.5 rounded-sm bg-accent-primary/10 px-2.5 py-1 text-11 font-medium text-accent-primary"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Circle className="h-1.5 w-1.5 fill-accent-primary" strokeWidth={2} />
|
||||
{t("workspace_projects.network.public.title")}
|
||||
<NewTabIcon className="hidden h-3 w-3 group-hover:block" strokeWidth={2} />
|
||||
</a>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</Header.LeftItem>
|
||||
<Header.RightItem>
|
||||
<div className="hidden gap-2 md:flex">
|
||||
<HeaderFilters
|
||||
projectId={projectId}
|
||||
currentProjectDetails={currentProjectDetails}
|
||||
workspaceSlug={workspaceSlug}
|
||||
canUserCreateIssue={canUserCreateIssue}
|
||||
/>
|
||||
</div>
|
||||
{canUserCreateIssue && (
|
||||
<Button
|
||||
variant="primary"
|
||||
size="lg"
|
||||
onClick={() => {
|
||||
toggleCreateIssueModal(true, EIssuesStoreType.PROJECT);
|
||||
}}
|
||||
data-ph-element={WORK_ITEM_TRACKER_ELEMENTS.HEADER_ADD_BUTTON.WORK_ITEMS}
|
||||
>
|
||||
<div className="block sm:hidden">{t("issue.label", { count: 1 })}</div>
|
||||
<div className="hidden sm:block">{t("issue.add.label")}</div>
|
||||
</Button>
|
||||
)}
|
||||
</Header.RightItem>
|
||||
</Header>
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
// plane types
|
||||
import type { TIssueServiceType, TWorkItemWidgets } from "@plane/types";
|
||||
|
||||
export type TWorkItemAdditionalWidgetActionButtonsProps = {
|
||||
disabled: boolean;
|
||||
hideWidgets: TWorkItemWidgets[];
|
||||
issueServiceType: TIssueServiceType;
|
||||
projectId: string;
|
||||
workItemId: string;
|
||||
workspaceSlug: string;
|
||||
};
|
||||
|
||||
export function WorkItemAdditionalWidgetActionButtons(_props: TWorkItemAdditionalWidgetActionButtonsProps) {
|
||||
return null;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
// plane types
|
||||
import type { TIssueServiceType, TWorkItemWidgets } from "@plane/types";
|
||||
|
||||
export type TWorkItemAdditionalWidgetCollapsiblesProps = {
|
||||
disabled: boolean;
|
||||
hideWidgets: TWorkItemWidgets[];
|
||||
issueServiceType: TIssueServiceType;
|
||||
projectId: string;
|
||||
workItemId: string;
|
||||
workspaceSlug: string;
|
||||
};
|
||||
|
||||
export function WorkItemAdditionalWidgetCollapsibles(_props: TWorkItemAdditionalWidgetCollapsiblesProps) {
|
||||
return null;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
// plane types
|
||||
import type { TIssueServiceType, TWorkItemWidgets } from "@plane/types";
|
||||
|
||||
export type TWorkItemAdditionalWidgetModalsProps = {
|
||||
hideWidgets: TWorkItemWidgets[];
|
||||
issueServiceType: TIssueServiceType;
|
||||
projectId: string;
|
||||
workItemId: string;
|
||||
workspaceSlug: string;
|
||||
};
|
||||
|
||||
export function WorkItemAdditionalWidgetModals(_props: TWorkItemAdditionalWidgetModalsProps) {
|
||||
return null;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { observer } from "mobx-react";
|
||||
|
||||
export type TAdditionalActivityRoot = {
|
||||
activityId: string;
|
||||
showIssue?: boolean;
|
||||
ends: "top" | "bottom" | undefined;
|
||||
field: string | undefined;
|
||||
};
|
||||
|
||||
export const AdditionalActivityRoot = observer(function AdditionalActivityRoot(_props: TAdditionalActivityRoot) {
|
||||
return <></>;
|
||||
});
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
// plane imports
|
||||
|
||||
export type TWorkItemAdditionalSidebarProperties = {
|
||||
workItemId: string;
|
||||
workItemTypeId: string | null;
|
||||
projectId: string;
|
||||
workspaceSlug: string;
|
||||
isEditable: boolean;
|
||||
isPeekView?: boolean;
|
||||
};
|
||||
|
||||
export function WorkItemAdditionalSidebarProperties(_props: TWorkItemAdditionalSidebarProperties) {
|
||||
return <></>;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
export * from "./issue-identifier";
|
||||
export * from "./issue-properties-activity";
|
||||
export * from "./issue-type-switcher";
|
||||
export * from "./issue-type-activity";
|
||||
export * from "./parent-select-root";
|
||||
export * from "./issue-creator";
|
||||
export * from "./additional-activity-root";
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import Link from "next/link";
|
||||
// hooks
|
||||
import { useIssueDetail } from "@/hooks/store/use-issue-detail";
|
||||
|
||||
type TIssueUser = {
|
||||
activityId: string;
|
||||
customUserName?: string;
|
||||
};
|
||||
|
||||
export function IssueCreatorDisplay(props: TIssueUser) {
|
||||
const { activityId, customUserName } = props;
|
||||
// hooks
|
||||
const {
|
||||
activity: { getActivityById },
|
||||
} = useIssueDetail();
|
||||
|
||||
const activity = getActivityById(activityId);
|
||||
|
||||
if (!activity) return <></>;
|
||||
|
||||
return (
|
||||
<>
|
||||
{customUserName ? (
|
||||
<span className="font-medium text-primary">{customUserName || "NODE.DC"}</span>
|
||||
) : (
|
||||
<Link
|
||||
href={`/${activity?.workspace_detail?.slug}/profile/${activity?.actor_detail?.id}`}
|
||||
className="font-medium text-primary hover:underline"
|
||||
>
|
||||
{activity.actor_detail?.display_name}
|
||||
</Link>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { observer } from "mobx-react";
|
||||
// plane imports
|
||||
import type { TIssueIdentifierProps, TIssueTypeIdentifier } from "@plane/types";
|
||||
// hooks
|
||||
import { useIssueDetail } from "@/hooks/store/use-issue-detail";
|
||||
import { useProject } from "@/hooks/store/use-project";
|
||||
import { IdentifierText } from "@/components/issues/issue-detail/identifier-text";
|
||||
|
||||
export const IssueIdentifier = observer(function IssueIdentifier(props: TIssueIdentifierProps) {
|
||||
const { projectId, variant, size, displayProperties, enableClickToCopyIdentifier = false } = props;
|
||||
// store hooks
|
||||
const { getProjectIdentifierById } = useProject();
|
||||
const {
|
||||
issue: { getIssueById },
|
||||
} = useIssueDetail();
|
||||
// Determine if the component is using store data or not
|
||||
const isUsingStoreData = "issueId" in props;
|
||||
// derived values
|
||||
const issue = isUsingStoreData ? getIssueById(props.issueId) : null;
|
||||
const projectIdentifier = isUsingStoreData ? getProjectIdentifierById(projectId) : props.projectIdentifier;
|
||||
const issueSequenceId = isUsingStoreData ? issue?.sequence_id : props.issueSequenceId;
|
||||
const shouldRenderIssueID = displayProperties ? displayProperties.key : true;
|
||||
|
||||
if (!shouldRenderIssueID) return null;
|
||||
|
||||
return (
|
||||
<div className="flex shrink-0 items-center space-x-2">
|
||||
<IdentifierText
|
||||
identifier={`${projectIdentifier}-${issueSequenceId}`}
|
||||
enableClickToCopyIdentifier={enableClickToCopyIdentifier}
|
||||
variant={variant}
|
||||
size={size}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export const IssueTypeIdentifier = observer(function IssueTypeIdentifier(_props: TIssueTypeIdentifier) {
|
||||
return <></>;
|
||||
});
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
export * from "./root";
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
type TIssueAdditionalPropertiesActivity = {
|
||||
activityId: string;
|
||||
ends: "top" | "bottom" | undefined;
|
||||
};
|
||||
|
||||
export function IssueAdditionalPropertiesActivity(_props: TIssueAdditionalPropertiesActivity) {
|
||||
return <></>;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { observer } from "mobx-react";
|
||||
|
||||
export type TIssueTypeActivity = { activityId: string; showIssue?: boolean; ends: "top" | "bottom" | undefined };
|
||||
|
||||
export const IssueTypeActivity = observer(function IssueTypeActivity(_props: TIssueTypeActivity) {
|
||||
return <></>;
|
||||
});
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { observer } from "mobx-react";
|
||||
// store hooks
|
||||
import { useIssueDetail } from "@/hooks/store/use-issue-detail";
|
||||
// plane web components
|
||||
import { IssueIdentifier } from "@/plane-web/components/issues/issue-details/issue-identifier";
|
||||
|
||||
export type TIssueTypeSwitcherProps = {
|
||||
issueId: string;
|
||||
disabled: boolean;
|
||||
};
|
||||
|
||||
export const IssueTypeSwitcher = observer(function IssueTypeSwitcher(props: TIssueTypeSwitcherProps) {
|
||||
const { issueId } = props;
|
||||
// store hooks
|
||||
const {
|
||||
issue: { getIssueById },
|
||||
} = useIssueDetail();
|
||||
// derived values
|
||||
const issue = getIssueById(issueId);
|
||||
|
||||
if (!issue || !issue.project_id) return <></>;
|
||||
|
||||
return <IssueIdentifier issueId={issueId} projectId={issue.project_id} size="md" enableClickToCopyIdentifier />;
|
||||
});
|
||||
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
// plane imports
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
// components
|
||||
import type { TIssueOperations } from "@/components/issues/issue-detail";
|
||||
import { IssueParentSelect } from "@/components/issues/issue-detail/parent-select";
|
||||
// hooks
|
||||
import { useIssueDetail } from "@/hooks/store/use-issue-detail";
|
||||
|
||||
type TIssueParentSelect = {
|
||||
className?: string;
|
||||
disabled?: boolean;
|
||||
issueId: string;
|
||||
issueOperations: TIssueOperations;
|
||||
projectId: string;
|
||||
workspaceSlug: string;
|
||||
};
|
||||
|
||||
export const IssueParentSelectRoot = observer(function IssueParentSelectRoot(props: TIssueParentSelect) {
|
||||
const { issueId, issueOperations, projectId, workspaceSlug } = props;
|
||||
const { t } = useTranslation();
|
||||
// store hooks
|
||||
const {
|
||||
issue: { getIssueById },
|
||||
} = useIssueDetail();
|
||||
const {
|
||||
toggleParentIssueModal,
|
||||
removeSubIssue,
|
||||
subIssues: { setSubIssueHelpers, fetchSubIssues },
|
||||
} = useIssueDetail();
|
||||
|
||||
// derived values
|
||||
const issue = getIssueById(issueId);
|
||||
const parentIssue = issue?.parent_id ? getIssueById(issue.parent_id) : undefined;
|
||||
|
||||
const handleParentIssue = async (_issueId: string | null = null) => {
|
||||
try {
|
||||
await issueOperations.update(workspaceSlug, projectId, issueId, { parent_id: _issueId });
|
||||
await issueOperations.fetch(workspaceSlug, projectId, issueId, false);
|
||||
if (_issueId) await fetchSubIssues(workspaceSlug, projectId, _issueId);
|
||||
toggleParentIssueModal(null);
|
||||
} catch (_error) {
|
||||
console.error("something went wrong while fetching the issue");
|
||||
}
|
||||
};
|
||||
|
||||
const handleRemoveSubIssue = async (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
parentIssueId: string,
|
||||
issueId: string
|
||||
) => {
|
||||
try {
|
||||
setSubIssueHelpers(parentIssueId, "issue_loader", issueId);
|
||||
await removeSubIssue(workspaceSlug, projectId, parentIssueId, issueId);
|
||||
await fetchSubIssues(workspaceSlug, projectId, parentIssueId);
|
||||
setSubIssueHelpers(parentIssueId, "issue_loader", issueId);
|
||||
} catch (_error) {
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: t("common.error.label"),
|
||||
message: t("common.something_went_wrong"),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const workItemLink = `/${workspaceSlug}/projects/${parentIssue?.project_id}/issues/${parentIssue?.id}`;
|
||||
|
||||
if (!issue) return <></>;
|
||||
|
||||
return (
|
||||
<IssueParentSelect
|
||||
{...props}
|
||||
handleParentIssue={handleParentIssue}
|
||||
handleRemoveSubIssue={handleRemoveSubIssue}
|
||||
workItemLink={workItemLink}
|
||||
/>
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import type { TIssue } from "@plane/types";
|
||||
|
||||
export type TDateAlertProps = {
|
||||
date: string;
|
||||
workItem: TIssue;
|
||||
projectId: string;
|
||||
};
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function DateAlert(props: TDateAlertProps) {
|
||||
return <></>;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import type { TIssue } from "@plane/types";
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function TransferHopInfo({ workItem }: { workItem: TIssue }) {
|
||||
return <></>;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import type { IIssueDisplayProperties, TIssue } from "@plane/types";
|
||||
|
||||
export type TWorkItemLayoutAdditionalProperties = {
|
||||
displayProperties: IIssueDisplayProperties;
|
||||
issue: TIssue;
|
||||
};
|
||||
|
||||
export function WorkItemLayoutAdditionalProperties(_props: TWorkItemLayoutAdditionalProperties) {
|
||||
return <></>;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
export * from "./team-issues";
|
||||
export * from "./team-view-issues";
|
||||
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { observer } from "mobx-react";
|
||||
|
||||
export const TeamEmptyState = observer(function TeamEmptyState() {
|
||||
return <></>;
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { observer } from "mobx-react";
|
||||
|
||||
export const TeamProjectWorkItemEmptyState = observer(function TeamProjectWorkItemEmptyState() {
|
||||
return <></>;
|
||||
});
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { observer } from "mobx-react";
|
||||
|
||||
export const TeamViewEmptyState = observer(function TeamViewEmptyState() {
|
||||
return <></>;
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
|
||||
type Props = {
|
||||
issueId: string;
|
||||
className?: string;
|
||||
size?: number;
|
||||
showProgressText?: boolean;
|
||||
showLabel?: boolean;
|
||||
};
|
||||
|
||||
export function IssueStats(_props: Props) {
|
||||
return <></>;
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import type { ISvgIcons } from "@plane/propel/icons";
|
||||
import type { TContextMenuItem } from "@plane/ui";
|
||||
|
||||
export interface CopyMenuHelperProps {
|
||||
baseItem: {
|
||||
key: string;
|
||||
title: string;
|
||||
icon: React.FC<ISvgIcons>;
|
||||
action: () => void;
|
||||
shouldRender: boolean;
|
||||
};
|
||||
activeLayout: string;
|
||||
setCreateUpdateIssueModal: (open: boolean) => void;
|
||||
setDuplicateWorkItemModal?: (open: boolean) => void;
|
||||
workspaceSlug?: string;
|
||||
}
|
||||
|
||||
export const createCopyMenuWithDuplication = (props: CopyMenuHelperProps): TContextMenuItem => {
|
||||
const { baseItem } = props;
|
||||
|
||||
return baseItem;
|
||||
};
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
type TDuplicateWorkItemModalProps = {
|
||||
workItemId: string;
|
||||
onClose: () => void;
|
||||
isOpen: boolean;
|
||||
workspaceSlug: string;
|
||||
projectId: string;
|
||||
};
|
||||
|
||||
export function DuplicateWorkItemModal(_props: TDuplicateWorkItemModalProps) {
|
||||
return <></>;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
export * from "./duplicate-modal";
|
||||
export * from "./copy-menu-helper";
|
||||
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import type { FC } from "react";
|
||||
import { CalendarDays, LayersIcon, Paperclip } from "lucide-react";
|
||||
// types
|
||||
import { ISSUE_GROUP_BY_OPTIONS } from "@plane/constants";
|
||||
import type { ISvgIcons } from "@plane/propel/icons";
|
||||
import {
|
||||
LinkIcon,
|
||||
CycleIcon,
|
||||
StatePropertyIcon,
|
||||
ModuleIcon,
|
||||
MembersPropertyIcon,
|
||||
DueDatePropertyIcon,
|
||||
EstimatePropertyIcon,
|
||||
LabelPropertyIcon,
|
||||
PriorityPropertyIcon,
|
||||
StartDatePropertyIcon,
|
||||
} from "@plane/propel/icons";
|
||||
import type {
|
||||
IGroupByColumn,
|
||||
IIssueDisplayProperties,
|
||||
TGetColumns,
|
||||
TIssueGroupByOptions,
|
||||
TSpreadsheetColumn,
|
||||
} from "@plane/types";
|
||||
// components
|
||||
import {
|
||||
SpreadsheetAssigneeColumn,
|
||||
SpreadsheetAttachmentColumn,
|
||||
SpreadsheetCreatedOnColumn,
|
||||
SpreadsheetDueDateColumn,
|
||||
SpreadsheetEstimateColumn,
|
||||
SpreadsheetLabelColumn,
|
||||
SpreadsheetModuleColumn,
|
||||
SpreadsheetCycleColumn,
|
||||
SpreadsheetLinkColumn,
|
||||
SpreadsheetPriorityColumn,
|
||||
SpreadsheetStartDateColumn,
|
||||
SpreadsheetStateColumn,
|
||||
SpreadsheetSubIssueColumn,
|
||||
SpreadsheetUpdatedOnColumn,
|
||||
} from "@/components/issues/issue-layouts/spreadsheet/columns";
|
||||
// store
|
||||
import { store } from "@/lib/store-context";
|
||||
|
||||
export type TGetScopeMemberIdsResult = {
|
||||
memberIds: string[];
|
||||
includeNone: boolean;
|
||||
};
|
||||
|
||||
export const getScopeMemberIds = ({ isWorkspaceLevel, projectId }: TGetColumns): TGetScopeMemberIdsResult => {
|
||||
// store values
|
||||
const { workspaceMemberIds } = store.memberRoot.workspace;
|
||||
const { projectMemberIds } = store.memberRoot.project;
|
||||
// derived values
|
||||
const memberIds = workspaceMemberIds;
|
||||
|
||||
if (isWorkspaceLevel) {
|
||||
return { memberIds: memberIds ?? [], includeNone: true };
|
||||
}
|
||||
|
||||
if (projectId || (projectMemberIds && projectMemberIds.length > 0)) {
|
||||
const { getProjectMemberIds } = store.memberRoot.project;
|
||||
const _projectMemberIds = projectId ? getProjectMemberIds(projectId, false) : projectMemberIds;
|
||||
return {
|
||||
memberIds: _projectMemberIds ?? [],
|
||||
includeNone: true,
|
||||
};
|
||||
}
|
||||
|
||||
return { memberIds: [], includeNone: true };
|
||||
};
|
||||
|
||||
export const getTeamProjectColumns = (): IGroupByColumn[] | undefined => undefined;
|
||||
|
||||
export const SpreadSheetPropertyIconMap: Record<string, FC<ISvgIcons>> = {
|
||||
MembersPropertyIcon: MembersPropertyIcon,
|
||||
CalenderDays: CalendarDays,
|
||||
DueDatePropertyIcon: DueDatePropertyIcon,
|
||||
EstimatePropertyIcon: EstimatePropertyIcon,
|
||||
LabelPropertyIcon: LabelPropertyIcon,
|
||||
ModuleIcon: ModuleIcon,
|
||||
ContrastIcon: CycleIcon,
|
||||
PriorityPropertyIcon: PriorityPropertyIcon,
|
||||
StartDatePropertyIcon: StartDatePropertyIcon,
|
||||
StatePropertyIcon: StatePropertyIcon,
|
||||
Link2: LinkIcon,
|
||||
Paperclip: Paperclip,
|
||||
LayersIcon: LayersIcon,
|
||||
};
|
||||
|
||||
export const SPREADSHEET_COLUMNS: { [key in keyof IIssueDisplayProperties]: TSpreadsheetColumn } = {
|
||||
assignee: SpreadsheetAssigneeColumn,
|
||||
created_on: SpreadsheetCreatedOnColumn,
|
||||
due_date: SpreadsheetDueDateColumn,
|
||||
estimate: SpreadsheetEstimateColumn,
|
||||
labels: SpreadsheetLabelColumn,
|
||||
modules: SpreadsheetModuleColumn,
|
||||
cycle: SpreadsheetCycleColumn,
|
||||
link: SpreadsheetLinkColumn,
|
||||
priority: SpreadsheetPriorityColumn,
|
||||
start_date: SpreadsheetStartDateColumn,
|
||||
state: SpreadsheetStateColumn,
|
||||
sub_issue_count: SpreadsheetSubIssueColumn,
|
||||
updated_on: SpreadsheetUpdatedOnColumn,
|
||||
attachment_count: SpreadsheetAttachmentColumn,
|
||||
};
|
||||
|
||||
export const useGroupByOptions = (
|
||||
options: TIssueGroupByOptions[]
|
||||
): {
|
||||
key: TIssueGroupByOptions;
|
||||
titleTranslationKey: string;
|
||||
}[] => {
|
||||
const groupByOptions = ISSUE_GROUP_BY_OPTIONS.filter((option) => options.includes(option.key));
|
||||
return groupByOptions;
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
export * from "./provider";
|
||||
export * from "./issue-type-select";
|
||||
export * from "./template-select";
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import type { Control } from "react-hook-form";
|
||||
// plane imports
|
||||
import type { EditorRefApi } from "@plane/editor";
|
||||
// types
|
||||
import type { TBulkIssueProperties, TIssue } from "@plane/types";
|
||||
|
||||
export type TIssueFields = TIssue & TBulkIssueProperties;
|
||||
|
||||
export type TIssueTypeDropdownVariant = "xs" | "sm";
|
||||
|
||||
export type TIssueTypeSelectProps<T extends Partial<TIssueFields>> = {
|
||||
control: Control<T>;
|
||||
projectId: string | null;
|
||||
editorRef?: React.MutableRefObject<EditorRefApi | null>;
|
||||
disabled?: boolean;
|
||||
variant?: TIssueTypeDropdownVariant;
|
||||
placeholder?: string;
|
||||
isRequired?: boolean;
|
||||
renderChevron?: boolean;
|
||||
dropDownContainerClassName?: string;
|
||||
showMandatoryFieldInfo?: boolean; // Show info about mandatory fields
|
||||
handleFormChange?: () => void;
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function IssueTypeSelect<T extends Partial<TIssueFields>>(props: TIssueTypeSelectProps<T>) {
|
||||
return <></>;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
export type TWorkItemModalAdditionalPropertiesProps = {
|
||||
isDraft?: boolean;
|
||||
projectId: string | null;
|
||||
workItemId: string | undefined;
|
||||
workspaceSlug: string;
|
||||
};
|
||||
|
||||
export function WorkItemModalAdditionalProperties(_props: TWorkItemModalAdditionalPropertiesProps) {
|
||||
return null;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import React, { useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
// plane imports
|
||||
import type { ISearchIssueResponse, TIssue } from "@plane/types";
|
||||
// components
|
||||
import { IssueModalContext } from "@/components/issues/issue-modal/context";
|
||||
// hooks
|
||||
import { useUser } from "@/hooks/store/user/user-user";
|
||||
|
||||
export type TIssueModalProviderProps = {
|
||||
templateId?: string;
|
||||
dataForPreload?: Partial<TIssue>;
|
||||
allowedProjectIds?: string[];
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
export const IssueModalProvider = observer(function IssueModalProvider(props: TIssueModalProviderProps) {
|
||||
const { children, allowedProjectIds } = props;
|
||||
// states
|
||||
const [selectedParentIssue, setSelectedParentIssue] = useState<ISearchIssueResponse | null>(null);
|
||||
// store hooks
|
||||
const { projectsWithCreatePermissions } = useUser();
|
||||
// derived values
|
||||
const projectIdsWithCreatePermissions = Object.keys(projectsWithCreatePermissions ?? {});
|
||||
|
||||
return (
|
||||
<IssueModalContext.Provider
|
||||
value={{
|
||||
allowedProjectIds: allowedProjectIds ?? projectIdsWithCreatePermissions,
|
||||
workItemTemplateId: null,
|
||||
setWorkItemTemplateId: () => {},
|
||||
isApplyingTemplate: false,
|
||||
setIsApplyingTemplate: () => {},
|
||||
selectedParentIssue,
|
||||
setSelectedParentIssue,
|
||||
issuePropertyValues: {},
|
||||
setIssuePropertyValues: () => {},
|
||||
issuePropertyValueErrors: {},
|
||||
setIssuePropertyValueErrors: () => {},
|
||||
getIssueTypeIdOnProjectChange: () => null,
|
||||
getActiveAdditionalPropertiesLength: () => 0,
|
||||
handlePropertyValuesValidation: () => true,
|
||||
handleCreateUpdatePropertyValues: () => Promise.resolve(),
|
||||
handleProjectEntitiesFetch: () => Promise.resolve(),
|
||||
handleTemplateChange: () => Promise.resolve(),
|
||||
handleConvert: () => Promise.resolve(),
|
||||
handleCreateSubWorkItem: () => Promise.resolve(),
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</IssueModalContext.Provider>
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
export type TWorkItemTemplateDropdownSize = "xs" | "sm";
|
||||
|
||||
export type TWorkItemTemplateSelect = {
|
||||
projectId: string | null;
|
||||
typeId: string | null;
|
||||
disabled?: boolean;
|
||||
size?: TWorkItemTemplateDropdownSize;
|
||||
placeholder?: string;
|
||||
renderChevron?: boolean;
|
||||
dropDownContainerClassName?: string;
|
||||
handleModalClose: () => void;
|
||||
handleFormChange?: () => void;
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function WorkItemTemplateSelect(props: TWorkItemTemplateSelect) {
|
||||
return <></>;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
export * from "./root";
|
||||
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import type { FC } from "react";
|
||||
import { useEffect, useRef } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import type { UseFormRegister, UseFormSetFocus } from "react-hook-form";
|
||||
// plane constants
|
||||
// plane helpers
|
||||
import { useOutsideClickDetector } from "@plane/hooks";
|
||||
// types
|
||||
import type { TIssue } from "@plane/types";
|
||||
import { EIssueLayoutTypes } from "@plane/types";
|
||||
// components
|
||||
import type { TQuickAddIssueForm } from "@/components/issues/issue-layouts/quick-add";
|
||||
import {
|
||||
CalendarQuickAddIssueForm,
|
||||
GanttQuickAddIssueForm,
|
||||
KanbanQuickAddIssueForm,
|
||||
ListQuickAddIssueForm,
|
||||
SpreadsheetQuickAddIssueForm,
|
||||
} from "@/components/issues/issue-layouts/quick-add";
|
||||
// hooks
|
||||
import { useProject } from "@/hooks/store/use-project";
|
||||
import useKeypress from "@/hooks/use-keypress";
|
||||
|
||||
export type TQuickAddIssueFormRoot = {
|
||||
isOpen: boolean;
|
||||
layout: EIssueLayoutTypes;
|
||||
prePopulatedData?: Partial<TIssue>;
|
||||
projectId: string;
|
||||
hasError?: boolean;
|
||||
setFocus: UseFormSetFocus<TIssue>;
|
||||
register: UseFormRegister<TIssue>;
|
||||
onSubmit: () => void;
|
||||
onClose: () => void;
|
||||
isEpic: boolean;
|
||||
};
|
||||
|
||||
export const QuickAddIssueFormRoot = observer(function QuickAddIssueFormRoot(props: TQuickAddIssueFormRoot) {
|
||||
const { isOpen, layout, projectId, hasError = false, setFocus, register, onSubmit, onClose, isEpic } = props;
|
||||
// store hooks
|
||||
const { getProjectById } = useProject();
|
||||
// derived values
|
||||
const projectDetail = getProjectById(projectId);
|
||||
// refs
|
||||
const ref = useRef<HTMLFormElement>(null);
|
||||
// click detection
|
||||
useKeypress("Escape", onClose);
|
||||
useOutsideClickDetector(ref, onClose);
|
||||
// set focus on name input
|
||||
useEffect(() => {
|
||||
setFocus("name");
|
||||
}, [setFocus]);
|
||||
|
||||
if (!projectDetail) return <></>;
|
||||
|
||||
const QUICK_ADD_ISSUE_FORMS: Record<EIssueLayoutTypes, FC<TQuickAddIssueForm>> = {
|
||||
[EIssueLayoutTypes.LIST]: ListQuickAddIssueForm,
|
||||
[EIssueLayoutTypes.KANBAN]: KanbanQuickAddIssueForm,
|
||||
[EIssueLayoutTypes.CALENDAR]: CalendarQuickAddIssueForm,
|
||||
[EIssueLayoutTypes.GANTT]: GanttQuickAddIssueForm,
|
||||
[EIssueLayoutTypes.SPREADSHEET]: SpreadsheetQuickAddIssueForm,
|
||||
};
|
||||
|
||||
const CurrentLayoutQuickAddIssueForm = QUICK_ADD_ISSUE_FORMS[layout] ?? null;
|
||||
|
||||
if (!CurrentLayoutQuickAddIssueForm) return <></>;
|
||||
|
||||
return (
|
||||
<CurrentLayoutQuickAddIssueForm
|
||||
ref={ref}
|
||||
isOpen={isOpen}
|
||||
projectDetail={projectDetail}
|
||||
hasError={hasError}
|
||||
register={register}
|
||||
onSubmit={onSubmit}
|
||||
isEpic={isEpic}
|
||||
/>
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
// plane imports
|
||||
import type { TActivityFilters, TActivityFilterOption } from "@plane/constants";
|
||||
import { ACTIVITY_FILTER_TYPE_OPTIONS } from "@plane/constants";
|
||||
// components
|
||||
import { ActivityFilter } from "@/components/issues/issue-detail/issue-activity";
|
||||
|
||||
export type TActivityFilterRoot = {
|
||||
selectedFilters: TActivityFilters[];
|
||||
toggleFilter: (filter: TActivityFilters) => void;
|
||||
projectId: string;
|
||||
isIntakeIssue?: boolean;
|
||||
};
|
||||
|
||||
export function ActivityFilterRoot(props: TActivityFilterRoot) {
|
||||
const { selectedFilters, toggleFilter } = props;
|
||||
|
||||
const filters: TActivityFilterOption[] = Object.entries(ACTIVITY_FILTER_TYPE_OPTIONS).map(([key, value]) => {
|
||||
const filterKey = key as TActivityFilters;
|
||||
return {
|
||||
key: filterKey,
|
||||
labelTranslationKey: value.labelTranslationKey,
|
||||
isSelected: selectedFilters.includes(filterKey),
|
||||
onClick: () => toggleFilter(filterKey),
|
||||
};
|
||||
});
|
||||
|
||||
return <ActivityFilter selectedFilters={selectedFilters} filterOptions={filters} />;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
export * from "./root";
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import type { TIssueActivityComment } from "@plane/types";
|
||||
|
||||
type TIssueActivityWorklog = {
|
||||
workspaceSlug: string;
|
||||
projectId: string;
|
||||
issueId: string;
|
||||
activityComment: TIssueActivityComment;
|
||||
ends?: "top" | "bottom";
|
||||
};
|
||||
|
||||
export function IssueActivityWorklog(_props: TIssueActivityWorklog) {
|
||||
return <></>;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
type TIssueActivityWorklogCreateButton = {
|
||||
workspaceSlug: string;
|
||||
projectId: string;
|
||||
issueId: string;
|
||||
disabled: boolean;
|
||||
};
|
||||
|
||||
export function IssueActivityWorklogCreateButton(_props: TIssueActivityWorklogCreateButton) {
|
||||
return <></>;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
export * from "./root";
|
||||
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
type TIssueWorklogProperty = {
|
||||
workspaceSlug: string;
|
||||
projectId: string;
|
||||
issueId: string;
|
||||
disabled: boolean;
|
||||
};
|
||||
|
||||
export function IssueWorklogProperty(_props: TIssueWorklogProperty) {
|
||||
return <></>;
|
||||
}
|
||||
Reference in New Issue
Block a user