diff --git a/web/components/issues/issue-layouts/filters/applied-filters/filters-list.tsx b/web/components/issues/issue-layouts/filters/applied-filters/filters-list.tsx index 2f98b67f4..83c072ede 100644 --- a/web/components/issues/issue-layouts/filters/applied-filters/filters-list.tsx +++ b/web/components/issues/issue-layouts/filters/applied-filters/filters-list.tsx @@ -27,7 +27,7 @@ type Props = { states?: IStateResponse | undefined; }; -const membersFilters = ["assignees", "mentions" ,"created_by", "subscriber"]; +const membersFilters = ["assignees", "mentions", "created_by", "subscriber"]; const dateFilters = ["start_date", "target_date"]; export const AppliedFiltersList: React.FC = observer((props) => { diff --git a/web/components/issues/issue-layouts/kanban/block.tsx b/web/components/issues/issue-layouts/kanban/block.tsx index d72e93a8d..34ed02382 100644 --- a/web/components/issues/issue-layouts/kanban/block.tsx +++ b/web/components/issues/issue-layouts/kanban/block.tsx @@ -12,6 +12,7 @@ interface IssueBlockProps { index: number; issue: IIssue; isDragDisabled: boolean; + showEmptyGroup: boolean; handleIssues: ( sub_group_by: string | null, group_by: string | null, @@ -23,7 +24,17 @@ interface IssueBlockProps { } export const KanbanIssueBlock: React.FC = (props) => { - const { sub_group_id, columnId, index, issue, isDragDisabled, handleIssues, quickActions, displayProperties } = props; + const { + sub_group_id, + columnId, + index, + issue, + isDragDisabled, + showEmptyGroup, + handleIssues, + quickActions, + displayProperties, + } = props; const updateIssue = (sub_group_by: string | null, group_by: string | null, issueToUpdate: IIssue) => { if (issueToUpdate) handleIssues(sub_group_by, group_by, issueToUpdate, "update"); @@ -83,6 +94,7 @@ export const KanbanIssueBlock: React.FC = (props) => { issue={issue} handleIssues={updateIssue} displayProperties={displayProperties} + showEmptyGroup={showEmptyGroup} /> diff --git a/web/components/issues/issue-layouts/kanban/blocks-list.tsx b/web/components/issues/issue-layouts/kanban/blocks-list.tsx index b167df709..ea1b4c840 100644 --- a/web/components/issues/issue-layouts/kanban/blocks-list.tsx +++ b/web/components/issues/issue-layouts/kanban/blocks-list.tsx @@ -7,6 +7,7 @@ interface IssueBlocksListProps { columnId: string; issues: IIssue[]; isDragDisabled: boolean; + showEmptyGroup: boolean; handleIssues: ( sub_group_by: string | null, group_by: string | null, @@ -18,7 +19,16 @@ interface IssueBlocksListProps { } export const KanbanIssueBlocksList: React.FC = (props) => { - const { sub_group_id, columnId, issues, isDragDisabled, handleIssues, quickActions, displayProperties } = props; + const { + sub_group_id, + columnId, + issues, + showEmptyGroup, + isDragDisabled, + handleIssues, + quickActions, + displayProperties, + } = props; return ( <> @@ -29,6 +39,7 @@ export const KanbanIssueBlocksList: React.FC = (props) => key={`kanban-issue-block-${issue.id}`} index={index} issue={issue} + showEmptyGroup={showEmptyGroup} handleIssues={handleIssues} quickActions={quickActions} displayProperties={displayProperties} diff --git a/web/components/issues/issue-layouts/kanban/default.tsx b/web/components/issues/issue-layouts/kanban/default.tsx index 8f000e56f..79b8a7d07 100644 --- a/web/components/issues/issue-layouts/kanban/default.tsx +++ b/web/components/issues/issue-layouts/kanban/default.tsx @@ -9,7 +9,7 @@ import { KanbanIssueBlocksList, BoardInlineCreateIssueForm } from "components/is // types import { IIssueDisplayProperties, IIssue } from "types"; // constants -import { ISSUE_STATE_GROUPS, ISSUE_PRIORITIES, getValueFromObject } from "constants/issue"; +import { getValueFromObject } from "constants/issue"; export interface IGroupByKanBan { issues: any; @@ -25,6 +25,7 @@ export interface IGroupByKanBan { issue: IIssue, action: "update" | "delete" ) => void; + showEmptyGroup: boolean; quickActions: (sub_group_by: string | null, group_by: string | null, issue: IIssue) => React.ReactNode; displayProperties: IIssueDisplayProperties; kanBanToggle: any; @@ -42,6 +43,7 @@ const GroupByKanBan: React.FC = observer((props) => { listKey, isDragDisabled, handleIssues, + showEmptyGroup, quickActions, displayProperties, kanBanToggle, @@ -92,6 +94,7 @@ const GroupByKanBan: React.FC = observer((props) => { columnId={getValueFromObject(_list, listKey) as string} issues={issues[getValueFromObject(_list, listKey) as string]} isDragDisabled={isDragDisabled} + showEmptyGroup={showEmptyGroup} handleIssues={handleIssues} quickActions={quickActions} displayProperties={displayProperties} @@ -140,6 +143,13 @@ export interface IKanBan { displayProperties: IIssueDisplayProperties; kanBanToggle: any; handleKanBanToggle: any; + showEmptyGroup: boolean; + states: any; + stateGroups: any; + priorities: any; + labels: any; + members: any; + projects: any; enableQuickIssueCreate?: boolean; } @@ -154,22 +164,50 @@ export const KanBan: React.FC = observer((props) => { displayProperties, kanBanToggle, handleKanBanToggle, + showEmptyGroup, + states, + stateGroups, + priorities, + labels, + members, + projects, enableQuickIssueCreate, } = props; - const { project: projectStore, issueKanBanView: issueKanBanViewStore } = useMobxStore(); + const { issueKanBanView: issueKanBanViewStore } = useMobxStore(); return (
+ {/* TODO: have to implement */} + {group_by && group_by === "projects" && ( + + )} + {group_by && group_by === "state" && ( = observer((props) => { group_by={group_by} sub_group_by={sub_group_by} sub_group_id={sub_group_id} - list={ISSUE_STATE_GROUPS} + list={stateGroups} listKey={`key`} isDragDisabled={!issueKanBanViewStore?.canUserDragDrop} + showEmptyGroup={showEmptyGroup} handleIssues={handleIssues} quickActions={quickActions} displayProperties={displayProperties} @@ -203,9 +242,10 @@ export const KanBan: React.FC = observer((props) => { group_by={group_by} sub_group_by={sub_group_by} sub_group_id={sub_group_id} - list={ISSUE_PRIORITIES} + list={priorities} listKey={`key`} isDragDisabled={!issueKanBanViewStore?.canUserDragDrop} + showEmptyGroup={showEmptyGroup} handleIssues={handleIssues} quickActions={quickActions} displayProperties={displayProperties} @@ -221,9 +261,10 @@ export const KanBan: React.FC = observer((props) => { group_by={group_by} sub_group_by={sub_group_by} sub_group_id={sub_group_id} - list={projectStore?.projectLabels} + list={labels ? [...labels, { id: "None", name: "None" }] : labels} listKey={`id`} isDragDisabled={!issueKanBanViewStore?.canUserDragDrop} + showEmptyGroup={showEmptyGroup} handleIssues={handleIssues} quickActions={quickActions} displayProperties={displayProperties} @@ -239,9 +280,10 @@ export const KanBan: React.FC = observer((props) => { group_by={group_by} sub_group_by={sub_group_by} sub_group_id={sub_group_id} - list={projectStore?.projectMembers} - listKey={`member.id`} + list={members ? [...members, { id: "None", display_name: "None" }] : members} + listKey={`id`} isDragDisabled={!issueKanBanViewStore?.canUserDragDrop} + showEmptyGroup={showEmptyGroup} handleIssues={handleIssues} quickActions={quickActions} displayProperties={displayProperties} @@ -257,9 +299,10 @@ export const KanBan: React.FC = observer((props) => { group_by={group_by} sub_group_by={sub_group_by} sub_group_id={sub_group_id} - list={projectStore?.projectMembers} - listKey={`member.id`} + list={members} + listKey={`id`} isDragDisabled={!issueKanBanViewStore?.canUserDragDrop} + showEmptyGroup={showEmptyGroup} handleIssues={handleIssues} quickActions={quickActions} displayProperties={displayProperties} diff --git a/web/components/issues/issue-layouts/kanban/headers/assignee.tsx b/web/components/issues/issue-layouts/kanban/headers/assignee.tsx index 231d9e44a..d350ca90b 100644 --- a/web/components/issues/issue-layouts/kanban/headers/assignee.tsx +++ b/web/components/issues/issue-layouts/kanban/headers/assignee.tsx @@ -39,8 +39,8 @@ export const AssigneesHeader: FC = observer((props) => { (sub_group_by && header_type === "sub_group_by" ? ( } - title={assignee?.member?.display_name || ""} + icon={} + title={assignee?.display_name || ""} count={issues_count} kanBanToggle={kanBanToggle} handleKanBanToggle={handleKanBanToggle} @@ -50,12 +50,12 @@ export const AssigneesHeader: FC = observer((props) => { sub_group_by={sub_group_by} group_by={group_by} column_id={column_id} - icon={} - title={assignee?.member?.display_name || ""} + icon={} + title={assignee?.display_name || ""} count={issues_count} kanBanToggle={kanBanToggle} handleKanBanToggle={handleKanBanToggle} - issuePayload={{ assignees: [assignee?.member?.id] }} + issuePayload={{ assignees: [assignee?.id] }} /> ))} diff --git a/web/components/issues/issue-layouts/kanban/headers/created_by.tsx b/web/components/issues/issue-layouts/kanban/headers/created_by.tsx index 660fb7bd6..dde2059a9 100644 --- a/web/components/issues/issue-layouts/kanban/headers/created_by.tsx +++ b/web/components/issues/issue-layouts/kanban/headers/created_by.tsx @@ -36,8 +36,8 @@ export const CreatedByHeader: FC = observer((props) => { (sub_group_by && header_type === "sub_group_by" ? ( } - title={createdBy?.member?.display_name || ""} + icon={} + title={createdBy?.display_name || ""} count={issues_count} kanBanToggle={kanBanToggle} handleKanBanToggle={handleKanBanToggle} @@ -47,12 +47,12 @@ export const CreatedByHeader: FC = observer((props) => { sub_group_by={sub_group_by} group_by={group_by} column_id={column_id} - icon={} - title={createdBy?.member?.display_name || ""} + icon={} + title={createdBy?.display_name || ""} count={issues_count} kanBanToggle={kanBanToggle} handleKanBanToggle={handleKanBanToggle} - issuePayload={{ created_by: createdBy?.member?.id }} + issuePayload={{ created_by: createdBy?.id }} /> ))} diff --git a/web/components/issues/issue-layouts/kanban/properties.tsx b/web/components/issues/issue-layouts/kanban/properties.tsx index 27468346e..a17947550 100644 --- a/web/components/issues/issue-layouts/kanban/properties.tsx +++ b/web/components/issues/issue-layouts/kanban/properties.tsx @@ -18,10 +18,11 @@ export interface IKanBanProperties { issue: IIssue; handleIssues: (sub_group_by: string | null, group_by: string | null, issue: IIssue) => void; displayProperties: IIssueDisplayProperties; + showEmptyGroup: boolean; } export const KanBanProperties: React.FC = observer((props) => { - const { sub_group_id, columnId: group_id, issue, handleIssues, displayProperties } = props; + const { sub_group_id, columnId: group_id, issue, handleIssues, displayProperties, showEmptyGroup } = props; const handleState = (state: IState) => { handleIssues( @@ -104,7 +105,7 @@ export const KanBanProperties: React.FC = observer((props) => )} {/* label */} - {displayProperties && displayProperties?.labels && ( + {displayProperties && displayProperties?.labels && (showEmptyGroup || issue?.labels.length > 0) && ( = observer((props) => )} {/* start date */} - {displayProperties && displayProperties?.start_date && ( + {displayProperties && displayProperties?.start_date && (showEmptyGroup || issue?.start_date) && ( handleStartDate(date)} @@ -125,7 +126,7 @@ export const KanBanProperties: React.FC = observer((props) => )} {/* target/due date */} - {displayProperties && displayProperties?.due_date && ( + {displayProperties && displayProperties?.due_date && (showEmptyGroup || issue?.target_date) && ( handleTargetDate(date)} @@ -177,7 +178,7 @@ export const KanBanProperties: React.FC = observer((props) => )} {/* assignee */} - {displayProperties && displayProperties?.assignee && ( + {displayProperties && displayProperties?.assignee && (showEmptyGroup || issue?.assignees.length > 0) && ( { const group_by: string | null = issueFilterStore?.userDisplayFilters?.group_by || null; + const userDisplayFilters = issueFilterStore?.userDisplayFilters || null; + const displayProperties = issueFilterStore?.userDisplayProperties || null; const currentKanBanView: "swimlanes" | "default" = issueFilterStore?.userDisplayFilters?.sub_group_by @@ -116,6 +118,13 @@ export const CycleKanBanLayout: React.FC = observer(() => { displayProperties={displayProperties} kanBanToggle={cycleIssueKanBanViewStore?.kanBanToggle} handleKanBanToggle={handleKanBanToggle} + states={states} + stateGroups={stateGroups} + priorities={priorities} + labels={labels} + members={members?.map((m) => m.member) ?? null} + projects={projects} + showEmptyGroup={userDisplayFilters?.show_empty_groups || true} /> ) : ( { labels={labels} members={members?.map((m) => m.member) ?? null} projects={projects} - estimates={estimates?.points ? orderArrayBy(estimates.points, "key") : null} + showEmptyGroup={userDisplayFilters?.show_empty_groups || true} /> )} diff --git a/web/components/issues/issue-layouts/kanban/roots/module-root.tsx b/web/components/issues/issue-layouts/kanban/roots/module-root.tsx index 8360902ae..be40c6bca 100644 --- a/web/components/issues/issue-layouts/kanban/roots/module-root.tsx +++ b/web/components/issues/issue-layouts/kanban/roots/module-root.tsx @@ -36,6 +36,8 @@ export const ModuleKanBanLayout: React.FC = observer(() => { const group_by: string | null = issueFilterStore?.userDisplayFilters?.group_by || null; + const userDisplayFilters = issueFilterStore?.userDisplayFilters || null; + const displayProperties = issueFilterStore?.userDisplayProperties || null; const currentKanBanView: "swimlanes" | "default" = issueFilterStore?.userDisplayFilters?.sub_group_by @@ -115,6 +117,13 @@ export const ModuleKanBanLayout: React.FC = observer(() => { displayProperties={displayProperties} kanBanToggle={moduleIssueKanBanViewStore?.kanBanToggle} handleKanBanToggle={handleKanBanToggle} + states={states} + stateGroups={stateGroups} + priorities={priorities} + labels={labels} + members={members?.map((m) => m.member) ?? null} + projects={projects} + showEmptyGroup={userDisplayFilters?.show_empty_groups || true} /> ) : ( { labels={labels} members={members?.map((m) => m.member) ?? null} projects={projects} - estimates={estimates?.points ? orderArrayBy(estimates.points, "key") : null} + showEmptyGroup={userDisplayFilters?.show_empty_groups || true} /> )} diff --git a/web/components/issues/issue-layouts/kanban/roots/profile-issues-root.tsx b/web/components/issues/issue-layouts/kanban/roots/profile-issues-root.tsx index b65669da9..2849315b4 100644 --- a/web/components/issues/issue-layouts/kanban/roots/profile-issues-root.tsx +++ b/web/components/issues/issue-layouts/kanban/roots/profile-issues-root.tsx @@ -34,6 +34,8 @@ export const ProfileIssuesKanBanLayout: FC = observer(() => { const group_by: string | null = profileIssueFiltersStore?.userDisplayFilters?.group_by || null; + const userDisplayFilters = profileIssueFiltersStore?.userDisplayFilters || null; + const displayProperties = profileIssueFiltersStore?.userDisplayProperties || null; const currentKanBanView: "swimlanes" | "default" = profileIssueFiltersStore?.userDisplayFilters?.sub_group_by @@ -99,6 +101,13 @@ export const ProfileIssuesKanBanLayout: FC = observer(() => { displayProperties={displayProperties} kanBanToggle={issueKanBanViewStore?.kanBanToggle} handleKanBanToggle={handleKanBanToggle} + states={states} + stateGroups={stateGroups} + priorities={priorities} + labels={labels} + members={members?.map((m) => m.member) ?? null} + projects={projects} + showEmptyGroup={userDisplayFilters?.show_empty_groups || true} /> ) : ( { labels={labels} members={members?.map((m) => m.member) ?? null} projects={projects} - estimates={null} + showEmptyGroup={userDisplayFilters?.show_empty_groups || true} /> )} diff --git a/web/components/issues/issue-layouts/kanban/roots/project-root.tsx b/web/components/issues/issue-layouts/kanban/roots/project-root.tsx index 999f013f5..179d628b4 100644 --- a/web/components/issues/issue-layouts/kanban/roots/project-root.tsx +++ b/web/components/issues/issue-layouts/kanban/roots/project-root.tsx @@ -8,8 +8,6 @@ import { useMobxStore } from "lib/mobx/store-provider"; import { KanBanSwimLanes } from "../swimlanes"; import { KanBan } from "../default"; import { ProjectIssueQuickActions } from "components/issues"; -// helpers -import { orderArrayBy } from "helpers/array.helper"; // types import { IIssue } from "types"; // constants @@ -19,7 +17,7 @@ export interface IKanBanLayout {} export const KanBanLayout: React.FC = observer(() => { const router = useRouter(); - const { workspaceSlug } = router.query; + const { workspaceSlug } = router.query as { workspaceSlug: string }; const { project: projectStore, @@ -36,6 +34,8 @@ export const KanBanLayout: React.FC = observer(() => { const group_by: string | null = issueFilterStore?.userDisplayFilters?.group_by || null; + const userDisplayFilters = issueFilterStore?.userDisplayFilters || null; + const displayProperties = issueFilterStore?.userDisplayProperties || null; const currentKanBanView: "swimlanes" | "default" = issueFilterStore?.userDisplayFilters?.sub_group_by @@ -80,7 +80,7 @@ export const KanBanLayout: React.FC = observer(() => { const labels = projectStore?.projectLabels || null; const members = projectStore?.projectMembers || null; const stateGroups = ISSUE_STATE_GROUPS || null; - const projects = workspaceSlug ? projectStore?.projects[workspaceSlug.toString()] || null : null; + const projects = workspaceSlug ? projectStore?.projects?.[workspaceSlug] || null : null; const estimates = currentProjectDetails?.estimate !== null ? projectStore.projectEstimates?.find((e) => e.id === currentProjectDetails?.estimate) || null @@ -105,7 +105,14 @@ export const KanBanLayout: React.FC = observer(() => { displayProperties={displayProperties} kanBanToggle={issueKanBanViewStore?.kanBanToggle} handleKanBanToggle={handleKanBanToggle} + states={states} + stateGroups={stateGroups} + priorities={priorities} + labels={labels} + members={members?.map((m) => m.member) ?? null} + projects={projects} enableQuickIssueCreate + showEmptyGroup={userDisplayFilters?.show_empty_groups || true} /> ) : ( { labels={labels} members={members?.map((m) => m.member) ?? null} projects={projects} - estimates={estimates?.points ? orderArrayBy(estimates.points, "key") : null} + showEmptyGroup={userDisplayFilters?.show_empty_groups || true} /> )} diff --git a/web/components/issues/issue-layouts/kanban/swimlanes.tsx b/web/components/issues/issue-layouts/kanban/swimlanes.tsx index d31f29f86..7acfdf625 100644 --- a/web/components/issues/issue-layouts/kanban/swimlanes.tsx +++ b/web/components/issues/issue-layouts/kanban/swimlanes.tsx @@ -1,15 +1,13 @@ import React from "react"; import { observer } from "mobx-react-lite"; -// mobx store -import { useMobxStore } from "lib/mobx/store-provider"; // components import { KanBanGroupByHeaderRoot } from "./headers/group-by-root"; import { KanBanSubGroupByHeaderRoot } from "./headers/sub-group-by-root"; import { KanBan } from "./default"; // types -import { IEstimatePoint, IIssue, IIssueDisplayProperties, IIssueLabels, IProject, IState, IUserLite } from "types"; +import { IIssue, IIssueDisplayProperties, IIssueLabels, IProject, IState, IUserLite } from "types"; // constants -import { ISSUE_STATE_GROUPS, ISSUE_PRIORITIES, getValueFromObject } from "constants/issue"; +import { getValueFromObject } from "constants/issue"; interface ISubGroupSwimlaneHeader { issues: any; @@ -19,11 +17,6 @@ interface ISubGroupSwimlaneHeader { listKey: string; kanBanToggle: any; handleKanBanToggle: any; - states: IState[] | null; - labels: IIssueLabels[] | null; - members: IUserLite[] | null; - projects: IProject[] | null; - estimates: IEstimatePoint[] | null; } const SubGroupSwimlaneHeader: React.FC = ({ issues, @@ -65,6 +58,13 @@ const SubGroupSwimlaneHeader: React.FC = ({ }; interface ISubGroupSwimlane extends ISubGroupSwimlaneHeader { + showEmptyGroup: boolean; + states: IState[] | null; + stateGroups: any; + priorities: any; + labels: IIssueLabels[] | null; + members: IUserLite[] | null; + projects: IProject[] | null; issues: any; handleIssues: ( sub_group_by: string | null, @@ -76,13 +76,6 @@ interface ISubGroupSwimlane extends ISubGroupSwimlaneHeader { displayProperties: IIssueDisplayProperties; kanBanToggle: any; handleKanBanToggle: any; - states: IState[] | null; - stateGroups: any; - priorities: any; - labels: IIssueLabels[] | null; - members: IUserLite[] | null; - projects: IProject[] | null; - estimates: IEstimatePoint[] | null; } const SubGroupSwimlane: React.FC = observer((props) => { const { @@ -96,13 +89,13 @@ const SubGroupSwimlane: React.FC = observer((props) => { displayProperties, kanBanToggle, handleKanBanToggle, + showEmptyGroup, states, stateGroups, priorities, labels, members, projects, - estimates, } = props; const calculateIssueCount = (column_id: string) => { @@ -146,6 +139,13 @@ const SubGroupSwimlane: React.FC = observer((props) => { displayProperties={displayProperties} kanBanToggle={kanBanToggle} handleKanBanToggle={handleKanBanToggle} + showEmptyGroup={showEmptyGroup} + states={states} + stateGroups={stateGroups} + priorities={priorities} + labels={labels} + members={members} + projects={projects} enableQuickIssueCreate />
@@ -170,13 +170,13 @@ export interface IKanBanSwimLanes { displayProperties: IIssueDisplayProperties; kanBanToggle: any; handleKanBanToggle: any; + showEmptyGroup: boolean; states: IState[] | null; stateGroups: any; priorities: any; labels: IIssueLabels[] | null; members: IUserLite[] | null; projects: IProject[] | null; - estimates: IEstimatePoint[] | null; } export const KanBanSwimLanes: React.FC = observer((props) => { @@ -189,34 +189,39 @@ export const KanBanSwimLanes: React.FC = observer((props) => { displayProperties, kanBanToggle, handleKanBanToggle, + showEmptyGroup, states, stateGroups, priorities, labels, members, projects, - estimates, } = props; - const { project: projectStore } = useMobxStore(); - return (
+ {group_by && group_by === "project" && ( + + )} + {group_by && group_by === "state" && ( )} @@ -225,15 +230,10 @@ export const KanBanSwimLanes: React.FC = observer((props) => { issues={issues} sub_group_by={sub_group_by} group_by={group_by} - list={ISSUE_STATE_GROUPS} + list={stateGroups} listKey={`key`} kanBanToggle={kanBanToggle} handleKanBanToggle={handleKanBanToggle} - states={states} - labels={labels} - members={members} - projects={projects} - estimates={estimates} /> )} @@ -242,15 +242,10 @@ export const KanBanSwimLanes: React.FC = observer((props) => { issues={issues} sub_group_by={sub_group_by} group_by={group_by} - list={ISSUE_PRIORITIES} + list={priorities} listKey={`key`} kanBanToggle={kanBanToggle} handleKanBanToggle={handleKanBanToggle} - states={states} - labels={labels} - members={members} - projects={projects} - estimates={estimates} /> )} @@ -259,15 +254,10 @@ export const KanBanSwimLanes: React.FC = observer((props) => { issues={issues} sub_group_by={sub_group_by} group_by={group_by} - list={projectStore?.projectLabels} + list={labels ? [...labels, { id: "None", name: "None" }] : labels} listKey={`id`} kanBanToggle={kanBanToggle} handleKanBanToggle={handleKanBanToggle} - states={states} - labels={labels} - members={members} - projects={projects} - estimates={estimates} /> )} @@ -276,15 +266,10 @@ export const KanBanSwimLanes: React.FC = observer((props) => { issues={issues} sub_group_by={sub_group_by} group_by={group_by} - list={projectStore?.projectMembers} - listKey={`member.id`} + list={members ? [...members, { id: "None", display_name: "None" }] : members} + listKey={`id`} kanBanToggle={kanBanToggle} handleKanBanToggle={handleKanBanToggle} - states={states} - labels={labels} - members={members} - projects={projects} - estimates={estimates} /> )} @@ -293,15 +278,10 @@ export const KanBanSwimLanes: React.FC = observer((props) => { issues={issues} sub_group_by={sub_group_by} group_by={group_by} - list={projectStore?.projectMembers} - listKey={`member.id`} + list={members} + listKey={`id`} kanBanToggle={kanBanToggle} handleKanBanToggle={handleKanBanToggle} - states={states} - labels={labels} - members={members} - projects={projects} - estimates={estimates} /> )}
@@ -311,20 +291,42 @@ export const KanBanSwimLanes: React.FC = observer((props) => { issues={issues} sub_group_by={sub_group_by} group_by={group_by} - list={projectStore?.projectStates} + list={states} listKey={`id`} handleIssues={handleIssues} quickActions={quickActions} displayProperties={displayProperties} kanBanToggle={kanBanToggle} handleKanBanToggle={handleKanBanToggle} + showEmptyGroup={showEmptyGroup} + states={states} + stateGroups={stateGroups} + priorities={priorities} + labels={labels} + members={members} + projects={projects} + /> + )} + + {sub_group_by && sub_group_by === "state" && ( + )} @@ -333,20 +335,20 @@ export const KanBanSwimLanes: React.FC = observer((props) => { issues={issues} sub_group_by={sub_group_by} group_by={group_by} - list={ISSUE_STATE_GROUPS} + list={stateGroups} listKey={`key`} handleIssues={handleIssues} quickActions={quickActions} displayProperties={displayProperties} kanBanToggle={kanBanToggle} handleKanBanToggle={handleKanBanToggle} + showEmptyGroup={showEmptyGroup} states={states} stateGroups={stateGroups} priorities={priorities} labels={labels} members={members} projects={projects} - estimates={estimates} /> )} @@ -355,20 +357,20 @@ export const KanBanSwimLanes: React.FC = observer((props) => { issues={issues} sub_group_by={sub_group_by} group_by={group_by} - list={ISSUE_PRIORITIES} + list={priorities} listKey={`key`} handleIssues={handleIssues} quickActions={quickActions} displayProperties={displayProperties} kanBanToggle={kanBanToggle} handleKanBanToggle={handleKanBanToggle} + showEmptyGroup={showEmptyGroup} states={states} stateGroups={stateGroups} priorities={priorities} labels={labels} members={members} projects={projects} - estimates={estimates} /> )} @@ -377,20 +379,20 @@ export const KanBanSwimLanes: React.FC = observer((props) => { issues={issues} sub_group_by={sub_group_by} group_by={group_by} - list={projectStore?.projectLabels} + list={labels ? [...labels, { id: "None", name: "None" }] : labels} listKey={`id`} handleIssues={handleIssues} quickActions={quickActions} displayProperties={displayProperties} kanBanToggle={kanBanToggle} handleKanBanToggle={handleKanBanToggle} + showEmptyGroup={showEmptyGroup} states={states} stateGroups={stateGroups} priorities={priorities} labels={labels} members={members} projects={projects} - estimates={estimates} /> )} @@ -399,20 +401,20 @@ export const KanBanSwimLanes: React.FC = observer((props) => { issues={issues} sub_group_by={sub_group_by} group_by={group_by} - list={projectStore?.projectMembers} - listKey={`member.id`} + list={members ? [...members, { id: "None", display_name: "None" }] : members} + listKey={`id`} handleIssues={handleIssues} quickActions={quickActions} displayProperties={displayProperties} kanBanToggle={kanBanToggle} handleKanBanToggle={handleKanBanToggle} + showEmptyGroup={showEmptyGroup} states={states} stateGroups={stateGroups} priorities={priorities} labels={labels} members={members} projects={projects} - estimates={estimates} /> )} @@ -421,20 +423,20 @@ export const KanBanSwimLanes: React.FC = observer((props) => { issues={issues} sub_group_by={sub_group_by} group_by={group_by} - list={projectStore?.projectMembers} - listKey={`member.id`} + list={members} + listKey={`id`} handleIssues={handleIssues} quickActions={quickActions} displayProperties={displayProperties} kanBanToggle={kanBanToggle} handleKanBanToggle={handleKanBanToggle} + showEmptyGroup={showEmptyGroup} states={states} stateGroups={stateGroups} priorities={priorities} labels={labels} members={members} projects={projects} - estimates={estimates} /> )}
diff --git a/web/components/issues/issue-layouts/list/block.tsx b/web/components/issues/issue-layouts/list/block.tsx index 2cccbd339..80ebea869 100644 --- a/web/components/issues/issue-layouts/list/block.tsx +++ b/web/components/issues/issue-layouts/list/block.tsx @@ -12,10 +12,11 @@ interface IssueBlockProps { handleIssues: (group_by: string | null, issue: IIssue, action: "update" | "delete") => void; quickActions: (group_by: string | null, issue: IIssue) => React.ReactNode; display_properties: any; + showEmptyGroup?: boolean; } export const IssueBlock: React.FC = (props) => { - const { columnId, issue, handleIssues, quickActions, display_properties } = props; + const { columnId, issue, handleIssues, quickActions, display_properties, showEmptyGroup } = props; const updateIssue = (group_by: string | null, issueToUpdate: IIssue) => { handleIssues(group_by, issueToUpdate, "update"); @@ -51,6 +52,7 @@ export const IssueBlock: React.FC = (props) => { issue={issue} handleIssues={updateIssue} display_properties={display_properties} + showEmptyGroup={showEmptyGroup} /> {quickActions(!columnId && columnId === "null" ? null : columnId, issue)} diff --git a/web/components/issues/issue-layouts/list/blocks-list.tsx b/web/components/issues/issue-layouts/list/blocks-list.tsx index 31bba3bed..de5cf908c 100644 --- a/web/components/issues/issue-layouts/list/blocks-list.tsx +++ b/web/components/issues/issue-layouts/list/blocks-list.tsx @@ -10,10 +10,11 @@ interface Props { handleIssues: (group_by: string | null, issue: IIssue, action: "update" | "delete") => void; quickActions: (group_by: string | null, issue: IIssue) => React.ReactNode; display_properties: any; + showEmptyGroup?: boolean; } export const IssueBlocksList: FC = (props) => { - const { columnId, issues, handleIssues, quickActions, display_properties } = props; + const { columnId, issues, handleIssues, quickActions, display_properties, showEmptyGroup } = props; return (
@@ -26,6 +27,7 @@ export const IssueBlocksList: FC = (props) => { handleIssues={handleIssues} quickActions={quickActions} display_properties={display_properties} + showEmptyGroup={showEmptyGroup} /> )) ) : ( diff --git a/web/components/issues/issue-layouts/list/default.tsx b/web/components/issues/issue-layouts/list/default.tsx index 3c3f90cf8..54d847f71 100644 --- a/web/components/issues/issue-layouts/list/default.tsx +++ b/web/components/issues/issue-layouts/list/default.tsx @@ -18,6 +18,7 @@ export interface IGroupByList { display_properties: any; is_list?: boolean; enableQuickIssueCreate?: boolean; + showEmptyGroup?: boolean; } const GroupByList: React.FC = observer((props) => { @@ -31,6 +32,7 @@ const GroupByList: React.FC = observer((props) => { display_properties, is_list = false, enableQuickIssueCreate, + showEmptyGroup, } = props; return ( @@ -56,6 +58,7 @@ const GroupByList: React.FC = observer((props) => { handleIssues={handleIssues} quickActions={quickActions} display_properties={display_properties} + showEmptyGroup={showEmptyGroup} /> )} {enableQuickIssueCreate && ( @@ -88,6 +91,7 @@ export interface IList { priorities: any; enableQuickIssueCreate?: boolean; estimates: IEstimatePoint[] | null; + showEmptyGroup?: boolean; } export const List: React.FC = observer((props) => { @@ -103,7 +107,7 @@ export const List: React.FC = observer((props) => { projects, stateGroups, priorities, - + showEmptyGroup, enableQuickIssueCreate, } = props; @@ -120,6 +124,7 @@ export const List: React.FC = observer((props) => { display_properties={display_properties} is_list enableQuickIssueCreate={enableQuickIssueCreate} + showEmptyGroup={showEmptyGroup} /> )} @@ -133,6 +138,7 @@ export const List: React.FC = observer((props) => { quickActions={quickActions} display_properties={display_properties} enableQuickIssueCreate={enableQuickIssueCreate} + showEmptyGroup={showEmptyGroup} /> )} @@ -146,6 +152,7 @@ export const List: React.FC = observer((props) => { quickActions={quickActions} display_properties={display_properties} enableQuickIssueCreate={enableQuickIssueCreate} + showEmptyGroup={showEmptyGroup} /> )} @@ -159,6 +166,7 @@ export const List: React.FC = observer((props) => { quickActions={quickActions} display_properties={display_properties} enableQuickIssueCreate={enableQuickIssueCreate} + showEmptyGroup={showEmptyGroup} /> )} @@ -172,6 +180,7 @@ export const List: React.FC = observer((props) => { quickActions={quickActions} display_properties={display_properties} enableQuickIssueCreate={enableQuickIssueCreate} + showEmptyGroup={showEmptyGroup} /> )} @@ -179,12 +188,13 @@ export const List: React.FC = observer((props) => { )} @@ -192,12 +202,13 @@ export const List: React.FC = observer((props) => { )} @@ -211,6 +222,7 @@ export const List: React.FC = observer((props) => { quickActions={quickActions} display_properties={display_properties} enableQuickIssueCreate={enableQuickIssueCreate} + showEmptyGroup={showEmptyGroup} /> )}
diff --git a/web/components/issues/issue-layouts/list/properties.tsx b/web/components/issues/issue-layouts/list/properties.tsx index 5fe24d399..569b1c2ab 100644 --- a/web/components/issues/issue-layouts/list/properties.tsx +++ b/web/components/issues/issue-layouts/list/properties.tsx @@ -18,10 +18,12 @@ export interface IKanBanProperties { issue: IIssue; handleIssues: (group_by: string | null, issue: IIssue) => void; display_properties: any; + isReadonly?: boolean; + showEmptyGroup?: boolean; } export const KanBanProperties: FC = observer((props) => { - const { columnId: group_id, issue, handleIssues, display_properties } = props; + const { columnId: group_id, issue, handleIssues, display_properties, isReadonly, showEmptyGroup } = props; const handleState = (state: IState) => { handleIssues(!group_id && group_id === "null" ? null : group_id, { ...issue, state: state.id }); @@ -76,7 +78,7 @@ export const KanBanProperties: FC = observer((props) => { )} {/* label */} - {display_properties && display_properties?.labels && ( + {display_properties && display_properties?.labels && (showEmptyGroup || issue?.labels.length > 0) && ( = observer((props) => { )} {/* assignee */} - {display_properties && display_properties?.assignee && ( + {display_properties && display_properties?.assignee && (showEmptyGroup || issue?.assignees?.length > 0) && ( )} {/* start date */} - {display_properties && display_properties?.start_date && ( + {display_properties && display_properties?.start_date && (showEmptyGroup || issue?.start_date) && ( handleStartDate(date)} @@ -109,7 +110,7 @@ export const KanBanProperties: FC = observer((props) => { )} {/* target/due date */} - {display_properties && display_properties?.due_date && ( + {display_properties && display_properties?.due_date && (showEmptyGroup || issue?.target_date) && ( handleTargetDate(date)} diff --git a/web/components/issues/issue-layouts/list/roots/project-root.tsx b/web/components/issues/issue-layouts/list/roots/project-root.tsx index 235ad2fd9..16ce940b5 100644 --- a/web/components/issues/issue-layouts/list/roots/project-root.tsx +++ b/web/components/issues/issue-layouts/list/roots/project-root.tsx @@ -27,8 +27,8 @@ export const ListLayout: FC = observer(() => { const issues = issueStore?.getIssues; - const group_by: string | null = issueFilterStore?.userDisplayFilters?.group_by || null; - + const userDisplayFilters = issueFilterStore?.userDisplayFilters || null; + const group_by: string | null = userDisplayFilters?.group_by || null; const display_properties = issueFilterStore?.userDisplayProperties || null; const handleIssues = useCallback( @@ -77,6 +77,7 @@ export const ListLayout: FC = observer(() => { projects={projects} enableQuickIssueCreate estimates={estimates?.points ? orderArrayBy(estimates.points, "key") : null} + showEmptyGroup={userDisplayFilters.show_empty_groups} /> ); diff --git a/web/components/issues/issue-peek-overview/activity/card.tsx b/web/components/issues/issue-peek-overview/activity/card.tsx index 16ca09595..1b475c6c7 100644 --- a/web/components/issues/issue-peek-overview/activity/card.tsx +++ b/web/components/issues/issue-peek-overview/activity/card.tsx @@ -37,99 +37,101 @@ export const IssueActivityCard: FC = (props) => { return (
    - {issueComments.map((activityItem: any, index: any) => { - // determines what type of action is performed - const message = activityItem.field ? : "created the issue."; + {issueComments && + issueComments.length > 0 && + issueComments.map((activityItem: any, index: any) => { + // determines what type of action is performed + const message = activityItem.field ? : "created the issue."; - if ("field" in activityItem && activityItem.field !== "updated_by") { - return ( -
  • -
    - {issueComments.length > 1 && index !== issueComments.length - 1 ? ( -
  • +
    + {issueComments.length > 1 && index !== issueComments.length - 1 ? ( +
  • + ); + } else if ("comment_json" in activityItem) + return ( +
    +
    - - ); - } else if ("comment_json" in activityItem) - return ( -
    - -
    - ); - })} + ); + })}
);