plane/web/components/issues/issue-layouts/kanban/default.tsx
guru_sainath d6abb87a3a chore: implemented new store and issue layouts for issues and updated new data structure for issues (#2843)
* fix: Implemented new workflow in the issue store and updated the quick add workflow in list layout

* fix: initial load and mutaion of issues in list layout

* dev: implemented the new project issues store with grouped, subGrouped and unGrouped issue computed functions

* dev: default display properties data made as a function

* conflict: merge conflict resolved

* dev: implemented quick add logic in kanban

* chore: implemented quick add logic in calendar and spreadsheet layout

* fix: spreadsheet layout quick add fix

* dev: optimised the issues workflow and handled the issues order_by filter

* dev: project issue CRUD operations in new issue store architecture

* dev: issues filtering in calendar layout

* fix: build error

* dev/issue_filters_store

* chore: updated filters computed structure

* conflict: merge conflicts resolved in project issues

* dev: implemented gantt chart for project issues using the new mobx store

* dev: initialized cycle and module issue filters store

* dev: issue store and list layout store updates

* dev: quick add and update, delete issue in the list

* refactor list root changes

* dev: store new structure

* refactor spreadsheet and gnatt project roots

* fix errors for base gantt and spreadsheet roots

* connect Calendar project view

* minor house keeping

* connect Kanban View to th enew store

* generalise base calendar issue actions

* dev: store project issues and issue filters

* dev: store project issues and filters

* dev: updated undefined with displayFilters in project issue store

* Add Quick add to all the layouts

* connect module views to store

* dev: Rendering list issues in project issues

* dev: removed console log

* dev: module filters store

* fix errors and connect modules list and quick add for list

* dev: module issue store

* dev: modle filter store issue fixed and updates cycle issue filters

* minor house keeping changes

* dev: cycle issues and cycle filters

* connecty cycles to teh store

* dev: project view issues and issue filtrs

* connect project views

* dev: updated applied filters in layouts

* dev: replaced project id with view id in project views

* dev: in cycle and module store made cycledId and moduleId as optional

* fix minor issues and build errots

* dev: project draft and archived issues store and filters

---------

Co-authored-by: Anmol Singh Bhatia <anmolsinghbhatia@plane.so>
Co-authored-by: Aaryan Khandelwal <aaryankhandu123@gmail.com>
Co-authored-by: rahulramesha <rahulramesham@gmail.com>
2023-12-07 19:59:35 +05:30

404 lines
14 KiB
TypeScript

import React from "react";
import { observer } from "mobx-react-lite";
import { Droppable } from "@hello-pangea/dnd";
// mobx store
import { useMobxStore } from "lib/mobx/store-provider";
// components
import { KanBanGroupByHeaderRoot } from "./headers/group-by-root";
import { KanbanIssueBlocksList, KanBanQuickAddIssueForm } from "components/issues";
// types
import { IIssueDisplayProperties, IIssue, IState } from "types";
// constants
import { getValueFromObject } from "constants/issue";
import { replaceUnderscoreIfSnakeCase } from "helpers/string.helper";
import { EIssueActions } from "../types";
import { IIssueResponse, IGroupedIssues, ISubGroupedIssues, TUnGroupedIssues } from "store/issues/types";
export interface IGroupByKanBan {
issues: IIssueResponse;
issueIds: any;
sub_group_by: string | null;
group_by: string | null;
order_by: string | null;
sub_group_id: string;
list: any;
listKey: string;
states: IState[] | null;
isDragDisabled: boolean;
handleIssues: (sub_group_by: string | null, group_by: string | null, issue: IIssue, action: EIssueActions) => void;
showEmptyGroup: boolean;
quickActions: (sub_group_by: string | null, group_by: string | null, issue: IIssue) => React.ReactNode;
displayProperties: IIssueDisplayProperties | null;
kanBanToggle: any;
handleKanBanToggle: any;
enableQuickIssueCreate?: boolean;
isDragStarted?: boolean;
quickAddCallback?: (
workspaceSlug: string,
projectId: string,
data: IIssue,
viewId?: string
) => Promise<IIssue | undefined>;
viewId?: string;
}
const GroupByKanBan: React.FC<IGroupByKanBan> = observer((props) => {
const {
issues,
issueIds,
sub_group_by,
group_by,
order_by,
sub_group_id = "null",
list,
listKey,
isDragDisabled,
handleIssues,
showEmptyGroup,
quickActions,
displayProperties,
kanBanToggle,
handleKanBanToggle,
enableQuickIssueCreate,
isDragStarted,
quickAddCallback,
viewId,
} = props;
const verticalAlignPosition = (_list: any) =>
kanBanToggle?.groupByHeaderMinMax.includes(getValueFromObject(_list, listKey) as string);
return (
<div className="relative w-full h-full flex gap-3">
{list &&
list.length > 0 &&
list.map((_list: any) => (
<div
className={`relative flex-shrink-0 flex flex-col ${!verticalAlignPosition(_list) ? `w-[340px]` : ``} group`}
>
{sub_group_by === null && (
<div className="flex-shrink-0 w-full bg-custom-background-90 py-1 sticky top-0 z-[2]">
<KanBanGroupByHeaderRoot
column_id={getValueFromObject(_list, listKey) as string}
column_value={_list}
sub_group_by={sub_group_by}
group_by={group_by}
issues_count={issueIds?.[getValueFromObject(_list, listKey) as string]?.length || 0}
kanBanToggle={kanBanToggle}
handleKanBanToggle={handleKanBanToggle}
/>
</div>
)}
<div
className={`min-h-[150px] h-full ${
verticalAlignPosition(_list) ? `w-[0px] overflow-hidden` : `w-full transition-all`
}`}
>
<Droppable
droppableId={`${getValueFromObject(_list, listKey) as string}__${sub_group_id}`}
isDropDisabled={isDragDisabled}
>
{(provided: any, snapshot: any) => (
<div
className={`w-full h-full relative transition-all ${
snapshot.isDraggingOver ? `bg-custom-background-80` : ``
}`}
{...provided.droppableProps}
ref={provided.innerRef}
>
{issues ? (
<KanbanIssueBlocksList
sub_group_id={sub_group_id}
columnId={getValueFromObject(_list, listKey) as string}
issues={issues}
issueIds={issueIds?.[getValueFromObject(_list, listKey) as string] || []}
isDragDisabled={isDragDisabled}
showEmptyGroup={showEmptyGroup}
handleIssues={handleIssues}
quickActions={quickActions}
displayProperties={displayProperties}
/>
) : (
isDragDisabled && (
<div className="absolute top-0 left-0 w-full h-full flex items-center justify-center text-sm">
{/* <div className="text-custom-text-300 text-sm">Drop here</div> */}
</div>
)
)}
{provided.placeholder}
</div>
)}
</Droppable>
</div>
<div className="flex-shrink-0 w-full bg-custom-background-90 py-1 sticky bottom-0 z-[0]">
{enableQuickIssueCreate && (
<KanBanQuickAddIssueForm
formKey="name"
groupId={getValueFromObject(_list, listKey) as string}
subGroupId={sub_group_id}
prePopulatedData={{
...(group_by && { [group_by]: getValueFromObject(_list, listKey) }),
...(sub_group_by && sub_group_id !== "null" && { [sub_group_by]: sub_group_id }),
}}
quickAddCallback={quickAddCallback}
viewId={viewId}
/>
)}
</div>
{isDragStarted && isDragDisabled && (
<div className="invisible group-hover:visible transition-all text-sm absolute top-12 bottom-10 left-0 right-0 bg-custom-background-100/40 text-center">
<div className="rounded inline-flex mt-80 h-8 px-3 justify-center items-center bg-custom-background-80 text-custom-text-100 font-medium">
{`This board is ordered by "${replaceUnderscoreIfSnakeCase(
order_by ? (order_by[0] === "-" ? order_by.slice(1) : order_by) : "created_at"
)}"`}
</div>
</div>
)}
</div>
))}
</div>
);
});
export interface IKanBan {
issues: IIssueResponse;
issueIds: IGroupedIssues | ISubGroupedIssues | TUnGroupedIssues;
sub_group_by: string | null;
group_by: string | null;
order_by: string | null;
sub_group_id?: string;
handleIssues: (sub_group_by: string | null, group_by: string | null, issue: IIssue, action: EIssueActions) => void;
quickActions: (sub_group_by: string | null, group_by: string | null, issue: IIssue) => React.ReactNode;
displayProperties: IIssueDisplayProperties | null;
kanBanToggle: any;
handleKanBanToggle: any;
showEmptyGroup: boolean;
states: any;
stateGroups: any;
priorities: any;
labels: any;
members: any;
projects: any;
enableQuickIssueCreate?: boolean;
isDragStarted?: boolean;
quickAddCallback?: (
workspaceSlug: string,
projectId: string,
data: IIssue,
viewId?: string
) => Promise<IIssue | undefined>;
viewId?: string;
}
export const KanBan: React.FC<IKanBan> = observer((props) => {
const {
issues,
issueIds,
sub_group_by,
group_by,
order_by,
sub_group_id = "null",
handleIssues,
quickActions,
displayProperties,
kanBanToggle,
handleKanBanToggle,
showEmptyGroup,
states,
stateGroups,
priorities,
labels,
members,
projects,
enableQuickIssueCreate,
isDragStarted,
quickAddCallback,
viewId,
} = props;
const { issueKanBanView: issueKanBanViewStore } = useMobxStore();
return (
<div className="relative w-full h-full">
{group_by && group_by === "project" && (
<GroupByKanBan
issues={issues}
issueIds={issueIds}
group_by={group_by}
order_by={order_by}
sub_group_by={sub_group_by}
sub_group_id={sub_group_id}
list={projects}
listKey={`id`}
states={states}
isDragDisabled={!issueKanBanViewStore?.canUserDragDrop}
showEmptyGroup={showEmptyGroup}
handleIssues={handleIssues}
quickActions={quickActions}
displayProperties={displayProperties}
kanBanToggle={kanBanToggle}
handleKanBanToggle={handleKanBanToggle}
enableQuickIssueCreate={enableQuickIssueCreate}
isDragStarted={isDragStarted}
quickAddCallback={quickAddCallback}
viewId={viewId}
/>
)}
{group_by && group_by === "state" && (
<GroupByKanBan
issues={issues}
issueIds={issueIds}
group_by={group_by}
order_by={order_by}
sub_group_by={sub_group_by}
sub_group_id={sub_group_id}
list={states}
listKey={`id`}
states={states}
isDragDisabled={!issueKanBanViewStore?.canUserDragDrop}
showEmptyGroup={showEmptyGroup}
handleIssues={handleIssues}
quickActions={quickActions}
displayProperties={displayProperties}
kanBanToggle={kanBanToggle}
handleKanBanToggle={handleKanBanToggle}
enableQuickIssueCreate={enableQuickIssueCreate}
isDragStarted={isDragStarted}
quickAddCallback={quickAddCallback}
viewId={viewId}
/>
)}
{group_by && group_by === "state_detail.group" && (
<GroupByKanBan
issues={issues}
issueIds={issueIds}
group_by={group_by}
order_by={order_by}
sub_group_by={sub_group_by}
sub_group_id={sub_group_id}
list={stateGroups}
listKey={`key`}
states={states}
isDragDisabled={!issueKanBanViewStore?.canUserDragDrop}
showEmptyGroup={showEmptyGroup}
handleIssues={handleIssues}
quickActions={quickActions}
displayProperties={displayProperties}
kanBanToggle={kanBanToggle}
handleKanBanToggle={handleKanBanToggle}
enableQuickIssueCreate={enableQuickIssueCreate}
isDragStarted={isDragStarted}
quickAddCallback={quickAddCallback}
viewId={viewId}
/>
)}
{group_by && group_by === "priority" && (
<GroupByKanBan
issues={issues}
issueIds={issueIds}
group_by={group_by}
order_by={order_by}
sub_group_by={sub_group_by}
sub_group_id={sub_group_id}
list={priorities}
listKey={`key`}
states={states}
isDragDisabled={!issueKanBanViewStore?.canUserDragDrop}
showEmptyGroup={showEmptyGroup}
handleIssues={handleIssues}
quickActions={quickActions}
displayProperties={displayProperties}
kanBanToggle={kanBanToggle}
handleKanBanToggle={handleKanBanToggle}
enableQuickIssueCreate={enableQuickIssueCreate}
isDragStarted={isDragStarted}
quickAddCallback={quickAddCallback}
viewId={viewId}
/>
)}
{group_by && group_by === "labels" && (
<GroupByKanBan
issues={issues}
issueIds={issueIds}
group_by={group_by}
order_by={order_by}
sub_group_by={sub_group_by}
sub_group_id={sub_group_id}
list={labels ? [...labels, { id: "None", name: "None" }] : labels}
listKey={`id`}
states={states}
isDragDisabled={!issueKanBanViewStore?.canUserDragDrop}
showEmptyGroup={showEmptyGroup}
handleIssues={handleIssues}
quickActions={quickActions}
displayProperties={displayProperties}
kanBanToggle={kanBanToggle}
handleKanBanToggle={handleKanBanToggle}
enableQuickIssueCreate={enableQuickIssueCreate}
isDragStarted={isDragStarted}
quickAddCallback={quickAddCallback}
viewId={viewId}
/>
)}
{group_by && group_by === "assignees" && (
<GroupByKanBan
issues={issues}
issueIds={issueIds}
group_by={group_by}
order_by={order_by}
sub_group_by={sub_group_by}
sub_group_id={sub_group_id}
list={members ? [...members, { id: "None", display_name: "None" }] : members}
listKey={`id`}
states={states}
isDragDisabled={!issueKanBanViewStore?.canUserDragDrop}
showEmptyGroup={showEmptyGroup}
handleIssues={handleIssues}
quickActions={quickActions}
displayProperties={displayProperties}
kanBanToggle={kanBanToggle}
handleKanBanToggle={handleKanBanToggle}
enableQuickIssueCreate={enableQuickIssueCreate}
isDragStarted={isDragStarted}
quickAddCallback={quickAddCallback}
viewId={viewId}
/>
)}
{group_by && group_by === "created_by" && (
<GroupByKanBan
issues={issues}
issueIds={issueIds}
group_by={group_by}
order_by={order_by}
sub_group_by={sub_group_by}
sub_group_id={sub_group_id}
list={members}
listKey={`id`}
states={states}
isDragDisabled={!issueKanBanViewStore?.canUserDragDrop}
showEmptyGroup={showEmptyGroup}
handleIssues={handleIssues}
quickActions={quickActions}
displayProperties={displayProperties}
kanBanToggle={kanBanToggle}
handleKanBanToggle={handleKanBanToggle}
enableQuickIssueCreate={enableQuickIssueCreate}
isDragStarted={isDragStarted}
quickAddCallback={quickAddCallback}
viewId={viewId}
/>
)}
</div>
);
});