diff --git a/web/components/issues/issue-layouts/kanban/base-kanban-root.tsx b/web/components/issues/issue-layouts/kanban/base-kanban-root.tsx index 4c2e21649..5a94b6bac 100644 --- a/web/components/issues/issue-layouts/kanban/base-kanban-root.tsx +++ b/web/components/issues/issue-layouts/kanban/base-kanban-root.tsx @@ -236,51 +236,53 @@ export const BaseKanBanRoot: React.FC = observer((props: IBas )} -
- - {/* drag and delete component */} -
- - {(provided, snapshot) => ( -
- Drop here to delete the issue. -
- )} -
-
+
+
+ + {/* drag and delete component */} +
+ + {(provided, snapshot) => ( +
+ Drop here to delete the issue. +
+ )} +
+
- -
+ + +
); diff --git a/web/components/issues/issue-layouts/kanban/blocks-list.tsx b/web/components/issues/issue-layouts/kanban/blocks-list.tsx index 5a78e8c52..ce34b1fef 100644 --- a/web/components/issues/issue-layouts/kanban/blocks-list.tsx +++ b/web/components/issues/issue-layouts/kanban/blocks-list.tsx @@ -4,7 +4,7 @@ import { TIssue, IIssueDisplayProperties, IIssueMap } from "@plane/types"; import { EIssueActions } from "../types"; // components import { KanbanIssueBlock } from "components/issues"; -import { Draggable } from "@hello-pangea/dnd"; +import { Draggable, DraggableProvided, DraggableStateSnapshot } from "@hello-pangea/dnd"; interface IssueBlocksListProps { sub_group_id: string; @@ -43,8 +43,8 @@ const KanbanIssueBlocksListMemo: React.FC = (props) => { if (sub_group_id) draggableId = `${draggableId}__${sub_group_id}`; return ( - - {(provided, snapshot) => ( + + {(provided: DraggableProvided, snapshot: DraggableStateSnapshot) => ( = observer((props) => { group_by={group_by} sub_group_by={sub_group_by} sub_group_id={sub_group_id} - isDragDisabled={!issueKanBanView?.canUserDragDrop} + isDragDisabled={!issueKanBanView?.getCanUserDragDrop(group_by, sub_group_by)} handleIssues={handleIssues} quickActions={quickActions} kanbanFilters={kanbanFilters} diff --git a/web/components/issues/issue-layouts/roots/all-issue-layout-root.tsx b/web/components/issues/issue-layouts/roots/all-issue-layout-root.tsx index 59708739d..a01358ddc 100644 --- a/web/components/issues/issue-layouts/roots/all-issue-layout-root.tsx +++ b/web/components/issues/issue-layouts/roots/all-issue-layout-root.tsx @@ -100,6 +100,19 @@ export const AllIssueLayoutRoot: React.FC = observer(() => { [updateFilters, workspaceSlug] ); + const renderQuickActions = useCallback( + (issue: TIssue, customActionButton?: React.ReactElement, portalElement?: HTMLDivElement | null) => ( + handleIssues({ ...issue }, EIssueActions.UPDATE)} + handleDelete={async () => handleIssues(issue, EIssueActions.DELETE)} + portalElement={portalElement} + /> + ), + [handleIssues] + ); + return (
{!globalViewId || globalViewId !== dataViewId || loader === "init-loader" || !issueIds ? ( @@ -119,13 +132,7 @@ export const AllIssueLayoutRoot: React.FC = observer(() => { displayFilters={issueFilters?.displayFilters ?? {}} handleDisplayFilterUpdate={handleDisplayFiltersUpdate} issueIds={issueIds} - quickActions={(issue) => ( - handleIssues({ ...issue }, EIssueActions.UPDATE)} - handleDelete={async () => handleIssues(issue, EIssueActions.DELETE)} - /> - )} + quickActions={renderQuickActions} handleIssues={handleIssues} canEditProperties={canEditProperties} viewId={globalViewId} diff --git a/web/helpers/state.helper.ts b/web/helpers/state.helper.ts index e630ebb00..c19af3e95 100644 --- a/web/helpers/state.helper.ts +++ b/web/helpers/state.helper.ts @@ -8,7 +8,7 @@ export const orderStateGroups = (unorderedStateGroups: IStateResponse | undefine }; export const sortStates = (states: IState[]) => { - if (!states || states.length === 0) return null; + if (!states || states.length === 0) return; return states.sort((stateA, stateB) => { if (stateA.group === stateB.group) { diff --git a/web/store/issue/helpers/issue-helper.store.ts b/web/store/issue/helpers/issue-helper.store.ts index 7ae198aaa..5fdf0df82 100644 --- a/web/store/issue/helpers/issue-helper.store.ts +++ b/web/store/issue/helpers/issue-helper.store.ts @@ -167,7 +167,7 @@ export class IssueHelperStore implements TIssueHelperStore { array = reverse(sortBy(array, "created_at")); switch (key) { case "sort_order": - return reverse(sortBy(array, "sort_order")); + return sortBy(array, "sort_order"); case "state__name": return reverse(sortBy(array, "state")); diff --git a/web/store/issue/issue_kanban_view.store.ts b/web/store/issue/issue_kanban_view.store.ts index 3664ad22d..9476a129d 100644 --- a/web/store/issue/issue_kanban_view.store.ts +++ b/web/store/issue/issue_kanban_view.store.ts @@ -1,4 +1,5 @@ -import { action, computed, makeObservable, observable, runInAction } from "mobx"; +import { action, computed, makeObservable, observable } from "mobx"; +import { computedFn } from "mobx-utils"; import { IssueRootStore } from "./root.store"; // types @@ -8,7 +9,7 @@ export interface IIssueKanBanViewStore { subgroupByIssuesVisibility: string[]; }; // computed - canUserDragDrop: boolean; + getCanUserDragDrop: (order_by: string | null, group_by: string | null, sub_group_by?: string | null) => boolean; canUserDragDropVertically: boolean; canUserDragDropHorizontally: boolean; // actions @@ -27,7 +28,6 @@ export class IssueKanBanViewStore implements IIssueKanBanViewStore { makeObservable(this, { kanBanToggle: observable, // computed - canUserDragDrop: computed, canUserDragDropVertically: computed, canUserDragDropHorizontally: computed, @@ -38,25 +38,13 @@ export class IssueKanBanViewStore implements IIssueKanBanViewStore { this.rootStore = _rootStore; } - get canUserDragDrop() { - return true; - if (this.rootStore.issueDetail.peekIssue?.issueId) return false; - // FIXME: uncomment and fix - // if ( - // this.rootStore?.issueFilter?.userDisplayFilters?.order_by && - // this.rootStore?.issueFilter?.userDisplayFilters?.order_by === "sort_order" && - // this.rootStore?.issueFilter?.userDisplayFilters?.group_by && - // ["state", "priority"].includes(this.rootStore?.issueFilter?.userDisplayFilters?.group_by) - // ) { - // if (!this.rootStore?.issueFilter?.userDisplayFilters?.sub_group_by) return true; - // if ( - // this.rootStore?.issueFilter?.userDisplayFilters?.sub_group_by && - // ["state", "priority"].includes(this.rootStore?.issueFilter?.userDisplayFilters?.sub_group_by) - // ) - // return true; - // } - // return false; - } + getCanUserDragDrop = computedFn((group_by: string | null, sub_group_by?: string | null) => { + if (group_by && ["state", "priority"].includes(group_by)) { + if (!sub_group_by) return true; + if (sub_group_by && ["state", "priority"].includes(sub_group_by)) return true; + } + return false; + }); get canUserDragDropVertically() { return false; diff --git a/web/store/state.store.ts b/web/store/state.store.ts index 12b2d9815..eee6c1096 100644 --- a/web/store/state.store.ts +++ b/web/store/state.store.ts @@ -8,6 +8,8 @@ import { RootStore } from "./root.store"; import { IState } from "@plane/types"; // services import { ProjectStateService } from "services/project"; +// helpers +import { sortStates } from "helpers/state.helper"; export interface IStateStore { //Loaders @@ -78,7 +80,7 @@ export class StateStore implements IStateStore { const projectId = this.router.projectId; const worksapceSlug = this.router.workspaceSlug || ""; if (!projectId || !(this.fetchedMap[projectId] || this.fetchedMap[worksapceSlug])) return; - return Object.values(this.stateMap).filter((state) => state.project_id === projectId); + return sortStates(Object.values(this.stateMap).filter((state) => state.project_id === projectId)); } /** @@ -106,7 +108,7 @@ export class StateStore implements IStateStore { getProjectStates = computedFn((projectId: string) => { const worksapceSlug = this.router.workspaceSlug || ""; if (!projectId || !(this.fetchedMap[projectId] || this.fetchedMap[worksapceSlug])) return; - return Object.values(this.stateMap).filter((state) => state.project_id === projectId); + return sortStates(Object.values(this.stateMap).filter((state) => state.project_id === projectId)); }); /**