[WEB-575] chore: safely re-enable SWR (#3805)

* safley enable swr and make sure to minimalize re renders

* resolve build errors

* fix dropdowns updation by adding observer
This commit is contained in:
rahulramesha 2024-02-28 15:18:11 +05:30 committed by GitHub
parent bd142989b4
commit 6c70d3854a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
49 changed files with 952 additions and 1173 deletions

View file

@ -21,10 +21,10 @@ import {
CycleDropdown,
DateDropdown,
EstimateDropdown,
MemberDropdown,
ModuleDropdown,
PriorityDropdown,
ProjectDropdown,
ProjectMemberDropdown,
StateDropdown,
} from "components/dropdowns";
// ui
@ -474,7 +474,7 @@ export const DraftIssueForm: FC<IssueFormProps> = observer((props) => {
name="assignee_ids"
render={({ field: { value, onChange } }) => (
<div className="h-7">
<ProjectMemberDropdown
<MemberDropdown
projectId={projectId}
value={value}
onChange={onChange}

View file

@ -5,7 +5,7 @@ import { CalendarCheck2, Signal, Tag } from "lucide-react";
import { useIssueDetail, useProject, useProjectState } from "hooks/store";
// components
import { IssueLabel, TIssueOperations } from "components/issues";
import { DateDropdown, PriorityDropdown, ProjectMemberDropdown, StateDropdown } from "components/dropdowns";
import { DateDropdown, PriorityDropdown, MemberDropdown, StateDropdown } from "components/dropdowns";
// icons
import { DoubleCircleIcon, StateGroupIcon, UserGroupIcon } from "@plane/ui";
// helper
@ -80,7 +80,7 @@ export const InboxIssueDetailsSidebar: React.FC<Props> = observer((props) => {
<UserGroupIcon className="h-4 w-4 flex-shrink-0" />
<span>Assignees</span>
</div>
<ProjectMemberDropdown
<MemberDropdown
value={issue?.assignee_ids ?? undefined}
onChange={(val) => issueOperations.update(workspaceSlug, projectId, issueId, { assignee_ids: val })}
disabled={!is_editable}

View file

@ -27,13 +27,7 @@ import {
IssueLabel,
} from "components/issues";
import { IssueSubscription } from "./subscription";
import {
DateDropdown,
EstimateDropdown,
PriorityDropdown,
ProjectMemberDropdown,
StateDropdown,
} from "components/dropdowns";
import { DateDropdown, EstimateDropdown, PriorityDropdown, MemberDropdown, StateDropdown } from "components/dropdowns";
// icons
import { ContrastIcon, DiceIcon, DoubleCircleIcon, RelatedIcon, UserGroupIcon } from "@plane/ui";
// helpers
@ -161,7 +155,7 @@ export const IssueDetailsSidebar: React.FC<Props> = observer((props) => {
<UserGroupIcon className="h-4 w-4 flex-shrink-0" />
<span>Assignees</span>
</div>
<ProjectMemberDropdown
<MemberDropdown
value={issue?.assignee_ids ?? undefined}
onChange={(val) => issueOperations.update(workspaceSlug, projectId, issueId, { assignee_ids: val })}
disabled={!is_editable}

View file

@ -26,7 +26,7 @@ export const CalendarIssueBlocks: React.FC<Props> = observer((props) => {
const {
router: { workspaceSlug, projectId },
} = useApplication();
const { getProjectById } = useProject();
const { getProjectIdentifierById } = useProject();
const { getProjectStates } = useProjectState();
const { peekIssue, setPeekIssue } = useIssueDetail();
// states
@ -108,7 +108,7 @@ export const CalendarIssueBlocks: React.FC<Props> = observer((props) => {
}}
/>
<div className="flex-shrink-0 text-xs text-custom-text-300">
{getProjectById(issue?.project_id)?.identifier}-{issue.sequence_id}
{getProjectIdentifierById(issue?.project_id)}-{issue.sequence_id}
</div>
<Tooltip tooltipHeading="Title" tooltipContent={issue.name}>
<div className="truncate text-xs">{issue.name}</div>

View file

@ -66,7 +66,7 @@ export const IssueGanttSidebarBlock: React.FC<Props> = observer((props) => {
const { issueId } = props;
// store hooks
const { getStateById } = useProjectState();
const { getProjectById } = useProject();
const { getProjectIdentifierById } = useProject();
const {
router: { workspaceSlug },
} = useApplication();
@ -76,7 +76,7 @@ export const IssueGanttSidebarBlock: React.FC<Props> = observer((props) => {
} = useIssueDetail();
// derived values
const issueDetails = getIssueById(issueId);
const projectDetails = issueDetails && getProjectById(issueDetails?.project_id);
const projectIdentifier = issueDetails && getProjectIdentifierById(issueDetails?.project_id);
const stateDetails = issueDetails && getStateById(issueDetails?.state_id);
const handleIssuePeekOverview = () =>
@ -95,7 +95,7 @@ export const IssueGanttSidebarBlock: React.FC<Props> = observer((props) => {
<div className="relative flex h-full w-full cursor-pointer items-center gap-2">
{stateDetails && <StateGroupIcon stateGroup={stateDetails?.group} color={stateDetails?.color} />}
<div className="flex-shrink-0 text-xs text-custom-text-300">
{projectDetails?.identifier} {issueDetails?.sequence_id}
{projectIdentifier} {issueDetails?.sequence_id}
</div>
<Tooltip tooltipHeading="Title" tooltipContent={issueDetails?.name}>
<span className="flex-grow truncate text-sm font-medium">{issueDetails?.name}</span>

View file

@ -42,9 +42,9 @@ interface IssueDetailsBlockProps {
const KanbanIssueDetailsBlock: React.FC<IssueDetailsBlockProps> = observer((props: IssueDetailsBlockProps) => {
const { issue, handleIssues, quickActions, isReadOnly, displayProperties } = props;
// hooks
const { getProjectById } = useProject();
const { getProjectIdentifierById } = useProject();
const {
router: { workspaceSlug, projectId },
router: { workspaceSlug },
} = useApplication();
const { setPeekIssue } = useIssueDetail();
@ -64,7 +64,7 @@ const KanbanIssueDetailsBlock: React.FC<IssueDetailsBlockProps> = observer((prop
<WithDisplayPropertiesHOC displayProperties={displayProperties || {}} displayPropertyKey="key">
<div className="relative">
<div className="line-clamp-1 text-xs text-custom-text-300">
{getProjectById(issue.project_id)?.identifier}-{issue.sequence_id}
{getProjectIdentifierById(issue.project_id)}-{issue.sequence_id}
</div>
<div className="absolute -top-1 right-0 hidden group-hover/kanban-block:block">{quickActions(issue)}</div>
</div>

View file

@ -1,4 +1,4 @@
import React, { useMemo } from "react";
import React, { useCallback, useMemo } from "react";
import { useRouter } from "next/router";
import { observer } from "mobx-react-lite";
// hooks
@ -46,7 +46,15 @@ export const CycleKanBanLayout: React.FC = observer(() => {
const isCompletedCycle =
cycleId && currentProjectCompletedCycleIds ? currentProjectCompletedCycleIds.includes(cycleId.toString()) : false;
const canEditIssueProperties = () => !isCompletedCycle;
const canEditIssueProperties = useCallback(() => !isCompletedCycle, [isCompletedCycle]);
const addIssuesToView = useCallback(
(issueIds: string[]) => {
if (!workspaceSlug || !projectId || !cycleId) throw new Error();
return issues.addIssueToCycle(workspaceSlug.toString(), projectId.toString(), cycleId.toString(), issueIds);
},
[issues?.addIssueToCycle, workspaceSlug, projectId, cycleId]
);
return (
<BaseKanBanRoot
@ -57,10 +65,7 @@ export const CycleKanBanLayout: React.FC = observer(() => {
QuickActions={CycleIssueQuickActions}
viewId={cycleId?.toString() ?? ""}
storeType={EIssuesStoreType.CYCLE}
addIssuesToView={(issueIds: string[]) => {
if (!workspaceSlug || !projectId || !cycleId) throw new Error();
return issues.addIssueToCycle(workspaceSlug.toString(), projectId.toString(), cycleId.toString(), issueIds);
}}
addIssuesToView={addIssuesToView}
canEditPropertiesBasedOnProject={canEditIssueProperties}
isCompletedCycle={isCompletedCycle}
/>

View file

@ -24,9 +24,9 @@ export const IssueBlock: React.FC<IssueBlockProps> = observer((props: IssueBlock
const { issuesMap, issueId, handleIssues, quickActions, displayProperties, canEditProperties } = props;
// hooks
const {
router: { workspaceSlug, projectId },
router: { workspaceSlug },
} = useApplication();
const { getProjectById } = useProject();
const { getProjectIdentifierById } = useProject();
const { peekIssue, setPeekIssue } = useIssueDetail();
const updateIssue = async (issueToUpdate: TIssue) => {
@ -45,7 +45,7 @@ export const IssueBlock: React.FC<IssueBlockProps> = observer((props: IssueBlock
if (!issue) return null;
const canEditIssueProperties = canEditProperties(issue.project_id);
const projectDetails = getProjectById(issue.project_id);
const projectIdentifier = getProjectIdentifierById(issue.project_id);
return (
<div
@ -56,7 +56,7 @@ export const IssueBlock: React.FC<IssueBlockProps> = observer((props: IssueBlock
>
{displayProperties && displayProperties?.key && (
<div className="flex-shrink-0 text-xs font-medium text-custom-text-300">
{projectDetails?.identifier}-{issue.sequence_id}
{projectIdentifier}-{issue.sequence_id}
</div>
)}

View file

@ -1,4 +1,4 @@
import React, { useMemo } from "react";
import React, { useCallback, useMemo } from "react";
import { useRouter } from "next/router";
import { observer } from "mobx-react-lite";
// hooks
@ -44,7 +44,15 @@ export const CycleListLayout: React.FC = observer(() => {
const isCompletedCycle =
cycleId && currentProjectCompletedCycleIds ? currentProjectCompletedCycleIds.includes(cycleId.toString()) : false;
const canEditIssueProperties = () => !isCompletedCycle;
const canEditIssueProperties = useCallback(() => !isCompletedCycle, [isCompletedCycle]);
const addIssuesToView = useCallback(
(issueIds: string[]) => {
if (!workspaceSlug || !projectId || !cycleId) throw new Error();
return issues.addIssueToCycle(workspaceSlug.toString(), projectId.toString(), cycleId.toString(), issueIds);
},
[issues?.addIssueToCycle, workspaceSlug, projectId, cycleId]
);
return (
<BaseListRoot
@ -54,10 +62,7 @@ export const CycleListLayout: React.FC = observer(() => {
issueActions={issueActions}
viewId={cycleId?.toString()}
storeType={EIssuesStoreType.CYCLE}
addIssuesToView={(issueIds: string[]) => {
if (!workspaceSlug || !projectId || !cycleId) throw new Error();
return issues.addIssueToCycle(workspaceSlug.toString(), projectId.toString(), cycleId.toString(), issueIds);
}}
addIssuesToView={addIssuesToView}
canEditPropertiesBasedOnProject={canEditIssueProperties}
isCompletedCycle={isCompletedCycle}
/>

View file

@ -13,7 +13,7 @@ import {
DateDropdown,
EstimateDropdown,
PriorityDropdown,
ProjectMemberDropdown,
MemberDropdown,
ModuleDropdown,
CycleDropdown,
StateDropdown,
@ -313,7 +313,7 @@ export const IssueProperties: React.FC<IIssueProperties> = observer((props) => {
{/* assignee */}
<WithDisplayPropertiesHOC displayProperties={displayProperties} displayPropertyKey="assignee">
<div className="h-5">
<ProjectMemberDropdown
<MemberDropdown
projectId={issue?.project_id}
value={issue?.assignee_ids}
onChange={handleAssignee}

View file

@ -88,11 +88,15 @@ export const AllIssueLayoutRoot: React.FC = observer(() => {
}
};
useSWR(workspaceSlug ? `WORKSPACE_GLOBAL_VIEWS${workspaceSlug}` : null, async () => {
if (workspaceSlug) {
await fetchAllGlobalViews(workspaceSlug.toString());
}
});
useSWR(
workspaceSlug ? `WORKSPACE_GLOBAL_VIEWS_${workspaceSlug}` : null,
async () => {
if (workspaceSlug) {
await fetchAllGlobalViews(workspaceSlug.toString());
}
},
{ revalidateIfStale: false, revalidateOnFocus: false }
);
useSWR(
workspaceSlug && globalViewId ? `WORKSPACE_GLOBAL_VIEW_ISSUES_${workspaceSlug}_${globalViewId}` : null,
@ -103,7 +107,8 @@ export const AllIssueLayoutRoot: React.FC = observer(() => {
await fetchIssues(workspaceSlug.toString(), globalViewId.toString(), issueIds ? "mutation" : "init-loader");
routerFilterParams();
}
}
},
{ revalidateIfStale: false, revalidateOnFocus: false }
);
const canEditProperties = useCallback(

View file

@ -33,7 +33,8 @@ export const ArchivedIssueLayoutRoot: React.FC = observer(() => {
issues?.groupedIssueIds ? "mutation" : "init-loader"
);
}
}
},
{ revalidateIfStale: false, revalidateOnFocus: false }
);
if (issues?.loader === "init-loader" || !issues?.groupedIssueIds) {

View file

@ -47,7 +47,8 @@ export const CycleLayoutRoot: React.FC = observer(() => {
cycleId.toString()
);
}
}
},
{ revalidateIfStale: false, revalidateOnFocus: false }
);
const activeLayout = issuesFilter?.issueFilters?.displayFilters?.layout;

View file

@ -33,7 +33,8 @@ export const DraftIssueLayoutRoot: React.FC = observer(() => {
issues?.groupedIssueIds ? "mutation" : "init-loader"
);
}
}
},
{ revalidateIfStale: false, revalidateOnFocus: false }
);
const activeLayout = issuesFilter?.issueFilters?.displayFilters?.layout || undefined;

View file

@ -43,7 +43,8 @@ export const ModuleLayoutRoot: React.FC = observer(() => {
moduleId.toString()
);
}
}
},
{ revalidateIfStale: false, revalidateOnFocus: false }
);
const userFilters = issuesFilter?.issueFilters?.filters;

View file

@ -29,16 +29,20 @@ export const ProjectLayoutRoot: FC = observer(() => {
// hooks
const { issues, issuesFilter } = useIssues(EIssuesStoreType.PROJECT);
useSWR(workspaceSlug && projectId ? `PROJECT_ISSUES_${workspaceSlug}_${projectId}` : null, async () => {
if (workspaceSlug && projectId) {
await issuesFilter?.fetchFilters(workspaceSlug.toString(), projectId.toString());
await issues?.fetchIssues(
workspaceSlug.toString(),
projectId.toString(),
issues?.groupedIssueIds ? "mutation" : "init-loader"
);
}
});
useSWR(
workspaceSlug && projectId ? `PROJECT_ISSUES_${workspaceSlug}_${projectId}` : null,
async () => {
if (workspaceSlug && projectId) {
await issuesFilter?.fetchFilters(workspaceSlug.toString(), projectId.toString());
await issues?.fetchIssues(
workspaceSlug.toString(),
projectId.toString(),
issues?.groupedIssueIds ? "mutation" : "init-loader"
);
}
},
{ revalidateIfStale: false, revalidateOnFocus: false }
);
const activeLayout = issuesFilter?.issueFilters?.displayFilters?.layout;

View file

@ -41,7 +41,8 @@ export const ProjectViewLayoutRoot: React.FC = observer(() => {
viewId.toString()
);
}
}
},
{ revalidateIfStale: false, revalidateOnFocus: false }
);
const issueActions = useMemo(

View file

@ -1,7 +1,7 @@
import React from "react";
import { observer } from "mobx-react-lite";
// components
import { ProjectMemberDropdown } from "components/dropdowns";
import { MemberDropdown } from "components/dropdowns";
// types
import { TIssue } from "@plane/types";
@ -17,7 +17,7 @@ export const SpreadsheetAssigneeColumn: React.FC<Props> = observer((props: Props
return (
<div className="h-11 border-b-[0.5px] border-custom-border-200">
<ProjectMemberDropdown
<MemberDropdown
value={issue?.assignee_ids ?? []}
onChange={(data) => {
onChange(

View file

@ -142,7 +142,7 @@ const IssueRowDetails = observer((props: IssueRowDetailsProps) => {
const router = useRouter();
const { workspaceSlug } = router.query;
//hooks
const { getProjectById } = useProject();
const { getProjectIdentifierById } = useProject();
const { peekIssue, setPeekIssue } = useIssueDetail();
// states
const [isMenuActive, setIsMenuActive] = useState(false);
@ -212,7 +212,7 @@ const IssueRowDetails = observer((props: IssueRowDetailsProps) => {
isMenuActive ? "opacity-0" : "opacity-100"
}`}
>
{getProjectById(issueDetail.project_id)?.identifier}-{issueDetail.sequence_id}
{getProjectIdentifierById(issueDetail.project_id)}-{issueDetail.sequence_id}
</span>
{canEditProperties(issueDetail.project_id) && (

View file

@ -1,4 +1,4 @@
import React, { useMemo } from "react";
import React, { useCallback, useMemo } from "react";
import { observer } from "mobx-react-lite";
import { useRouter } from "next/router";
// mobx store
@ -39,7 +39,7 @@ export const CycleSpreadsheetLayout: React.FC = observer(() => {
const isCompletedCycle =
cycleId && currentProjectCompletedCycleIds ? currentProjectCompletedCycleIds.includes(cycleId.toString()) : false;
const canEditIssueProperties = () => !isCompletedCycle;
const canEditIssueProperties = useCallback(() => !isCompletedCycle, [isCompletedCycle]);
return (
<BaseSpreadsheetRoot

View file

@ -23,7 +23,7 @@ import {
ModuleDropdown,
PriorityDropdown,
ProjectDropdown,
ProjectMemberDropdown,
MemberDropdown,
StateDropdown,
} from "components/dropdowns";
// ui
@ -510,7 +510,7 @@ export const IssueFormRoot: FC<IssueFormProps> = observer((props) => {
name="assignee_ids"
render={({ field: { value, onChange } }) => (
<div className="h-7">
<ProjectMemberDropdown
<MemberDropdown
projectId={projectId}
value={value}
onChange={(assigneeIds) => {

View file

@ -54,7 +54,6 @@ export const CreateUpdateIssueModal: React.FC<IssuesModalProps> = observer((prop
const {
router: { workspaceSlug, projectId, cycleId, moduleId, viewId: projectViewId },
} = useApplication();
const { currentWorkspace } = useWorkspace();
const { workspaceProjectIds } = useProject();
const { fetchCycleDetails } = useCycle();
const { fetchModuleDetails } = useModule();

View file

@ -14,13 +14,7 @@ import {
TIssueOperations,
IssueRelationSelect,
} from "components/issues";
import {
DateDropdown,
EstimateDropdown,
PriorityDropdown,
ProjectMemberDropdown,
StateDropdown,
} from "components/dropdowns";
import { DateDropdown, EstimateDropdown, PriorityDropdown, MemberDropdown, StateDropdown } from "components/dropdowns";
// components
import { renderFormattedPayloadDate } from "helpers/date-time.helper";
// helpers
@ -87,7 +81,7 @@ export const PeekOverviewProperties: FC<IPeekOverviewProperties> = observer((pro
<UserGroupIcon className="h-4 w-4 flex-shrink-0" />
<span>Assignees</span>
</div>
<ProjectMemberDropdown
<MemberDropdown
value={issue?.assignee_ids ?? undefined}
onChange={(val) => issueOperations.update(workspaceSlug, projectId, issueId, { assignee_ids: val })}
disabled={disabled}

View file

@ -2,7 +2,7 @@ import React from "react";
// hooks
import { useIssueDetail } from "hooks/store";
// components
import { PriorityDropdown, ProjectMemberDropdown, StateDropdown } from "components/dropdowns";
import { PriorityDropdown, MemberDropdown, StateDropdown } from "components/dropdowns";
// types
import { TSubIssueOperations } from "./root";
@ -62,7 +62,7 @@ export const IssueProperty: React.FC<IIssueProperty> = (props) => {
</div>
<div className="h-5 flex-shrink-0">
<ProjectMemberDropdown
<MemberDropdown
value={issue.assignee_ids}
projectId={issue.project_id}
onChange={(val) =>