plane/web/components/issues/view-select/state.tsx

139 lines
3.9 KiB
TypeScript
Raw Permalink Normal View History

import { useState } from "react";
import { useRouter } from "next/router";
import useSWR from "swr";
// services
import stateService from "services/state.service";
import trackEventServices from "services/track-event.service";
// ui
2023-03-05 17:54:50 +00:00
import { CustomSearchSelect, Tooltip } from "components/ui";
// icons
import { StateGroupIcon } from "components/icons";
// helpers
import { getStatesList } from "helpers/state.helper";
// types
import { ICurrentUserResponse, IIssue } from "types";
// fetch-keys
2023-04-22 12:49:35 +00:00
import { STATES_LIST } from "constants/fetch-keys";
type Props = {
issue: IIssue;
partialUpdateIssue: (formData: Partial<IIssue>, issue: IIssue) => void;
2023-03-05 14:52:01 +00:00
position?: "left" | "right";
tooltipPosition?: "top" | "bottom";
className?: string;
selfPositioned?: boolean;
customButton?: boolean;
user: ICurrentUserResponse | undefined;
isNotAllowed: boolean;
};
export const ViewStateSelect: React.FC<Props> = ({
issue,
partialUpdateIssue,
2023-03-05 14:52:01 +00:00
position = "left",
tooltipPosition = "top",
className = "",
selfPositioned = false,
customButton = false,
user,
isNotAllowed,
}) => {
const [fetchStates, setFetchStates] = useState(false);
const router = useRouter();
2023-02-13 14:08:58 +00:00
const { workspaceSlug } = router.query;
const { data: stateGroups } = useSWR(
workspaceSlug && issue && fetchStates ? STATES_LIST(issue.project) : null,
workspaceSlug && issue && fetchStates
2023-02-13 14:08:58 +00:00
? () => stateService.getStates(workspaceSlug as string, issue.project)
: null
);
const states = getStatesList(stateGroups);
2023-03-05 17:54:50 +00:00
const options = states?.map((state) => ({
value: state.id,
query: state.name,
content: (
<div className="flex items-center gap-2">
<StateGroupIcon stateGroup={state.group} color={state.color} />
2023-03-05 17:54:50 +00:00
{state.name}
</div>
),
}));
const selectedOption = issue.state_detail;
2023-03-05 14:52:01 +00:00
const stateLabel = (
<Tooltip
tooltipHeading="State"
tooltipContent={selectedOption?.name ?? ""}
position={tooltipPosition}
>
<div className="flex items-center cursor-pointer w-full gap-2 text-custom-text-200">
<span className="h-3.5 w-3.5">
{selectedOption && (
<StateGroupIcon stateGroup={selectedOption.group} color={selectedOption.color} />
)}
</span>
<span className="truncate">{selectedOption?.name ?? "State"}</span>
</div>
</Tooltip>
);
return (
2023-03-05 17:54:50 +00:00
<CustomSearchSelect
className={className}
value={issue.state}
onChange={(data: string) => {
const oldState = states?.find((s) => s.id === issue.state);
const newState = states?.find((s) => s.id === data);
partialUpdateIssue(
{
state: data,
state_detail: newState,
},
issue
);
trackEventServices.trackIssuePartialPropertyUpdateEvent(
{
workspaceSlug,
workspaceId: issue.workspace,
projectId: issue.project_detail.id,
projectIdentifier: issue.project_detail.identifier,
projectName: issue.project_detail.name,
issueId: issue.id,
},
"ISSUE_PROPERTY_UPDATE_STATE",
user
);
if (oldState?.group !== "completed" && newState?.group !== "completed") {
trackEventServices.trackIssueMarkedAsDoneEvent(
{
workspaceSlug: issue.workspace_detail.slug,
workspaceId: issue.workspace_detail.id,
projectId: issue.project_detail.id,
projectIdentifier: issue.project_detail.identifier,
projectName: issue.project_detail.name,
issueId: issue.id,
},
user
);
}
}}
2023-03-05 17:54:50 +00:00
options={options}
{...(customButton ? { customButton: stateLabel } : { label: stateLabel })}
2023-03-05 14:52:01 +00:00
position={position}
2023-03-05 17:54:50 +00:00
disabled={isNotAllowed}
onOpen={() => setFetchStates(true)}
2023-03-05 17:54:50 +00:00
noChevron
selfPositioned={selfPositioned}
2023-03-05 17:54:50 +00:00
/>
);
};