chore: use new cycle and module store. (#3172)

* chore: use new cycle and module store.

* chore: minor improvements.
This commit is contained in:
Prateek Shourya 2023-12-18 18:43:40 +05:30 committed by GitHub
parent cad2706286
commit 9595493c42
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 103 additions and 75 deletions

View File

@ -1,9 +1,9 @@
import { useCallback, useState } from "react"; import React, { useCallback, useState } from "react";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
// hooks // hooks
import { useMobxStore } from "lib/mobx/store-provider"; import { useMobxStore } from "lib/mobx/store-provider";
import { useApplication, useLabel, useProject, useProjectState, useUser } from "hooks/store"; import { useApplication, useCycle, useLabel, useProject, useProjectState, useUser } from "hooks/store";
import useLocalStorage from "hooks/use-local-storage"; import useLocalStorage from "hooks/use-local-storage";
// components // components
import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "components/issues"; import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "components/issues";
@ -23,6 +23,30 @@ import { EFilterType } from "store_legacy/issues/types";
import { EProjectStore } from "store_legacy/command-palette.store"; import { EProjectStore } from "store_legacy/command-palette.store";
import { EUserProjectRoles } from "constants/project"; import { EUserProjectRoles } from "constants/project";
const CycleDropdownOption: React.FC<{ cycleId: string }> = ({ cycleId }) => {
// router
const router = useRouter();
const { workspaceSlug, projectId } = router.query;
// store hooks
const { getCycleById } = useCycle();
// derived values
const cycle = getCycleById(cycleId);
if (!cycle) return null;
return (
<CustomMenu.MenuItem
key={cycle.id}
onClick={() => router.push(`/${workspaceSlug}/projects/${projectId}/cycles/${cycle.id}`)}
>
<div className="flex items-center gap-1.5">
<ContrastIcon className="h-3 w-3" />
{truncateText(cycle.name, 40)}
</div>
</CustomMenu.MenuItem>
);
};
export const CycleIssuesHeader: React.FC = observer(() => { export const CycleIssuesHeader: React.FC = observer(() => {
// states // states
const [analyticsModal, setAnalyticsModal] = useState(false); const [analyticsModal, setAnalyticsModal] = useState(false);
@ -35,11 +59,11 @@ export const CycleIssuesHeader: React.FC = observer(() => {
}; };
// store hooks // store hooks
const { const {
cycle: cycleStore,
projectIssuesFilter: projectIssueFiltersStore, projectIssuesFilter: projectIssueFiltersStore,
projectMember: { projectMembers }, projectMember: { projectMembers },
cycleIssuesFilter: { issueFilters, updateFilters }, cycleIssuesFilter: { issueFilters, updateFilters },
} = useMobxStore(); } = useMobxStore();
const { projectAllCycles, getCycleById } = useCycle();
const { const {
commandPalette: { toggleCreateIssueModal }, commandPalette: { toggleCreateIssueModal },
eventTracker: { setTrackElement }, eventTracker: { setTrackElement },
@ -105,9 +129,8 @@ export const CycleIssuesHeader: React.FC = observer(() => {
[workspaceSlug, projectId, cycleId, updateFilters] [workspaceSlug, projectId, cycleId, updateFilters]
); );
const cyclesList = cycleStore.projectCycles; // derived values
const cycleDetails = cycleId ? cycleStore.getCycleById(cycleId.toString()) : undefined; const cycleDetails = cycleId ? getCycleById(cycleId.toString()) : undefined;
const canUserCreateIssue = const canUserCreateIssue =
currentProjectRole && [EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER].includes(currentProjectRole); currentProjectRole && [EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER].includes(currentProjectRole);
@ -157,16 +180,8 @@ export const CycleIssuesHeader: React.FC = observer(() => {
width="auto" width="auto"
placement="bottom-start" placement="bottom-start"
> >
{cyclesList?.map((cycle) => ( {projectAllCycles?.map((cycleId) => (
<CustomMenu.MenuItem <CycleDropdownOption key={cycleId} cycleId={cycleId} />
key={cycle.id}
onClick={() => router.push(`/${workspaceSlug}/projects/${projectId}/cycles/${cycle.id}`)}
>
<div className="flex items-center gap-1.5">
<ContrastIcon className="h-3 w-3" />
{truncateText(cycle.name, 40)}
</div>
</CustomMenu.MenuItem>
))} ))}
</CustomMenu> </CustomMenu>
} }

View File

@ -3,7 +3,7 @@ import { useRouter } from "next/router";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
// hooks // hooks
import { useMobxStore } from "lib/mobx/store-provider"; import { useMobxStore } from "lib/mobx/store-provider";
import { useApplication, useLabel, useProject, useProjectState, useUser } from "hooks/store"; import { useApplication, useLabel, useModule, useProject, useProjectState, useUser } from "hooks/store";
import useLocalStorage from "hooks/use-local-storage"; import useLocalStorage from "hooks/use-local-storage";
// components // components
import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "components/issues"; import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "components/issues";
@ -24,6 +24,30 @@ import { EFilterType } from "store_legacy/issues/types";
import { EProjectStore } from "store_legacy/command-palette.store"; import { EProjectStore } from "store_legacy/command-palette.store";
import { EUserProjectRoles } from "constants/project"; import { EUserProjectRoles } from "constants/project";
const ModuleDropdownOption: React.FC<{ moduleId: string }> = ({ moduleId }) => {
// router
const router = useRouter();
const { workspaceSlug, projectId } = router.query;
// store hooks
const { getModuleById } = useModule();
// derived values
const moduleDetail = getModuleById(moduleId);
if (!moduleDetail) return null;
return (
<CustomMenu.MenuItem
key={moduleDetail.id}
onClick={() => router.push(`/${workspaceSlug}/projects/${projectId}/modules/${moduleDetail.id}`)}
>
<div className="flex items-center gap-1.5">
<DiceIcon className="h-3 w-3" />
{truncateText(moduleDetail.name, 40)}
</div>
</CustomMenu.MenuItem>
);
};
export const ModuleIssuesHeader: React.FC = observer(() => { export const ModuleIssuesHeader: React.FC = observer(() => {
// states // states
const [analyticsModal, setAnalyticsModal] = useState(false); const [analyticsModal, setAnalyticsModal] = useState(false);
@ -36,10 +60,10 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
}; };
// store hooks // store hooks
const { const {
module: moduleStore,
projectMember: { projectMembers }, projectMember: { projectMembers },
moduleIssuesFilter: { issueFilters, updateFilters }, moduleIssuesFilter: { issueFilters, updateFilters },
} = useMobxStore(); } = useMobxStore();
const { projectModules, getModuleById } = useModule();
const { const {
commandPalette: { toggleCreateIssueModal }, commandPalette: { toggleCreateIssueModal },
eventTracker: { setTrackElement }, eventTracker: { setTrackElement },
@ -105,9 +129,8 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
[workspaceSlug, projectId, moduleId, updateFilters] [workspaceSlug, projectId, moduleId, updateFilters]
); );
const modulesList = projectId ? moduleStore.modules[projectId.toString()] : undefined; // derived values
const moduleDetails = moduleId ? moduleStore.getModuleById(moduleId.toString()) : undefined; const moduleDetails = moduleId ? getModuleById(moduleId.toString()) : undefined;
const canUserCreateIssue = const canUserCreateIssue =
currentProjectRole && [EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER].includes(currentProjectRole); currentProjectRole && [EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER].includes(currentProjectRole);
@ -157,16 +180,8 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
width="auto" width="auto"
placement="bottom-start" placement="bottom-start"
> >
{modulesList?.map((module) => ( {projectModules?.map((moduleId) => (
<CustomMenu.MenuItem <ModuleDropdownOption moduleId={moduleId} />
key={module.id}
onClick={() => router.push(`/${workspaceSlug}/projects/${projectId}/modules/${module.id}`)}
>
<div className="flex items-center gap-1.5">
<DiceIcon className="h-3 w-3" />
{truncateText(module.name, 40)}
</div>
</CustomMenu.MenuItem>
))} ))}
</CustomMenu> </CustomMenu>
} }

View File

@ -32,7 +32,6 @@ export const CycleLayoutRoot: React.FC = observer(() => {
}; };
// store hooks // store hooks
const { const {
cycle: cycleStore,
cycleIssues: { loader, getIssues, fetchIssues }, cycleIssues: { loader, getIssues, fetchIssues },
cycleIssuesFilter: { issueFilters, fetchFilters }, cycleIssuesFilter: { issueFilters, fetchFilters },
} = useMobxStore(); } = useMobxStore();

View File

@ -1,8 +1,8 @@
import React, { useState } from "react"; import React, { useState } from "react";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import { usePopper } from "react-popper"; import { usePopper } from "react-popper";
// mobx store // hooks
import { useMobxStore } from "lib/mobx/store-provider"; import { useCycle } from "hooks/store";
// ui // ui
import { Combobox } from "@headlessui/react"; import { Combobox } from "@headlessui/react";
// icons // icons
@ -28,28 +28,27 @@ export const IssueCycleSelect: React.FC<IssueCycleSelectProps> = observer((props
placement: "bottom-start", placement: "bottom-start",
}); });
const { cycle: cycleStore } = useMobxStore(); const { projectAllCycles, fetchAllCycles, getCycleById } = useCycle();
const fetchCycles = () => { const fetchCycles = () => {
if (workspaceSlug && projectId) cycleStore.fetchCycles(workspaceSlug, projectId, "all"); if (workspaceSlug && projectId) fetchAllCycles(workspaceSlug, projectId);
}; };
const cycles = cycleStore.projectCycles; const selectedCycle = value ? getCycleById(value) : null;
const selectedCycle = cycles ? cycles?.find((i) => i.id === value) : undefined; const options = projectAllCycles?.map((cycleId) => {
const cycleDetail = getCycleById(cycleId);
const options = cycles?.map((cycle) => ({ return {
value: cycle.id, value: cycleId,
query: cycle.name, query: cycleDetail?.name ?? "",
content: ( content: (
<div className="flex items-center gap-1.5 truncate"> <div className="flex items-center gap-1.5">
<span className="flex h-3.5 w-3.5 flex-shrink-0 items-center justify-center"> <ContrastIcon className="h-3 w-3" />
<ContrastIcon /> {cycleDetail?.name}
</span> </div>
<span className="flex-grow truncate">{cycle.name}</span> ),
</div> };
), });
}));
const filteredOptions = const filteredOptions =
query === "" ? options : options?.filter((option) => option.query.toLowerCase().includes(query.toLowerCase())); query === "" ? options : options?.filter((option) => option.query.toLowerCase().includes(query.toLowerCase()));

View File

@ -2,7 +2,8 @@ import React, { useState } from "react";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import { mutate } from "swr"; import { mutate } from "swr";
// mobx store // hooks
import { useModule } from "hooks/store";
import { useMobxStore } from "lib/mobx/store-provider"; import { useMobxStore } from "lib/mobx/store-provider";
// ui // ui
import { CustomSearchSelect, DiceIcon, Spinner, Tooltip } from "@plane/ui"; import { CustomSearchSelect, DiceIcon, Spinner, Tooltip } from "@plane/ui";
@ -25,9 +26,9 @@ export const SidebarModuleSelect: React.FC<Props> = observer((props) => {
const { workspaceSlug, projectId } = router.query; const { workspaceSlug, projectId } = router.query;
// mobx store // mobx store
const { const {
module: { projectModules },
moduleIssues: { removeIssueFromModule, addIssueToModule }, moduleIssues: { removeIssueFromModule, addIssueToModule },
} = useMobxStore(); } = useMobxStore();
const { projectModules, getModuleById } = useModule();
const [isUpdating, setIsUpdating] = useState(false); const [isUpdating, setIsUpdating] = useState(false);
@ -63,21 +64,25 @@ export const SidebarModuleSelect: React.FC<Props> = observer((props) => {
}); });
}; };
const options = projectModules?.map((module) => ({ const options = projectModules?.map((moduleId) => {
value: module.id, const moduleDetail = getModuleById(moduleId);
query: module.name, return {
content: ( value: moduleId,
<div className="flex items-center gap-1.5 truncate"> query: moduleDetail?.name ?? "",
<span className="flex h-3.5 w-3.5 flex-shrink-0 items-center justify-center"> content: (
<DiceIcon /> <div className="flex items-center gap-1.5 truncate">
</span> <span className="flex h-3.5 w-3.5 flex-shrink-0 items-center justify-center">
<span className="flex-grow truncate">{module.name}</span> <DiceIcon />
</div> </span>
), <span className="flex-grow truncate">{moduleDetail?.name}</span>
})); </div>
),
};
});
// derived values
const issueModule = issueDetail?.issue_module; const issueModule = issueDetail?.issue_module;
const selectedModule = issueModule?.module ? getModuleById(issueModule?.module) : null;
const disableSelect = disabled || isUpdating; const disableSelect = disabled || isUpdating;
return ( return (
@ -88,16 +93,13 @@ export const SidebarModuleSelect: React.FC<Props> = observer((props) => {
value === issueModule?.module_detail.id value === issueModule?.module_detail.id
? handleRemoveIssueFromModule(issueModule?.id ?? "", issueModule?.module ?? "") ? handleRemoveIssueFromModule(issueModule?.id ?? "", issueModule?.module ?? "")
: handleModuleChange : handleModuleChange
? handleModuleChange(value) ? handleModuleChange(value)
: handleModuleStoreChange(value); : handleModuleStoreChange(value);
}} }}
options={options} options={options}
customButton={ customButton={
<div> <div>
<Tooltip <Tooltip position="left" tooltipContent={`${selectedModule?.name ?? "No module"}`}>
position="left"
tooltipContent={`${projectModules?.find((m) => m.id === issueModule?.module)?.name ?? "No module"}`}
>
<button <button
type="button" type="button"
className={`flex w-full items-center rounded bg-custom-background-80 px-2.5 py-0.5 text-xs ${ className={`flex w-full items-center rounded bg-custom-background-80 px-2.5 py-0.5 text-xs ${
@ -110,9 +112,7 @@ export const SidebarModuleSelect: React.FC<Props> = observer((props) => {
}`} }`}
> >
<span className="flex-shrink-0">{issueModule && <DiceIcon className="h-3.5 w-3.5" />}</span> <span className="flex-shrink-0">{issueModule && <DiceIcon className="h-3.5 w-3.5" />}</span>
<span className="truncate"> <span className="truncate">{selectedModule?.name ?? "No module"}</span>
{projectModules?.find((m) => m.id === issueModule?.module)?.name ?? "No module"}
</span>
</span> </span>
</button> </button>
</Tooltip> </Tooltip>