mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
Merge branch 'refactor/mobx-store' of https://github.com/makeplane/plane into refactor/mobx-store
This commit is contained in:
commit
9b86afd089
@ -123,12 +123,15 @@ export const BaseKanBanRoot: React.FC<IBaseKanBanLayout> = observer((props: IBas
|
||||
|
||||
const isEditingAllowed = !!currentProjectRole && currentProjectRole >= EUserWorkspaceRoles.MEMBER;
|
||||
|
||||
const canEditProperties = (projectId: string | undefined) => {
|
||||
const isEditingAllowedBasedOnProject =
|
||||
canEditPropertiesBasedOnProject && projectId ? canEditPropertiesBasedOnProject(projectId) : isEditingAllowed;
|
||||
const canEditProperties = useCallback(
|
||||
(projectId: string | undefined) => {
|
||||
const isEditingAllowedBasedOnProject =
|
||||
canEditPropertiesBasedOnProject && projectId ? canEditPropertiesBasedOnProject(projectId) : isEditingAllowed;
|
||||
|
||||
return enableInlineEditing && isEditingAllowedBasedOnProject;
|
||||
};
|
||||
return enableInlineEditing && isEditingAllowedBasedOnProject;
|
||||
},
|
||||
[canEditPropertiesBasedOnProject, enableInlineEditing, isEditingAllowed]
|
||||
);
|
||||
|
||||
const onDragStart = (dragStart: DragStart) => {
|
||||
setDragState({
|
||||
@ -183,18 +186,21 @@ export const BaseKanBanRoot: React.FC<IBaseKanBanLayout> = observer((props: IBas
|
||||
[issueActions]
|
||||
);
|
||||
|
||||
const renderQuickActions = (issue: IIssue, customActionButton?: React.ReactElement) => (
|
||||
<QuickActions
|
||||
customActionButton={customActionButton}
|
||||
issue={issue}
|
||||
handleDelete={async () => handleIssues(issue, EIssueActions.DELETE)}
|
||||
handleUpdate={
|
||||
issueActions[EIssueActions.UPDATE] ? async (data) => handleIssues(data, EIssueActions.UPDATE) : undefined
|
||||
}
|
||||
handleRemoveFromView={
|
||||
issueActions[EIssueActions.REMOVE] ? async () => handleIssues(issue, EIssueActions.REMOVE) : undefined
|
||||
}
|
||||
/>
|
||||
const renderQuickActions = useCallback(
|
||||
(issue: IIssue, customActionButton?: React.ReactElement) => (
|
||||
<QuickActions
|
||||
customActionButton={customActionButton}
|
||||
issue={issue}
|
||||
handleDelete={async () => handleIssues(issue, EIssueActions.DELETE)}
|
||||
handleUpdate={
|
||||
issueActions[EIssueActions.UPDATE] ? async (data) => handleIssues(data, EIssueActions.UPDATE) : undefined
|
||||
}
|
||||
handleRemoveFromView={
|
||||
issueActions[EIssueActions.REMOVE] ? async () => handleIssues(issue, EIssueActions.REMOVE) : undefined
|
||||
}
|
||||
/>
|
||||
),
|
||||
[issueActions, handleIssues]
|
||||
);
|
||||
|
||||
const handleDeleteIssue = async () => {
|
||||
|
@ -1,8 +1,10 @@
|
||||
// components
|
||||
import { KanbanIssueBlock } from "components/issues";
|
||||
import { memo } from "react";
|
||||
//types
|
||||
import { IIssueDisplayProperties, IIssue } from "types";
|
||||
import { EIssueActions } from "../types";
|
||||
import { IIssueResponse } from "store_legacy/issues/types";
|
||||
// components
|
||||
import { KanbanIssueBlock } from "components/issues";
|
||||
|
||||
interface IssueBlocksListProps {
|
||||
sub_group_id: string;
|
||||
@ -17,7 +19,7 @@ interface IssueBlocksListProps {
|
||||
canEditProperties: (projectId: string | undefined) => boolean;
|
||||
}
|
||||
|
||||
export const KanbanIssueBlocksList: React.FC<IssueBlocksListProps> = (props) => {
|
||||
const KanbanIssueBlocksListMemo: React.FC<IssueBlocksListProps> = (props) => {
|
||||
const {
|
||||
sub_group_id,
|
||||
columnId,
|
||||
@ -61,3 +63,5 @@ export const KanbanIssueBlocksList: React.FC<IssueBlocksListProps> = (props) =>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const KanbanIssueBlocksList = memo(KanbanIssueBlocksListMemo);
|
||||
|
@ -1,11 +1,10 @@
|
||||
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 { KanbanIssueBlocksList, KanBanQuickAddIssueForm } from "components/issues";
|
||||
import { HeaderGroupByCard } from "./headers/group-by-card";
|
||||
import { KanbanGroup } from "./kanban-group";
|
||||
// types
|
||||
import { IIssueDisplayProperties, IIssue } from "types";
|
||||
// constants
|
||||
@ -76,81 +75,51 @@ const GroupByKanBan: React.FC<IGroupByKanBan> = observer((props) => {
|
||||
<div className="relative flex h-full w-full gap-3">
|
||||
{list &&
|
||||
list.length > 0 &&
|
||||
list.map((_list: IKanbanColumn) => (
|
||||
<div
|
||||
className={`relative flex flex-shrink-0 flex-col ${!verticalAlignPosition(_list) ? `w-[340px]` : ``} group`}
|
||||
>
|
||||
{sub_group_by === null && (
|
||||
<div className="sticky top-0 z-[2] w-full flex-shrink-0 bg-custom-background-90 py-1">
|
||||
<HeaderGroupByCard
|
||||
sub_group_by={sub_group_by}
|
||||
group_by={group_by}
|
||||
column_id={_list.id}
|
||||
icon={_list.Icon}
|
||||
title={_list.name}
|
||||
count={issueIds?.[_list.id]?.length || 0}
|
||||
kanBanToggle={kanBanToggle}
|
||||
handleKanBanToggle={handleKanBanToggle}
|
||||
issuePayload={_list.payload}
|
||||
disableIssueCreation={disableIssueCreation}
|
||||
currentStore={currentStore}
|
||||
addIssuesToView={addIssuesToView}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
list.map((_list: IKanbanColumn) => {
|
||||
const verticalPosition = verticalAlignPosition(_list);
|
||||
|
||||
<div
|
||||
className={`${
|
||||
verticalAlignPosition(_list) ? `min-h-[150px] w-[0px] overflow-hidden` : `w-full transition-all`
|
||||
}`}
|
||||
>
|
||||
<Droppable droppableId={`${_list.id}__${sub_group_id}`}>
|
||||
{(provided: any, snapshot: any) => (
|
||||
<div
|
||||
className={`relative h-full w-full transition-all ${
|
||||
snapshot.isDraggingOver ? `bg-custom-background-80` : ``
|
||||
}`}
|
||||
{...provided.droppableProps}
|
||||
ref={provided.innerRef}
|
||||
>
|
||||
{issues && !verticalAlignPosition(_list) ? (
|
||||
<KanbanIssueBlocksList
|
||||
sub_group_id={sub_group_id}
|
||||
columnId={_list.id}
|
||||
issues={issues}
|
||||
issueIds={issueIds?.[_list.id] || []}
|
||||
isDragDisabled={isDragDisabled}
|
||||
showEmptyGroup={showEmptyGroup}
|
||||
handleIssues={handleIssues}
|
||||
quickActions={quickActions}
|
||||
displayProperties={displayProperties}
|
||||
canEditProperties={canEditProperties}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{provided.placeholder}
|
||||
</div>
|
||||
)}
|
||||
</Droppable>
|
||||
|
||||
<div className="sticky bottom-0 z-[0] w-full flex-shrink-0 bg-custom-background-90 py-1">
|
||||
{enableQuickIssueCreate && !disableIssueCreation && (
|
||||
<KanBanQuickAddIssueForm
|
||||
formKey="name"
|
||||
groupId={_list.id}
|
||||
subGroupId={sub_group_id}
|
||||
prePopulatedData={{
|
||||
...(group_by && { [group_by]: _list.id }),
|
||||
...(sub_group_by && sub_group_id !== "null" && { [sub_group_by]: sub_group_id }),
|
||||
}}
|
||||
quickAddCallback={quickAddCallback}
|
||||
viewId={viewId}
|
||||
return (
|
||||
<div className={`relative flex flex-shrink-0 flex-col ${!verticalPosition ? `w-[340px]` : ``} group`}>
|
||||
{sub_group_by === null && (
|
||||
<div className="sticky top-0 z-[2] w-full flex-shrink-0 bg-custom-background-90 py-1">
|
||||
<HeaderGroupByCard
|
||||
sub_group_by={sub_group_by}
|
||||
group_by={group_by}
|
||||
column_id={_list.id}
|
||||
icon={_list.Icon}
|
||||
title={_list.name}
|
||||
count={issueIds?.[_list.id]?.length || 0}
|
||||
kanBanToggle={kanBanToggle}
|
||||
handleKanBanToggle={handleKanBanToggle}
|
||||
issuePayload={_list.payload}
|
||||
disableIssueCreation={disableIssueCreation}
|
||||
currentStore={currentStore}
|
||||
addIssuesToView={addIssuesToView}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<KanbanGroup
|
||||
groupId={_list.id}
|
||||
issues={issues}
|
||||
issueIds={issueIds}
|
||||
sub_group_by={sub_group_by}
|
||||
group_by={group_by}
|
||||
sub_group_id={sub_group_id}
|
||||
isDragDisabled={isDragDisabled}
|
||||
handleIssues={handleIssues}
|
||||
showEmptyGroup={showEmptyGroup}
|
||||
quickActions={quickActions}
|
||||
displayProperties={displayProperties}
|
||||
enableQuickIssueCreate={enableQuickIssueCreate}
|
||||
quickAddCallback={quickAddCallback}
|
||||
viewId={viewId}
|
||||
disableIssueCreation={disableIssueCreation}
|
||||
canEditProperties={canEditProperties}
|
||||
verticalPosition={verticalPosition}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
102
web/components/issues/issue-layouts/kanban/kanban-group.tsx
Normal file
102
web/components/issues/issue-layouts/kanban/kanban-group.tsx
Normal file
@ -0,0 +1,102 @@
|
||||
import { Droppable } from "@hello-pangea/dnd";
|
||||
//types
|
||||
import { IIssue, IIssueDisplayProperties, IIssueResponse } from "types";
|
||||
import { EIssueActions } from "../types";
|
||||
//components
|
||||
import { KanBanQuickAddIssueForm, KanbanIssueBlocksList } from ".";
|
||||
|
||||
interface IKanbanGroup {
|
||||
groupId: string;
|
||||
issues: IIssueResponse;
|
||||
issueIds: any;
|
||||
sub_group_by: string | null;
|
||||
group_by: string | null;
|
||||
sub_group_id: string;
|
||||
isDragDisabled: boolean;
|
||||
handleIssues: (issue: IIssue, action: EIssueActions) => void;
|
||||
showEmptyGroup: boolean;
|
||||
quickActions: (issue: IIssue, customActionButton?: React.ReactElement) => React.ReactNode;
|
||||
displayProperties: IIssueDisplayProperties | null;
|
||||
enableQuickIssueCreate?: boolean;
|
||||
quickAddCallback?: (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
data: IIssue,
|
||||
viewId?: string
|
||||
) => Promise<IIssue | undefined>;
|
||||
viewId?: string;
|
||||
disableIssueCreation?: boolean;
|
||||
canEditProperties: (projectId: string | undefined) => boolean;
|
||||
verticalPosition: any;
|
||||
}
|
||||
|
||||
export const KanbanGroup = (props: IKanbanGroup) => {
|
||||
const {
|
||||
groupId,
|
||||
sub_group_id,
|
||||
group_by,
|
||||
sub_group_by,
|
||||
issues,
|
||||
verticalPosition,
|
||||
issueIds,
|
||||
isDragDisabled,
|
||||
showEmptyGroup,
|
||||
handleIssues,
|
||||
quickActions,
|
||||
displayProperties,
|
||||
canEditProperties,
|
||||
enableQuickIssueCreate,
|
||||
disableIssueCreation,
|
||||
quickAddCallback,
|
||||
viewId,
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<div className={`${verticalPosition ? `min-h-[150px] w-[0px] overflow-hidden` : `w-full transition-all`}`}>
|
||||
<Droppable droppableId={`${groupId}__${sub_group_id}`}>
|
||||
{(provided: any, snapshot: any) => (
|
||||
<div
|
||||
className={`relative h-full w-full transition-all ${
|
||||
snapshot.isDraggingOver ? `bg-custom-background-80` : ``
|
||||
}`}
|
||||
{...provided.droppableProps}
|
||||
ref={provided.innerRef}
|
||||
>
|
||||
{issues && !verticalPosition ? (
|
||||
<KanbanIssueBlocksList
|
||||
sub_group_id={sub_group_id}
|
||||
columnId={groupId}
|
||||
issues={issues}
|
||||
issueIds={issueIds?.[groupId] || []}
|
||||
isDragDisabled={isDragDisabled}
|
||||
showEmptyGroup={showEmptyGroup}
|
||||
handleIssues={handleIssues}
|
||||
quickActions={quickActions}
|
||||
displayProperties={displayProperties}
|
||||
canEditProperties={canEditProperties}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{provided.placeholder}
|
||||
</div>
|
||||
)}
|
||||
</Droppable>
|
||||
|
||||
<div className="sticky bottom-0 z-[0] w-full flex-shrink-0 bg-custom-background-90 py-1">
|
||||
{enableQuickIssueCreate && !disableIssueCreation && (
|
||||
<KanBanQuickAddIssueForm
|
||||
formKey="name"
|
||||
groupId={groupId}
|
||||
subGroupId={sub_group_id}
|
||||
prePopulatedData={{
|
||||
...(group_by && { [group_by]: groupId }),
|
||||
...(sub_group_by && sub_group_id !== "null" && { [sub_group_by]: sub_group_id }),
|
||||
}}
|
||||
quickAddCallback={quickAddCallback}
|
||||
viewId={viewId}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -1,14 +1,15 @@
|
||||
import { useRouter } from "next/router";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { useMemo } from "react";
|
||||
// mobx store
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
// components
|
||||
import { ProjectIssueQuickActions } from "components/issues";
|
||||
import { BaseKanBanRoot } from "../base-kanban-root";
|
||||
// types
|
||||
import { IIssue } from "types";
|
||||
// constants
|
||||
import { EIssueActions } from "../../types";
|
||||
import { BaseKanBanRoot } from "../base-kanban-root";
|
||||
import { EProjectStore } from "store_legacy/command-palette.store";
|
||||
import { IGroupedIssues, IIssueResponse, ISubGroupedIssues, TUnGroupedIssues } from "store_legacy/issues/types";
|
||||
|
||||
@ -25,18 +26,21 @@ export const KanBanLayout: React.FC = observer(() => {
|
||||
kanBanHelpers: kanBanHelperStore,
|
||||
} = useMobxStore();
|
||||
|
||||
const issueActions = {
|
||||
[EIssueActions.UPDATE]: async (issue: IIssue) => {
|
||||
if (!workspaceSlug) return;
|
||||
const issueActions = useMemo(
|
||||
() => ({
|
||||
[EIssueActions.UPDATE]: async (issue: IIssue) => {
|
||||
if (!workspaceSlug) return;
|
||||
|
||||
await issueStore.updateIssue(workspaceSlug, issue.project, issue.id, issue);
|
||||
},
|
||||
[EIssueActions.DELETE]: async (issue: IIssue) => {
|
||||
if (!workspaceSlug) return;
|
||||
await issueStore.updateIssue(workspaceSlug, issue.project, issue.id, issue);
|
||||
},
|
||||
[EIssueActions.DELETE]: async (issue: IIssue) => {
|
||||
if (!workspaceSlug) return;
|
||||
|
||||
await issueStore.removeIssue(workspaceSlug, issue.project, issue.id);
|
||||
},
|
||||
};
|
||||
await issueStore.removeIssue(workspaceSlug, issue.project, issue.id);
|
||||
},
|
||||
}),
|
||||
[issueStore]
|
||||
);
|
||||
|
||||
const handleDragDrop = async (
|
||||
source: any,
|
||||
|
@ -1,5 +1,7 @@
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react-lite";
|
||||
//mobx
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
// components
|
||||
import { KanBan } from "./default";
|
||||
import { HeaderSubGroupByCard } from "./headers/sub-group-by-card";
|
||||
@ -11,7 +13,6 @@ import { IIssueResponse, IGroupedIssues, ISubGroupedIssues, TUnGroupedIssues } f
|
||||
import { EIssueActions } from "../types";
|
||||
import { EProjectStore } from "store_legacy/command-palette.store";
|
||||
import { IKanbanColumn, columnTypes, getKanbanColumns } from "./utils";
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
|
||||
interface ISubGroupSwimlaneHeader {
|
||||
issueIds: any;
|
||||
@ -28,29 +29,27 @@ const SubGroupSwimlaneHeader: React.FC<ISubGroupSwimlaneHeader> = ({
|
||||
list,
|
||||
kanBanToggle,
|
||||
handleKanBanToggle,
|
||||
}) => {
|
||||
return (
|
||||
<div className="relative flex h-max min-h-full w-full items-center">
|
||||
{list &&
|
||||
list.length > 0 &&
|
||||
list.map((_list: IKanbanColumn) => (
|
||||
<div key={`${sub_group_by}_${_list.id}`} className="flex w-[340px] flex-shrink-0 flex-col">
|
||||
<HeaderGroupByCard
|
||||
sub_group_by={sub_group_by}
|
||||
group_by={group_by}
|
||||
column_id={_list.id}
|
||||
icon={_list.Icon}
|
||||
title={_list.name}
|
||||
count={issueIds?.[_list.id]?.length || 0}
|
||||
kanBanToggle={kanBanToggle}
|
||||
handleKanBanToggle={handleKanBanToggle}
|
||||
issuePayload={_list.payload}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}) => (
|
||||
<div className="relative flex h-max min-h-full w-full items-center">
|
||||
{list &&
|
||||
list.length > 0 &&
|
||||
list.map((_list: IKanbanColumn) => (
|
||||
<div key={`${sub_group_by}_${_list.id}`} className="flex w-[340px] flex-shrink-0 flex-col">
|
||||
<HeaderGroupByCard
|
||||
sub_group_by={sub_group_by}
|
||||
group_by={group_by}
|
||||
column_id={_list.id}
|
||||
icon={_list.Icon}
|
||||
title={_list.name}
|
||||
count={issueIds?.[_list.id]?.length || 0}
|
||||
kanBanToggle={kanBanToggle}
|
||||
handleKanBanToggle={handleKanBanToggle}
|
||||
issuePayload={_list.payload}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
||||
interface ISubGroupSwimlane extends ISubGroupSwimlaneHeader {
|
||||
issues: IIssueResponse;
|
||||
|
@ -51,62 +51,54 @@ const getProjectColumns = (project: IProjectStore): IKanbanColumn[] | undefined
|
||||
|
||||
if (!projects) return;
|
||||
|
||||
return projects.map((project) => {
|
||||
return {
|
||||
id: project.id,
|
||||
name: project.name,
|
||||
Icon: <div className="w-6 h-6">{renderEmoji(project.emoji || "")}</div>,
|
||||
payload: { project: project.id },
|
||||
};
|
||||
});
|
||||
return projects.map((project) => ({
|
||||
id: project.id,
|
||||
name: project.name,
|
||||
Icon: <div className="w-6 h-6">{renderEmoji(project.emoji || "")}</div>,
|
||||
payload: { project: project.id },
|
||||
}));
|
||||
};
|
||||
|
||||
const getStateColumns = (projectState: IProjectStateStore): IKanbanColumn[] | undefined => {
|
||||
const { projectStates } = projectState;
|
||||
if (!projectStates) return;
|
||||
|
||||
return projectStates.map((state) => {
|
||||
return {
|
||||
id: state.id,
|
||||
name: state.name,
|
||||
Icon: (
|
||||
<div className="w-3.5 h-3.5 rounded-full">
|
||||
<StateGroupIcon stateGroup={state.group} color={state.color} width="14" height="14" />
|
||||
</div>
|
||||
),
|
||||
payload: { state: state.id },
|
||||
};
|
||||
});
|
||||
return projectStates.map((state) => ({
|
||||
id: state.id,
|
||||
name: state.name,
|
||||
Icon: (
|
||||
<div className="w-3.5 h-3.5 rounded-full">
|
||||
<StateGroupIcon stateGroup={state.group} color={state.color} width="14" height="14" />
|
||||
</div>
|
||||
),
|
||||
payload: { state: state.id },
|
||||
}));
|
||||
};
|
||||
|
||||
const getStateGroupColumns = () => {
|
||||
const stateGroups = ISSUE_STATE_GROUPS;
|
||||
|
||||
return stateGroups.map((stateGroup) => {
|
||||
return {
|
||||
id: stateGroup.key,
|
||||
name: stateGroup.title,
|
||||
Icon: (
|
||||
<div className="w-3.5 h-3.5 rounded-full">
|
||||
<StateGroupIcon stateGroup={stateGroup.key} width="14" height="14" />
|
||||
</div>
|
||||
),
|
||||
payload: {},
|
||||
};
|
||||
});
|
||||
return stateGroups.map((stateGroup) => ({
|
||||
id: stateGroup.key,
|
||||
name: stateGroup.title,
|
||||
Icon: (
|
||||
<div className="w-3.5 h-3.5 rounded-full">
|
||||
<StateGroupIcon stateGroup={stateGroup.key} width="14" height="14" />
|
||||
</div>
|
||||
),
|
||||
payload: {},
|
||||
}));
|
||||
};
|
||||
|
||||
const getPriorityColumns = () => {
|
||||
const priorities = ISSUE_PRIORITIES;
|
||||
|
||||
return priorities.map((priority) => {
|
||||
return {
|
||||
id: priority.key,
|
||||
name: priority.title,
|
||||
Icon: <PriorityIcon priority={priority?.key} />,
|
||||
payload: { priority: priority.key },
|
||||
};
|
||||
});
|
||||
return priorities.map((priority) => ({
|
||||
id: priority.key,
|
||||
name: priority.title,
|
||||
Icon: <PriorityIcon priority={priority?.key} />,
|
||||
payload: { priority: priority.key },
|
||||
}));
|
||||
};
|
||||
|
||||
const getLabelsColumns = (projectLabel: IProjectLabelStore) => {
|
||||
@ -116,19 +108,14 @@ const getLabelsColumns = (projectLabel: IProjectLabelStore) => {
|
||||
|
||||
const labels = [...projectLabels, { id: "None", name: "None", color: "#666" }];
|
||||
|
||||
return labels.map((label) => {
|
||||
return {
|
||||
id: label.id,
|
||||
name: label.name,
|
||||
Icon: (
|
||||
<div
|
||||
className="w-[12px] h-[12px] rounded-full"
|
||||
style={{ backgroundColor: label.color ? label.color : "#666" }}
|
||||
/>
|
||||
),
|
||||
payload: { labels: [label.id] },
|
||||
};
|
||||
});
|
||||
return labels.map((label) => ({
|
||||
id: label.id,
|
||||
name: label.name,
|
||||
Icon: (
|
||||
<div className="w-[12px] h-[12px] rounded-full" style={{ backgroundColor: label.color ? label.color : "#666" }} />
|
||||
),
|
||||
payload: { labels: [label.id] },
|
||||
}));
|
||||
};
|
||||
|
||||
const getAssigneeColumns = (projectMember: IProjectMemberStore) => {
|
||||
|
Loading…
Reference in New Issue
Block a user