fix: dashboard issues widget tab rendering bug (#3795)

This commit is contained in:
Aaryan Khandelwal 2024-02-26 13:39:29 +05:30 committed by GitHub
parent e1ef830f39
commit 8b6206f28b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 61 additions and 62 deletions

View File

@ -67,6 +67,7 @@ export const AssignedIssuesWidget: React.FC<WidgetProps> = observer((props) => {
const filterParams = getRedirectionFilters(selectedTab); const filterParams = getRedirectionFilters(selectedTab);
const tabsList = selectedDurationFilter === "none" ? UNFILTERED_ISSUES_TABS_LIST : FILTERED_ISSUES_TABS_LIST; const tabsList = selectedDurationFilter === "none" ? UNFILTERED_ISSUES_TABS_LIST : FILTERED_ISSUES_TABS_LIST;
const selectedTabIndex = tabsList.findIndex((tab) => tab.key === selectedTab);
if (!widgetDetails || !widgetStats) return <WidgetLoader widgetKey={WIDGET_KEY} />; if (!widgetDetails || !widgetStats) return <WidgetLoader widgetKey={WIDGET_KEY} />;
@ -84,30 +85,25 @@ export const AssignedIssuesWidget: React.FC<WidgetProps> = observer((props) => {
onChange={(val) => { onChange={(val) => {
if (val === selectedDurationFilter) return; if (val === selectedDurationFilter) return;
let newTab = selectedTab;
// switch to pending tab if target date is changed to none // switch to pending tab if target date is changed to none
if (val === "none" && selectedTab !== "completed") { if (val === "none" && selectedTab !== "completed") newTab = "pending";
handleUpdateFilters({ duration: val, tab: "pending" });
return;
}
// switch to upcoming tab if target date is changed to other than none // switch to upcoming tab if target date is changed to other than none
if (val !== "none" && selectedDurationFilter === "none" && selectedTab !== "completed") { if (val !== "none" && selectedDurationFilter === "none" && selectedTab !== "completed") newTab = "upcoming";
handleUpdateFilters({ handleUpdateFilters({
duration: val, duration: val,
tab: "upcoming", tab: newTab,
}); });
return;
}
handleUpdateFilters({ duration: val });
}} }}
/> />
</div> </div>
<Tab.Group <Tab.Group
as="div" as="div"
selectedIndex={tabsList.findIndex((tab) => tab.key === selectedTab)} selectedIndex={selectedTabIndex}
onChange={(i) => { onChange={(i) => {
const selectedTab = tabsList[i]; const newSelectedTab = tabsList[i];
handleUpdateFilters({ tab: selectedTab?.key ?? "pending" }); handleUpdateFilters({ tab: newSelectedTab?.key ?? "completed" });
}} }}
className="h-full flex flex-col" className="h-full flex flex-col"
> >
@ -115,18 +111,21 @@ export const AssignedIssuesWidget: React.FC<WidgetProps> = observer((props) => {
<TabsList durationFilter={selectedDurationFilter} selectedTab={selectedTab} /> <TabsList durationFilter={selectedDurationFilter} selectedTab={selectedTab} />
</div> </div>
<Tab.Panels as="div" className="h-full"> <Tab.Panels as="div" className="h-full">
{tabsList.map((tab) => ( {tabsList.map((tab) => {
<Tab.Panel key={tab.key} as="div" className="h-full flex flex-col"> if (tab.key !== selectedTab) return null;
return (
<Tab.Panel key={tab.key} as="div" className="h-full flex flex-col" static>
<WidgetIssuesList <WidgetIssuesList
issues={widgetStats.issues}
tab={tab.key} tab={tab.key}
totalIssues={widgetStats.count}
type="assigned" type="assigned"
workspaceSlug={workspaceSlug} workspaceSlug={workspaceSlug}
widgetStats={widgetStats}
isLoading={fetching} isLoading={fetching}
/> />
</Tab.Panel> </Tab.Panel>
))} );
})}
</Tab.Panels> </Tab.Panels>
</Tab.Group> </Tab.Group>
</div> </div>

View File

@ -64,6 +64,7 @@ export const CreatedIssuesWidget: React.FC<WidgetProps> = observer((props) => {
const filterParams = getRedirectionFilters(selectedTab); const filterParams = getRedirectionFilters(selectedTab);
const tabsList = selectedDurationFilter === "none" ? UNFILTERED_ISSUES_TABS_LIST : FILTERED_ISSUES_TABS_LIST; const tabsList = selectedDurationFilter === "none" ? UNFILTERED_ISSUES_TABS_LIST : FILTERED_ISSUES_TABS_LIST;
const selectedTabIndex = tabsList.findIndex((tab) => tab.key === selectedTab);
if (!widgetDetails || !widgetStats) return <WidgetLoader widgetKey={WIDGET_KEY} />; if (!widgetDetails || !widgetStats) return <WidgetLoader widgetKey={WIDGET_KEY} />;
@ -81,30 +82,25 @@ export const CreatedIssuesWidget: React.FC<WidgetProps> = observer((props) => {
onChange={(val) => { onChange={(val) => {
if (val === selectedDurationFilter) return; if (val === selectedDurationFilter) return;
let newTab = selectedTab;
// switch to pending tab if target date is changed to none // switch to pending tab if target date is changed to none
if (val === "none" && selectedTab !== "completed") { if (val === "none" && selectedTab !== "completed") newTab = "pending";
handleUpdateFilters({ duration: val, tab: "pending" });
return;
}
// switch to upcoming tab if target date is changed to other than none // switch to upcoming tab if target date is changed to other than none
if (val !== "none" && selectedDurationFilter === "none" && selectedTab !== "completed") { if (val !== "none" && selectedDurationFilter === "none" && selectedTab !== "completed") newTab = "upcoming";
handleUpdateFilters({ handleUpdateFilters({
duration: val, duration: val,
tab: "upcoming", tab: newTab,
}); });
return;
}
handleUpdateFilters({ duration: val });
}} }}
/> />
</div> </div>
<Tab.Group <Tab.Group
as="div" as="div"
selectedIndex={tabsList.findIndex((tab) => tab.key === selectedTab)} selectedIndex={selectedTabIndex}
onChange={(i) => { onChange={(i) => {
const selectedTab = tabsList[i]; const newSelectedTab = tabsList[i];
handleUpdateFilters({ tab: selectedTab.key ?? "pending" }); handleUpdateFilters({ tab: newSelectedTab.key ?? "completed" });
}} }}
className="h-full flex flex-col" className="h-full flex flex-col"
> >
@ -112,18 +108,21 @@ export const CreatedIssuesWidget: React.FC<WidgetProps> = observer((props) => {
<TabsList durationFilter={selectedDurationFilter} selectedTab={selectedTab} /> <TabsList durationFilter={selectedDurationFilter} selectedTab={selectedTab} />
</div> </div>
<Tab.Panels as="div" className="h-full"> <Tab.Panels as="div" className="h-full">
{tabsList.map((tab) => ( {tabsList.map((tab) => {
<Tab.Panel key={tab.key} as="div" className="h-full flex flex-col"> if (tab.key !== selectedTab) return null;
return (
<Tab.Panel key={tab.key} as="div" className="h-full flex flex-col" static>
<WidgetIssuesList <WidgetIssuesList
issues={widgetStats.issues}
tab={tab.key} tab={tab.key}
totalIssues={widgetStats.count}
type="created" type="created"
workspaceSlug={workspaceSlug} workspaceSlug={workspaceSlug}
widgetStats={widgetStats}
isLoading={fetching} isLoading={fetching}
/> />
</Tab.Panel> </Tab.Panel>
))} );
})}
</Tab.Panels> </Tab.Panels>
</Tab.Group> </Tab.Group>
</div> </div>

View File

@ -19,19 +19,18 @@ import { Loader, getButtonStyling } from "@plane/ui";
import { cn } from "helpers/common.helper"; import { cn } from "helpers/common.helper";
import { getRedirectionFilters } from "helpers/dashboard.helper"; import { getRedirectionFilters } from "helpers/dashboard.helper";
// types // types
import { TIssue, TIssuesListTypes } from "@plane/types"; import { TAssignedIssuesWidgetResponse, TCreatedIssuesWidgetResponse, TIssue, TIssuesListTypes } from "@plane/types";
export type WidgetIssuesListProps = { export type WidgetIssuesListProps = {
isLoading: boolean; isLoading: boolean;
issues: TIssue[];
tab: TIssuesListTypes; tab: TIssuesListTypes;
totalIssues: number;
type: "assigned" | "created"; type: "assigned" | "created";
widgetStats: TAssignedIssuesWidgetResponse | TCreatedIssuesWidgetResponse;
workspaceSlug: string; workspaceSlug: string;
}; };
export const WidgetIssuesList: React.FC<WidgetIssuesListProps> = (props) => { export const WidgetIssuesList: React.FC<WidgetIssuesListProps> = (props) => {
const { isLoading, issues, tab, totalIssues, type, workspaceSlug } = props; const { isLoading, tab, type, widgetStats, workspaceSlug } = props;
// store hooks // store hooks
const { setPeekIssue } = useIssueDetail(); const { setPeekIssue } = useIssueDetail();
@ -59,6 +58,8 @@ export const WidgetIssuesList: React.FC<WidgetIssuesListProps> = (props) => {
}, },
}; };
const issuesList = widgetStats.issues;
return ( return (
<> <>
<div className="h-full"> <div className="h-full">
@ -69,7 +70,7 @@ export const WidgetIssuesList: React.FC<WidgetIssuesListProps> = (props) => {
<Loader.Item height="25px" /> <Loader.Item height="25px" />
<Loader.Item height="25px" /> <Loader.Item height="25px" />
</Loader> </Loader>
) : issues.length > 0 ? ( ) : issuesList.length > 0 ? (
<> <>
<div className="mt-7 mx-6 border-b-[0.5px] border-custom-border-200 grid grid-cols-6 gap-1 text-xs text-custom-text-300 pb-1"> <div className="mt-7 mx-6 border-b-[0.5px] border-custom-border-200 grid grid-cols-6 gap-1 text-xs text-custom-text-300 pb-1">
<h6 <h6
@ -80,7 +81,7 @@ export const WidgetIssuesList: React.FC<WidgetIssuesListProps> = (props) => {
> >
Issues Issues
<span className="flex-shrink-0 bg-custom-primary-100/20 text-custom-primary-100 text-xs font-medium rounded-xl px-3 flex items-center text-center justify-center"> <span className="flex-shrink-0 bg-custom-primary-100/20 text-custom-primary-100 text-xs font-medium rounded-xl px-3 flex items-center text-center justify-center">
{totalIssues} {widgetStats.count}
</span> </span>
</h6> </h6>
{["upcoming", "pending"].includes(tab) && <h6 className="text-center">Due date</h6>} {["upcoming", "pending"].includes(tab) && <h6 className="text-center">Due date</h6>}
@ -89,7 +90,7 @@ export const WidgetIssuesList: React.FC<WidgetIssuesListProps> = (props) => {
{type === "created" && <h6 className="text-center">Assigned to</h6>} {type === "created" && <h6 className="text-center">Assigned to</h6>}
</div> </div>
<div className="px-4 pb-3 mt-2"> <div className="px-4 pb-3 mt-2">
{issues.map((issue) => { {issuesList.map((issue) => {
const IssueListItem = ISSUE_LIST_ITEM[type][tab]; const IssueListItem = ISSUE_LIST_ITEM[type][tab];
if (!IssueListItem) return null; if (!IssueListItem) return null;
@ -112,7 +113,7 @@ export const WidgetIssuesList: React.FC<WidgetIssuesListProps> = (props) => {
</div> </div>
)} )}
</div> </div>
{issues.length > 0 && ( {!isLoading && issuesList.length > 0 && (
<Link <Link
href={`/${workspaceSlug}/workspace-views/${type}/${filterParams}`} href={`/${workspaceSlug}/workspace-views/${type}/${filterParams}`}
className={cn( className={cn(