mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
daa3094911
* chore: dynamic position dropdown (#2138) * chore: dynamic position state dropdown for issue view * style: state select dropdown styling * fix: state icon attribute names * chore: state select dynamic dropdown * chore: member select dynamic dropdown * chore: label select dynamic dropdown * chore: priority select dynamic dropdown * chore: label select dropdown improvement * refactor: state dropdown location * chore: dropdown improvement and code refactor * chore: dynamic dropdown hook type added --------- Co-authored-by: Aaryan Khandelwal <aaryankhandu123@gmail.com> * fix: fields not getting selected in the create issue form (#2212) * fix: hydration error and draft issue workflow * fix: build error * fix: properties getting de-selected after create, module & cycle not getting auto-select on the form * fix: display layout, props being updated directly * chore: sub issues count in individual issue (#2221) * Implemented nested issues in the sub issues section in issue detail page (#2233) * feat: subissues infinte level * feat: updated UI for sub issues * feat: subissues new ui and nested sub issues in issue detail * chore: removed repeated code * refactor: product updates modal layout (#2225) * fix: handle no issues in custom analytics (#2226) * fix: activity label color (#2227) * fix: profile issues layout switch (#2228) * chore: update service imports * chore: update issue detail store to handle peek overview --------- Co-authored-by: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Co-authored-by: Dakshesh Jain <65905942+dakshesh14@users.noreply.github.com> Co-authored-by: Bavisetti Narayan <72156168+NarayanBavisetti@users.noreply.github.com> Co-authored-by: guru_sainath <gurusainath007@gmail.com>
194 lines
5.5 KiB
TypeScript
194 lines
5.5 KiB
TypeScript
import React from "react";
|
|
// swr
|
|
import { mutate } from "swr";
|
|
// services
|
|
import issuesService from "services/issue.service";
|
|
import trackEventServices from "services/track_event.service";
|
|
// components
|
|
import { ViewDueDateSelect, ViewStartDateSelect } from "components/issues";
|
|
import { MembersSelect, PrioritySelect } from "components/project";
|
|
import { StateSelect } from "components/states";
|
|
// hooks
|
|
import useIssuesProperties from "hooks/use-issue-properties";
|
|
// types
|
|
import { ICurrentUserResponse, IIssue, IState } from "types";
|
|
// fetch-keys
|
|
import { SUB_ISSUES } from "constants/fetch-keys";
|
|
|
|
export interface IIssueProperty {
|
|
workspaceSlug: string;
|
|
projectId: string;
|
|
parentIssue: IIssue;
|
|
issue: IIssue;
|
|
user: ICurrentUserResponse | undefined;
|
|
editable: boolean;
|
|
}
|
|
|
|
export const IssueProperty: React.FC<IIssueProperty> = ({
|
|
workspaceSlug,
|
|
projectId,
|
|
parentIssue,
|
|
issue,
|
|
user,
|
|
editable,
|
|
}) => {
|
|
const [properties] = useIssuesProperties(workspaceSlug, projectId);
|
|
|
|
const handlePriorityChange = (data: any) => {
|
|
partialUpdateIssue({ priority: data });
|
|
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_PRIORITY",
|
|
user
|
|
);
|
|
};
|
|
|
|
const handleStateChange = (data: string, states: IState[] | undefined) => {
|
|
const oldState = states?.find((s) => s.id === issue.state);
|
|
const newState = states?.find((s) => s.id === data);
|
|
|
|
partialUpdateIssue({
|
|
state: data,
|
|
state_detail: newState,
|
|
});
|
|
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
|
|
);
|
|
}
|
|
};
|
|
|
|
const handleAssigneeChange = (data: any) => {
|
|
const newData = issue.assignees ?? [];
|
|
|
|
if (newData.includes(data)) newData.splice(newData.indexOf(data), 1);
|
|
else newData.push(data);
|
|
|
|
partialUpdateIssue({ assignees_list: data });
|
|
|
|
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_ASSIGNEE",
|
|
user
|
|
);
|
|
};
|
|
|
|
const partialUpdateIssue = async (data: Partial<IIssue>) => {
|
|
mutate(
|
|
workspaceSlug && parentIssue ? SUB_ISSUES(parentIssue.id) : null,
|
|
(elements: any) => {
|
|
const _elements = { ...elements };
|
|
const _issues = _elements.sub_issues.map((element: IIssue) =>
|
|
element.id === issue.id ? { ...element, ...data } : element
|
|
);
|
|
_elements["sub_issues"] = [..._issues];
|
|
return _elements;
|
|
},
|
|
false
|
|
);
|
|
|
|
const issueResponse = await issuesService.patchIssue(workspaceSlug as string, issue.project, issue.id, data, user);
|
|
|
|
mutate(
|
|
SUB_ISSUES(parentIssue.id),
|
|
(elements: any) => {
|
|
const _elements = elements.sub_issues.map((element: IIssue) =>
|
|
element.id === issue.id ? issueResponse : element
|
|
);
|
|
elements["sub_issues"] = _elements;
|
|
return elements;
|
|
},
|
|
true
|
|
);
|
|
};
|
|
|
|
return (
|
|
<div className="relative flex items-center gap-1">
|
|
{properties.priority && (
|
|
<div className="flex-shrink-0">
|
|
<PrioritySelect
|
|
value={issue.priority}
|
|
onChange={handlePriorityChange}
|
|
hideDropdownArrow
|
|
disabled={!editable}
|
|
/>
|
|
</div>
|
|
)}
|
|
|
|
{properties.state && (
|
|
<div className="flex-shrink-0">
|
|
<StateSelect value={issue.state_detail} onChange={handleStateChange} hideDropdownArrow disabled={!editable} />
|
|
</div>
|
|
)}
|
|
|
|
{properties.start_date && issue.start_date && (
|
|
<div className="flex-shrink-0 w-[104px]">
|
|
<ViewStartDateSelect
|
|
issue={issue}
|
|
partialUpdateIssue={partialUpdateIssue}
|
|
user={user}
|
|
isNotAllowed={!editable}
|
|
/>
|
|
</div>
|
|
)}
|
|
|
|
{properties.due_date && issue.target_date && (
|
|
<div className="flex-shrink-0 w-[104px]">
|
|
<ViewDueDateSelect
|
|
issue={issue}
|
|
partialUpdateIssue={partialUpdateIssue}
|
|
user={user}
|
|
isNotAllowed={!editable}
|
|
/>
|
|
</div>
|
|
)}
|
|
|
|
{properties.assignee && (
|
|
<div className="flex-shrink-0">
|
|
<MembersSelect
|
|
value={issue.assignees}
|
|
onChange={handleAssigneeChange}
|
|
membersDetails={issue.assignee_details}
|
|
hideDropdownArrow
|
|
disabled={!editable}
|
|
/>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|