forked from github/plane
refactor: replace keyboard events with command palette store (#2688)
This commit is contained in:
parent
53e7da08e4
commit
5a84ed279d
@ -3,6 +3,7 @@ import { useRouter } from "next/router";
|
||||
import useSWR, { mutate } from "swr";
|
||||
import { Command } from "cmdk";
|
||||
import { Dialog, Transition } from "@headlessui/react";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import {
|
||||
FileText,
|
||||
FolderPlus,
|
||||
@ -16,12 +17,13 @@ import {
|
||||
UserMinus2,
|
||||
UserPlus2,
|
||||
} from "lucide-react";
|
||||
// mobx store
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
// services
|
||||
import { WorkspaceService } from "services/workspace.service";
|
||||
import { IssueService } from "services/issue";
|
||||
// hooks
|
||||
import useDebounce from "hooks/use-debounce";
|
||||
import useUser from "hooks/use-user";
|
||||
import useToast from "hooks/use-toast";
|
||||
// components
|
||||
import {
|
||||
@ -61,11 +63,8 @@ type Props = {
|
||||
const workspaceService = new WorkspaceService();
|
||||
const issueService = new IssueService();
|
||||
|
||||
export const CommandModal: React.FC<Props> = (props) => {
|
||||
export const CommandModal: React.FC<Props> = observer((props) => {
|
||||
const { deleteIssue, isPaletteOpen, closePalette } = props;
|
||||
// router
|
||||
const router = useRouter();
|
||||
const { workspaceSlug, projectId, issueId } = router.query;
|
||||
// states
|
||||
const [placeholder, setPlaceholder] = useState("Type a command or search...");
|
||||
const [resultsCount, setResultsCount] = useState(0);
|
||||
@ -86,14 +85,19 @@ export const CommandModal: React.FC<Props> = (props) => {
|
||||
const [isWorkspaceLevel, setIsWorkspaceLevel] = useState(false);
|
||||
const [pages, setPages] = useState<string[]>([]);
|
||||
|
||||
const { user: userStore, commandPalette: commandPaletteStore } = useMobxStore();
|
||||
const user = userStore.currentUser ?? undefined;
|
||||
|
||||
// router
|
||||
const router = useRouter();
|
||||
const { workspaceSlug, projectId, issueId } = router.query;
|
||||
|
||||
const page = pages[pages.length - 1];
|
||||
|
||||
const debouncedSearchTerm = useDebounce(searchTerm, 500);
|
||||
|
||||
const { setToastAlert } = useToast();
|
||||
|
||||
const { user } = useUser();
|
||||
|
||||
const { data: issueDetails } = useSWR(
|
||||
workspaceSlug && projectId && issueId ? ISSUE_DETAILS(issueId as string) : null,
|
||||
workspaceSlug && projectId && issueId
|
||||
@ -468,10 +472,7 @@ export const CommandModal: React.FC<Props> = (props) => {
|
||||
<Command.Item
|
||||
onSelect={() => {
|
||||
closePalette();
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "c",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
commandPaletteStore.toggleCreateIssueModal(true);
|
||||
}}
|
||||
className="focus:bg-custom-background-80"
|
||||
>
|
||||
@ -488,10 +489,7 @@ export const CommandModal: React.FC<Props> = (props) => {
|
||||
<Command.Item
|
||||
onSelect={() => {
|
||||
closePalette();
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "p",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
commandPaletteStore.toggleCreateProjectModal(true);
|
||||
}}
|
||||
className="focus:outline-none"
|
||||
>
|
||||
@ -510,10 +508,7 @@ export const CommandModal: React.FC<Props> = (props) => {
|
||||
<Command.Item
|
||||
onSelect={() => {
|
||||
closePalette();
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "q",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
commandPaletteStore.toggleCreateCycleModal(true);
|
||||
}}
|
||||
className="focus:outline-none"
|
||||
>
|
||||
@ -528,10 +523,7 @@ export const CommandModal: React.FC<Props> = (props) => {
|
||||
<Command.Item
|
||||
onSelect={() => {
|
||||
closePalette();
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "m",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
commandPaletteStore.toggleCreateModuleModal(true);
|
||||
}}
|
||||
className="focus:outline-none"
|
||||
>
|
||||
@ -546,10 +538,7 @@ export const CommandModal: React.FC<Props> = (props) => {
|
||||
<Command.Item
|
||||
onSelect={() => {
|
||||
closePalette();
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "v",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
commandPaletteStore.toggleCreateViewModal(true);
|
||||
}}
|
||||
className="focus:outline-none"
|
||||
>
|
||||
@ -564,10 +553,7 @@ export const CommandModal: React.FC<Props> = (props) => {
|
||||
<Command.Item
|
||||
onSelect={() => {
|
||||
closePalette();
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "d",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
commandPaletteStore.toggleCreatePageModal(true);
|
||||
}}
|
||||
className="focus:outline-none"
|
||||
>
|
||||
@ -621,10 +607,7 @@ export const CommandModal: React.FC<Props> = (props) => {
|
||||
<Command.Item
|
||||
onSelect={() => {
|
||||
closePalette();
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "h",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
commandPaletteStore.toggleShortcutModal(true);
|
||||
}}
|
||||
className="focus:outline-none"
|
||||
>
|
||||
@ -762,4 +745,4 @@ export const CommandModal: React.FC<Props> = (props) => {
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
@ -1,10 +1,12 @@
|
||||
import { MouseEvent } from "react";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import useSWR from "swr";
|
||||
// mobx store
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
// hooks
|
||||
import useToast from "hooks/use-toast";
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
// ui
|
||||
import { SingleProgressStats } from "components/core";
|
||||
import {
|
||||
@ -25,7 +27,6 @@ import { ActiveCycleProgressStats } from "components/cycles";
|
||||
import { ViewIssueLabel } from "components/issues";
|
||||
// icons
|
||||
import { AlarmClock, AlertTriangle, ArrowRight, CalendarDays, Star, Target } from "lucide-react";
|
||||
|
||||
// helpers
|
||||
import { getDateRangeStatus, renderShortDateWithYearFormat, findHowManyDaysLeft } from "helpers/date-time.helper";
|
||||
import { truncateText } from "helpers/string.helper";
|
||||
@ -65,12 +66,12 @@ interface IActiveCycleDetails {
|
||||
projectId: string;
|
||||
}
|
||||
|
||||
export const ActiveCycleDetails: React.FC<IActiveCycleDetails> = (props) => {
|
||||
export const ActiveCycleDetails: React.FC<IActiveCycleDetails> = observer((props) => {
|
||||
const router = useRouter();
|
||||
|
||||
const { workspaceSlug, projectId } = props;
|
||||
|
||||
const { cycle: cycleStore } = useMobxStore();
|
||||
const { cycle: cycleStore, commandPalette: commandPaletteStore } = useMobxStore();
|
||||
|
||||
const { setToastAlert } = useToast();
|
||||
|
||||
@ -117,12 +118,7 @@ export const ActiveCycleDetails: React.FC<IActiveCycleDetails> = (props) => {
|
||||
<button
|
||||
type="button"
|
||||
className="text-custom-primary-100 text-sm outline-none"
|
||||
onClick={() => {
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "q",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
}}
|
||||
onClick={() => commandPaletteStore.toggleCreateCycleModal(true)}
|
||||
>
|
||||
Create a new cycle
|
||||
</button>
|
||||
@ -485,4 +481,4 @@ export const ActiveCycleDetails: React.FC<IActiveCycleDetails> = (props) => {
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
@ -1,8 +1,11 @@
|
||||
import { FC } from "react";
|
||||
// types
|
||||
import { ICycle } from "types";
|
||||
import { observer } from "mobx-react-lite";
|
||||
// mobx store
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
// components
|
||||
import { CyclePeekOverview, CyclesBoardCard } from "components/cycles";
|
||||
// types
|
||||
import { ICycle } from "types";
|
||||
|
||||
export interface ICyclesBoard {
|
||||
cycles: ICycle[];
|
||||
@ -12,9 +15,11 @@ export interface ICyclesBoard {
|
||||
peekCycle: string;
|
||||
}
|
||||
|
||||
export const CyclesBoard: FC<ICyclesBoard> = (props) => {
|
||||
export const CyclesBoard: FC<ICyclesBoard> = observer((props) => {
|
||||
const { cycles, filter, workspaceSlug, projectId, peekCycle } = props;
|
||||
|
||||
const { commandPalette: commandPaletteStore } = useMobxStore();
|
||||
|
||||
return (
|
||||
<>
|
||||
{cycles.length > 0 ? (
|
||||
@ -53,12 +58,7 @@ export const CyclesBoard: FC<ICyclesBoard> = (props) => {
|
||||
<button
|
||||
type="button"
|
||||
className="text-custom-primary-100 text-sm outline-none"
|
||||
onClick={() => {
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "q",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
}}
|
||||
onClick={() => commandPaletteStore.toggleCreateCycleModal(true)}
|
||||
>
|
||||
Create a new cycle
|
||||
</button>
|
||||
@ -67,4 +67,4 @@ export const CyclesBoard: FC<ICyclesBoard> = (props) => {
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
@ -1,7 +1,9 @@
|
||||
import { FC } from "react";
|
||||
import { observer } from "mobx-react-lite";
|
||||
// mobx store
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
// components
|
||||
import { CyclePeekOverview, CyclesListItem } from "components/cycles";
|
||||
|
||||
// ui
|
||||
import { Loader } from "@plane/ui";
|
||||
// types
|
||||
@ -14,9 +16,11 @@ export interface ICyclesList {
|
||||
projectId: string;
|
||||
}
|
||||
|
||||
export const CyclesList: FC<ICyclesList> = (props) => {
|
||||
export const CyclesList: FC<ICyclesList> = observer((props) => {
|
||||
const { cycles, filter, workspaceSlug, projectId } = props;
|
||||
|
||||
const { commandPalette: commandPaletteStore } = useMobxStore();
|
||||
|
||||
return (
|
||||
<>
|
||||
{cycles ? (
|
||||
@ -53,12 +57,7 @@ export const CyclesList: FC<ICyclesList> = (props) => {
|
||||
<button
|
||||
type="button"
|
||||
className="text-custom-primary-100 text-sm outline-none"
|
||||
onClick={() => {
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "q",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
}}
|
||||
onClick={() => commandPaletteStore.toggleCreateCycleModal(true)}
|
||||
>
|
||||
Create a new cycle
|
||||
</button>
|
||||
@ -75,4 +74,4 @@ export const CyclesList: FC<ICyclesList> = (props) => {
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
@ -317,11 +317,11 @@ export const CycleDetailsSidebar: React.FC<Props> = observer((props) => {
|
||||
<LinkIcon className="h-3 w-3 text-custom-text-300" />
|
||||
</button>
|
||||
{!isCompleted && (
|
||||
<CustomMenu width="lg" ellipsis>
|
||||
<CustomMenu width="lg" placement="bottom-end" ellipsis>
|
||||
<CustomMenu.MenuItem onClick={() => setCycleDeleteModal(true)}>
|
||||
<span className="flex items-center justify-start gap-2">
|
||||
<Trash2 className="h-4 w-4" />
|
||||
<span>Delete</span>
|
||||
<Trash2 className="h-3 w-3" />
|
||||
<span>Delete cycle</span>
|
||||
</span>
|
||||
</CustomMenu.MenuItem>
|
||||
</CustomMenu>
|
||||
|
@ -31,6 +31,7 @@ export const CycleIssuesHeader: React.FC = observer(() => {
|
||||
cycle: cycleStore,
|
||||
cycleIssueFilter: cycleIssueFilterStore,
|
||||
project: projectStore,
|
||||
commandPalette: commandPaletteStore,
|
||||
} = useMobxStore();
|
||||
const { currentProjectDetails } = projectStore;
|
||||
|
||||
@ -139,7 +140,6 @@ export const CycleIssuesHeader: React.FC = observer(() => {
|
||||
type="component"
|
||||
component={
|
||||
<CustomMenu
|
||||
placement="bottom-start"
|
||||
label={
|
||||
<>
|
||||
<ContrastIcon className="h-3 w-3" />
|
||||
@ -148,6 +148,7 @@ export const CycleIssuesHeader: React.FC = observer(() => {
|
||||
}
|
||||
className="ml-1.5 flex-shrink-0"
|
||||
width="auto"
|
||||
placement="bottom-start"
|
||||
>
|
||||
{cyclesList?.map((cycle) => (
|
||||
<CustomMenu.MenuItem
|
||||
@ -194,16 +195,7 @@ export const CycleIssuesHeader: React.FC = observer(() => {
|
||||
<Button onClick={() => setAnalyticsModal(true)} variant="neutral-primary" size="sm">
|
||||
Analytics
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "c",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
}}
|
||||
size="sm"
|
||||
prependIcon={<Plus />}
|
||||
>
|
||||
<Button onClick={() => commandPaletteStore.toggleCreateIssueModal(true)} size="sm" prependIcon={<Plus />}>
|
||||
Add Issue
|
||||
</Button>
|
||||
<button
|
||||
|
@ -1,22 +1,20 @@
|
||||
import { FC } from "react";
|
||||
import { useRouter } from "next/router";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { Plus } from "lucide-react";
|
||||
// mobx store
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
// ui
|
||||
import { Breadcrumbs, Button, ContrastIcon } from "@plane/ui";
|
||||
// helpers
|
||||
import { renderEmoji } from "helpers/emoji.helper";
|
||||
// hooks
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
|
||||
export interface ICyclesHeader {}
|
||||
|
||||
export const CyclesHeader: FC<ICyclesHeader> = (props) => {
|
||||
const {} = props;
|
||||
export const CyclesHeader: FC = observer(() => {
|
||||
// router
|
||||
const router = useRouter();
|
||||
const { workspaceSlug } = router.query;
|
||||
// store
|
||||
const { project: projectStore } = useMobxStore();
|
||||
const { project: projectStore, commandPalette: commandPaletteStore } = useMobxStore();
|
||||
const { currentProjectDetails } = projectStore;
|
||||
|
||||
return (
|
||||
@ -54,14 +52,11 @@ export const CyclesHeader: FC<ICyclesHeader> = (props) => {
|
||||
<Button
|
||||
variant="primary"
|
||||
prependIcon={<Plus />}
|
||||
onClick={() => {
|
||||
const e = new KeyboardEvent("keydown", { key: "q" });
|
||||
document.dispatchEvent(e);
|
||||
}}
|
||||
onClick={() => commandPaletteStore.toggleCreateCycleModal(true)}
|
||||
>
|
||||
Add Cycle
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
@ -31,6 +31,7 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
|
||||
module: moduleStore,
|
||||
moduleFilter: moduleFilterStore,
|
||||
project: projectStore,
|
||||
commandPalette: commandPaletteStore,
|
||||
} = useMobxStore();
|
||||
const activeLayout = issueFilterStore.userDisplayFilters.layout;
|
||||
const { currentProjectDetails } = projectStore;
|
||||
@ -146,6 +147,7 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
|
||||
}
|
||||
className="ml-1.5 flex-shrink-0"
|
||||
width="auto"
|
||||
placement="bottom-start"
|
||||
>
|
||||
{modulesList?.map((module) => (
|
||||
<CustomMenu.MenuItem
|
||||
@ -192,16 +194,7 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
|
||||
<Button onClick={() => setAnalyticsModal(true)} variant="neutral-primary" size="sm">
|
||||
Analytics
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "c",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
}}
|
||||
size="sm"
|
||||
prependIcon={<Plus />}
|
||||
>
|
||||
<Button onClick={() => commandPaletteStore.toggleCreateIssueModal(true)} size="sm" prependIcon={<Plus />}>
|
||||
Add Issue
|
||||
</Button>
|
||||
<button
|
||||
|
@ -17,7 +17,7 @@ export const ModulesListHeader: React.FC = observer(() => {
|
||||
const router = useRouter();
|
||||
const { workspaceSlug } = router.query;
|
||||
// store
|
||||
const { project: projectStore } = useMobxStore();
|
||||
const { project: projectStore, commandPalette: commandPaletteStore } = useMobxStore();
|
||||
const { currentProjectDetails } = projectStore;
|
||||
|
||||
const { storedValue: modulesView, setValue: setModulesView } = useLocalStorage("modules_view", "grid");
|
||||
@ -77,10 +77,7 @@ export const ModulesListHeader: React.FC = observer(() => {
|
||||
<Button
|
||||
variant="primary"
|
||||
prependIcon={<Plus />}
|
||||
onClick={() => {
|
||||
const e = new KeyboardEvent("keydown", { key: "m" });
|
||||
document.dispatchEvent(e);
|
||||
}}
|
||||
onClick={() => commandPaletteStore.toggleCreateModuleModal(true)}
|
||||
>
|
||||
Add Module
|
||||
</Button>
|
||||
|
@ -24,10 +24,11 @@ const pageService = new PageService();
|
||||
|
||||
export const PageDetailsHeader: FC<IPagesHeaderProps> = observer((props) => {
|
||||
const { showButton = false } = props;
|
||||
|
||||
const router = useRouter();
|
||||
const { workspaceSlug, pageId } = router.query;
|
||||
|
||||
const { project: projectStore } = useMobxStore();
|
||||
const { project: projectStore, commandPalette: commandPaletteStore } = useMobxStore();
|
||||
const { currentProjectDetails } = projectStore;
|
||||
|
||||
const { data: pageDetails } = useSWR(
|
||||
@ -78,10 +79,7 @@ export const PageDetailsHeader: FC<IPagesHeaderProps> = observer((props) => {
|
||||
variant="primary"
|
||||
prependIcon={<Plus />}
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
const e = new KeyboardEvent("keydown", { key: "d" });
|
||||
document.dispatchEvent(e);
|
||||
}}
|
||||
onClick={() => commandPaletteStore.toggleCreatePageModal(true)}
|
||||
>
|
||||
Create Page
|
||||
</Button>
|
||||
|
@ -18,7 +18,7 @@ export const PagesHeader: FC<IPagesHeaderProps> = observer((props) => {
|
||||
const router = useRouter();
|
||||
const { workspaceSlug } = router.query;
|
||||
|
||||
const { project: projectStore } = useMobxStore();
|
||||
const { project: projectStore, commandPalette: commandPaletteStore } = useMobxStore();
|
||||
const { currentProjectDetails } = projectStore;
|
||||
|
||||
return (
|
||||
@ -56,10 +56,7 @@ export const PagesHeader: FC<IPagesHeaderProps> = observer((props) => {
|
||||
variant="primary"
|
||||
prependIcon={<Plus />}
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
const e = new KeyboardEvent("keydown", { key: "d" });
|
||||
document.dispatchEvent(e);
|
||||
}}
|
||||
onClick={() => commandPaletteStore.toggleCreatePageModal(true)}
|
||||
>
|
||||
Create Page
|
||||
</Button>
|
||||
|
@ -23,7 +23,12 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
|
||||
const router = useRouter();
|
||||
const { workspaceSlug, projectId } = router.query;
|
||||
|
||||
const { issueFilter: issueFilterStore, project: projectStore, inbox: inboxStore } = useMobxStore();
|
||||
const {
|
||||
issueFilter: issueFilterStore,
|
||||
project: projectStore,
|
||||
inbox: inboxStore,
|
||||
commandPalette: commandPaletteStore,
|
||||
} = useMobxStore();
|
||||
|
||||
const activeLayout = issueFilterStore.userDisplayFilters.layout;
|
||||
|
||||
@ -198,16 +203,7 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
|
||||
<Button onClick={() => setAnalyticsModal(true)} variant="neutral-primary" size="sm">
|
||||
Analytics
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "c",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
}}
|
||||
size="sm"
|
||||
prependIcon={<Plus />}
|
||||
>
|
||||
<Button onClick={() => commandPaletteStore.toggleCreateIssueModal(true)} size="sm" prependIcon={<Plus />}>
|
||||
Add Issue
|
||||
</Button>
|
||||
</div>
|
||||
|
@ -11,7 +11,7 @@ export const ProjectsHeader = observer(() => {
|
||||
const { workspaceSlug } = router.query;
|
||||
|
||||
// store
|
||||
const { project: projectStore } = useMobxStore();
|
||||
const { project: projectStore, commandPalette: commandPaletteStore } = useMobxStore();
|
||||
|
||||
const projectsList = workspaceSlug ? projectStore.projects[workspaceSlug.toString()] : [];
|
||||
|
||||
@ -43,14 +43,7 @@ export const ProjectsHeader = observer(() => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<Button
|
||||
prependIcon={<Plus />}
|
||||
size="md"
|
||||
onClick={() => {
|
||||
const e = new KeyboardEvent("keydown", { key: "p" });
|
||||
document.dispatchEvent(e);
|
||||
}}
|
||||
>
|
||||
<Button prependIcon={<Plus />} size="md" onClick={() => commandPaletteStore.toggleCreateProjectModal(true)}>
|
||||
Add Project
|
||||
</Button>
|
||||
</div>
|
||||
|
@ -16,15 +16,14 @@ export const JiraGetImportDetail: React.FC = observer(() => {
|
||||
const router = useRouter();
|
||||
const { workspaceSlug } = router.query;
|
||||
|
||||
const { project: projectStore, commandPalette: commandPaletteStore } = useMobxStore();
|
||||
const projects = workspaceSlug ? projectStore.projects[workspaceSlug.toString()] : undefined;
|
||||
|
||||
const {
|
||||
control,
|
||||
formState: { errors },
|
||||
} = useFormContext<IJiraImporterForm>();
|
||||
|
||||
const { project: projectStore } = useMobxStore();
|
||||
|
||||
const projects = workspaceSlug ? projectStore.projects[workspaceSlug.toString()] : undefined;
|
||||
|
||||
return (
|
||||
<div className="h-full w-full space-y-8 overflow-y-auto">
|
||||
<div className="grid grid-cols-1 gap-10 md:grid-cols-2">
|
||||
@ -190,10 +189,7 @@ export const JiraGetImportDetail: React.FC = observer(() => {
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
const event = new KeyboardEvent("keydown", { key: "p" });
|
||||
document.dispatchEvent(event);
|
||||
}}
|
||||
onClick={() => commandPaletteStore.toggleCreateProjectModal(true)}
|
||||
className="flex cursor-pointer select-none items-center space-x-2 truncate rounded px-1 py-1.5 text-custom-text-200"
|
||||
>
|
||||
<Plus className="h-4 w-4 text-custom-text-200" />
|
||||
|
@ -26,7 +26,7 @@ export const CycleEmptyState: React.FC<Props> = observer((props) => {
|
||||
// states
|
||||
const [cycleIssuesListModal, setCycleIssuesListModal] = useState(false);
|
||||
|
||||
const { cycleIssue: cycleIssueStore } = useMobxStore();
|
||||
const { cycleIssue: cycleIssueStore, commandPalette: commandPaletteStore } = useMobxStore();
|
||||
|
||||
const { setToastAlert } = useToast();
|
||||
|
||||
@ -62,12 +62,7 @@ export const CycleEmptyState: React.FC<Props> = observer((props) => {
|
||||
primaryButton={{
|
||||
text: "New issue",
|
||||
icon: <PlusIcon className="h-3 w-3" strokeWidth={2} />,
|
||||
onClick: () => {
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "c",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
},
|
||||
onClick: () => commandPaletteStore.toggleCreateIssueModal(true),
|
||||
}}
|
||||
secondaryButton={
|
||||
<Button
|
||||
|
@ -1,25 +1,27 @@
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { PlusIcon } from "lucide-react";
|
||||
// mobx store
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
// components
|
||||
import { EmptyState } from "components/common";
|
||||
// assets
|
||||
import emptyIssue from "public/empty-state/issue.svg";
|
||||
|
||||
export const GlobalViewEmptyState: React.FC = () => (
|
||||
<div className="h-full w-full grid place-items-center">
|
||||
<EmptyState
|
||||
title="View issues will appear here"
|
||||
description="Issues help you track individual pieces of work. With Issues, keep track of what's going on, who is working on it, and what's done."
|
||||
image={emptyIssue}
|
||||
primaryButton={{
|
||||
text: "New issue",
|
||||
icon: <PlusIcon className="h-3 w-3" strokeWidth={2} />,
|
||||
onClick: () => {
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "c",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
export const GlobalViewEmptyState: React.FC = observer(() => {
|
||||
const { commandPalette: commandPaletteStore } = useMobxStore();
|
||||
|
||||
return (
|
||||
<div className="h-full w-full grid place-items-center">
|
||||
<EmptyState
|
||||
title="View issues will appear here"
|
||||
description="Issues help you track individual pieces of work. With Issues, keep track of what's going on, who is working on it, and what's done."
|
||||
image={emptyIssue}
|
||||
primaryButton={{
|
||||
text: "New issue",
|
||||
icon: <PlusIcon className="h-3 w-3" strokeWidth={2} />,
|
||||
onClick: () => commandPaletteStore.toggleCreateIssueModal(true),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
@ -22,7 +22,7 @@ export const ModuleEmptyState: React.FC<Props> = observer((props) => {
|
||||
// states
|
||||
const [moduleIssuesListModal, setModuleIssuesListModal] = useState(false);
|
||||
|
||||
const { moduleIssue: moduleIssueStore } = useMobxStore();
|
||||
const { moduleIssue: moduleIssueStore, commandPalette: commandPaletteStore } = useMobxStore();
|
||||
|
||||
const { setToastAlert } = useToast();
|
||||
|
||||
@ -58,12 +58,7 @@ export const ModuleEmptyState: React.FC<Props> = observer((props) => {
|
||||
primaryButton={{
|
||||
text: "New issue",
|
||||
icon: <PlusIcon className="h-3 w-3" strokeWidth={2} />,
|
||||
onClick: () => {
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "c",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
},
|
||||
onClick: () => commandPaletteStore.toggleCreateIssueModal(true),
|
||||
}}
|
||||
secondaryButton={
|
||||
<Button
|
||||
|
@ -1,25 +1,27 @@
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { PlusIcon } from "lucide-react";
|
||||
// mobx store
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
// components
|
||||
import { EmptyState } from "components/common";
|
||||
// assets
|
||||
import emptyIssue from "public/empty-state/issue.svg";
|
||||
|
||||
export const ProjectViewEmptyState: React.FC = () => (
|
||||
<div className="h-full w-full grid place-items-center">
|
||||
<EmptyState
|
||||
title="View issues will appear here"
|
||||
description="Issues help you track individual pieces of work. With Issues, keep track of what's going on, who is working on it, and what's done."
|
||||
image={emptyIssue}
|
||||
primaryButton={{
|
||||
text: "New issue",
|
||||
icon: <PlusIcon className="h-3 w-3" strokeWidth={2} />,
|
||||
onClick: () => {
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "c",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
export const ProjectViewEmptyState: React.FC = observer(() => {
|
||||
const { commandPalette: commandPaletteStore } = useMobxStore();
|
||||
|
||||
return (
|
||||
<div className="h-full w-full grid place-items-center">
|
||||
<EmptyState
|
||||
title="View issues will appear here"
|
||||
description="Issues help you track individual pieces of work. With Issues, keep track of what's going on, who is working on it, and what's done."
|
||||
image={emptyIssue}
|
||||
primaryButton={{
|
||||
text: "New issue",
|
||||
icon: <PlusIcon className="h-3 w-3" strokeWidth={2} />,
|
||||
onClick: () => commandPaletteStore.toggleCreateIssueModal(true),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
@ -1,25 +1,27 @@
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { PlusIcon } from "lucide-react";
|
||||
// mobx store
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
// components
|
||||
import { EmptyState } from "components/common";
|
||||
// assets
|
||||
import emptyIssue from "public/empty-state/issue.svg";
|
||||
|
||||
export const ProjectEmptyState: React.FC = () => (
|
||||
<div className="h-full w-full grid place-items-center">
|
||||
<EmptyState
|
||||
title="Project issues will appear here"
|
||||
description="Issues help you track individual pieces of work. With Issues, keep track of what's going on, who is working on it, and what's done."
|
||||
image={emptyIssue}
|
||||
primaryButton={{
|
||||
text: "New issue",
|
||||
icon: <PlusIcon className="h-3 w-3" strokeWidth={2} />,
|
||||
onClick: () => {
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "c",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
export const ProjectEmptyState: React.FC = observer(() => {
|
||||
const { commandPalette: commandPaletteStore } = useMobxStore();
|
||||
|
||||
return (
|
||||
<div className="h-full w-full grid place-items-center">
|
||||
<EmptyState
|
||||
title="Project issues will appear here"
|
||||
description="Issues help you track individual pieces of work. With Issues, keep track of what's going on, who is working on it, and what's done."
|
||||
image={emptyIssue}
|
||||
primaryButton={{
|
||||
text: "New issue",
|
||||
icon: <PlusIcon className="h-3 w-3" strokeWidth={2} />,
|
||||
onClick: () => commandPaletteStore.toggleCreateIssueModal(true),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
@ -17,7 +17,7 @@ export const ModulesListView: React.FC = observer(() => {
|
||||
const router = useRouter();
|
||||
const { workspaceSlug, projectId, peekModule } = router.query;
|
||||
|
||||
const { module: moduleStore } = useMobxStore();
|
||||
const { module: moduleStore, commandPalette: commandPaletteStore } = useMobxStore();
|
||||
|
||||
const { storedValue: modulesView } = useLocalStorage("modules_view", "grid");
|
||||
|
||||
@ -85,12 +85,7 @@ export const ModulesListView: React.FC = observer(() => {
|
||||
primaryButton={{
|
||||
icon: <Plus className="h-4 w-4" />,
|
||||
text: "New Module",
|
||||
onClick: () => {
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "m",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
},
|
||||
onClick: () => commandPaletteStore.toggleCreateModuleModal(true),
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
@ -246,11 +246,11 @@ export const ModuleDetailsSidebar: React.FC<Props> = observer((props) => {
|
||||
<button onClick={handleCopyText}>
|
||||
<LinkIcon className="h-3 w-3 text-custom-text-300" />
|
||||
</button>
|
||||
<CustomMenu width="lg" ellipsis>
|
||||
<CustomMenu width="lg" placement="bottom-end" ellipsis>
|
||||
<CustomMenu.MenuItem onClick={() => setModuleDeleteModal(true)}>
|
||||
<span className="flex items-center justify-start gap-2">
|
||||
<Trash2 className="h-4 w-4" />
|
||||
<span>Delete</span>
|
||||
<Trash2 className="h-3 w-3" />
|
||||
<span>Delete module</span>
|
||||
</span>
|
||||
</CustomMenu.MenuItem>
|
||||
</CustomMenu>
|
||||
|
@ -18,7 +18,8 @@ export const WorkspaceDashboardView = observer(() => {
|
||||
const router = useRouter();
|
||||
const { workspaceSlug } = router.query;
|
||||
// store
|
||||
const { user: userStore, project: projectStore } = useMobxStore();
|
||||
const { user: userStore, project: projectStore, commandPalette: commandPaletteStore } = useMobxStore();
|
||||
|
||||
const user = userStore.currentUser;
|
||||
const projects = workspaceSlug ? projectStore.projects[workspaceSlug.toString()] : null;
|
||||
const workspaceDashboardInfo = userStore.dashboardInfo;
|
||||
@ -67,16 +68,7 @@ export const WorkspaceDashboardView = observer(() => {
|
||||
<div className="p-5 md:p-8 pr-0">
|
||||
<h5 className="text-xl font-semibold">Create a project</h5>
|
||||
<p className="mt-2 mb-5">Manage your projects by creating issues, cycles, modules, views and pages.</p>
|
||||
<Button
|
||||
variant="primary"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "p",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
}}
|
||||
>
|
||||
<Button variant="primary" size="sm" onClick={() => commandPaletteStore.toggleCreateProjectModal(true)}>
|
||||
Create Project
|
||||
</Button>
|
||||
</div>
|
||||
|
@ -1,19 +1,18 @@
|
||||
import React from "react";
|
||||
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
import { observer } from "mobx-react-lite";
|
||||
import useSWR from "swr";
|
||||
|
||||
import { Plus } from "lucide-react";
|
||||
// mobx store
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
// services
|
||||
import { PageService } from "services/page.service";
|
||||
// components
|
||||
import { PagesView } from "components/pages";
|
||||
// ui
|
||||
import { EmptyState } from "components/common";
|
||||
// ui
|
||||
import { Loader } from "@plane/ui";
|
||||
// icons
|
||||
import { Plus } from "lucide-react";
|
||||
// images
|
||||
// assets
|
||||
import emptyPage from "public/empty-state/page.svg";
|
||||
// helpers
|
||||
import { replaceUnderscoreIfSnakeCase } from "helpers/string.helper";
|
||||
@ -26,7 +25,11 @@ import { RECENT_PAGES_LIST } from "constants/fetch-keys";
|
||||
// services
|
||||
const pageService = new PageService();
|
||||
|
||||
export const RecentPagesList: React.FC<TPagesListProps> = ({ viewType }) => {
|
||||
export const RecentPagesList: React.FC<TPagesListProps> = observer((props) => {
|
||||
const { viewType } = props;
|
||||
|
||||
const { commandPalette: commandPaletteStore } = useMobxStore();
|
||||
|
||||
const router = useRouter();
|
||||
const { workspaceSlug, projectId } = router.query;
|
||||
|
||||
@ -46,9 +49,7 @@ export const RecentPagesList: React.FC<TPagesListProps> = ({ viewType }) => {
|
||||
|
||||
return (
|
||||
<div key={key} className="h-full overflow-hidden pb-9">
|
||||
<h2 className="text-xl font-semibold capitalize mb-2">
|
||||
{replaceUnderscoreIfSnakeCase(key)}
|
||||
</h2>
|
||||
<h2 className="text-xl font-semibold capitalize mb-2">{replaceUnderscoreIfSnakeCase(key)}</h2>
|
||||
<PagesView pages={pages[key as keyof RecentPagesResponse]} viewType={viewType} />
|
||||
</div>
|
||||
);
|
||||
@ -61,12 +62,7 @@ export const RecentPagesList: React.FC<TPagesListProps> = ({ viewType }) => {
|
||||
primaryButton={{
|
||||
icon: <Plus className="h-4 w-4" />,
|
||||
text: "New Page",
|
||||
onClick: () => {
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "d",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
},
|
||||
onClick: () => commandPaletteStore.toggleCreatePageModal(true),
|
||||
}}
|
||||
/>
|
||||
)
|
||||
@ -79,4 +75,4 @@ export const RecentPagesList: React.FC<TPagesListProps> = ({ viewType }) => {
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
@ -1,21 +1,20 @@
|
||||
import { useState } from "react";
|
||||
|
||||
import useSWR, { mutate } from "swr";
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
import { observer } from "mobx-react-lite";
|
||||
import useSWR, { mutate } from "swr";
|
||||
import { Plus } from "lucide-react";
|
||||
// mobx store
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
// services
|
||||
import { PageService } from "services/page.service";
|
||||
import { ProjectService } from "services/project";
|
||||
// hooks
|
||||
import useToast from "hooks/use-toast";
|
||||
import useUserAuth from "hooks/use-user-auth";
|
||||
// components
|
||||
import { CreateUpdatePageModal, DeletePageModal, SinglePageDetailedItem, SinglePageListItem } from "components/pages";
|
||||
// ui
|
||||
import { EmptyState } from "components/common";
|
||||
// ui
|
||||
import { Loader } from "@plane/ui";
|
||||
// icons
|
||||
import { Plus } from "lucide-react";
|
||||
// images
|
||||
import emptyPage from "public/empty-state/page.svg";
|
||||
// types
|
||||
@ -37,17 +36,19 @@ type Props = {
|
||||
const pageService = new PageService();
|
||||
const projectService = new ProjectService();
|
||||
|
||||
export const PagesView: React.FC<Props> = ({ pages, viewType }) => {
|
||||
// router
|
||||
const router = useRouter();
|
||||
const { workspaceSlug, projectId } = router.query;
|
||||
export const PagesView: React.FC<Props> = observer(({ pages, viewType }) => {
|
||||
// states
|
||||
const [createUpdatePageModal, setCreateUpdatePageModal] = useState(false);
|
||||
const [selectedPageToUpdate, setSelectedPageToUpdate] = useState<IPage | null>(null);
|
||||
const [deletePageModal, setDeletePageModal] = useState(false);
|
||||
const [selectedPageToDelete, setSelectedPageToDelete] = useState<IPage | null>(null);
|
||||
|
||||
const { user } = useUserAuth();
|
||||
const { user: userStore, commandPalette: commandPaletteStore } = useMobxStore();
|
||||
const user = userStore.currentUser ?? undefined;
|
||||
|
||||
// router
|
||||
const router = useRouter();
|
||||
const { workspaceSlug, projectId } = router.query;
|
||||
|
||||
const { setToastAlert } = useToast();
|
||||
|
||||
@ -163,7 +164,7 @@ export const PagesView: React.FC<Props> = ({ pages, viewType }) => {
|
||||
};
|
||||
|
||||
const partialUpdatePage = (page: IPage, formData: Partial<IPage>) => {
|
||||
if (!workspaceSlug || !projectId) return;
|
||||
if (!workspaceSlug || !projectId || !user) return;
|
||||
|
||||
mutate<IPage[]>(
|
||||
ALL_PAGES_LIST(projectId.toString()),
|
||||
@ -264,12 +265,7 @@ export const PagesView: React.FC<Props> = ({ pages, viewType }) => {
|
||||
primaryButton={{
|
||||
icon: <Plus className="h-4 w-4" />,
|
||||
text: "New Page",
|
||||
onClick: () => {
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "d",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
},
|
||||
onClick: () => commandPaletteStore.toggleCreatePageModal(true),
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
@ -294,4 +290,4 @@ export const PagesView: React.FC<Props> = ({ pages, viewType }) => {
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
@ -18,7 +18,7 @@ export interface IProjectCardList {
|
||||
export const ProjectCardList: FC<IProjectCardList> = observer((props) => {
|
||||
const { workspaceSlug } = props;
|
||||
// store
|
||||
const { project: projectStore } = useMobxStore();
|
||||
const { project: projectStore, commandPalette: commandPaletteStore } = useMobxStore();
|
||||
|
||||
const projects = workspaceSlug ? projectStore.projects[workspaceSlug.toString()] : null;
|
||||
|
||||
@ -53,12 +53,7 @@ export const ProjectCardList: FC<IProjectCardList> = observer((props) => {
|
||||
primaryButton={{
|
||||
icon: <Plus className="h-4 w-4" />,
|
||||
text: "New Project",
|
||||
onClick: () => {
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "p",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
},
|
||||
onClick: () => commandPaletteStore.toggleCreateProjectModal(true),
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
@ -19,11 +19,6 @@ import { IProject } from "types";
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
|
||||
export const ProjectSidebarList: FC = observer(() => {
|
||||
const { theme: themeStore, project: projectStore } = useMobxStore();
|
||||
// router
|
||||
const router = useRouter();
|
||||
const { workspaceSlug } = router.query;
|
||||
|
||||
// states
|
||||
const [isFavoriteProjectCreate, setIsFavoriteProjectCreate] = useState(false);
|
||||
const [isProjectModalOpen, setIsProjectModalOpen] = useState(false);
|
||||
@ -31,6 +26,11 @@ export const ProjectSidebarList: FC = observer(() => {
|
||||
// refs
|
||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
const { theme: themeStore, project: projectStore, commandPalette: commandPaletteStore } = useMobxStore();
|
||||
// router
|
||||
const router = useRouter();
|
||||
const { workspaceSlug } = router.query;
|
||||
|
||||
// toast
|
||||
const { setToastAlert } = useToast();
|
||||
|
||||
@ -254,12 +254,7 @@ export const ProjectSidebarList: FC = observer(() => {
|
||||
<button
|
||||
type="button"
|
||||
className="flex w-full items-center gap-2 px-3 text-sm text-custom-sidebar-text-200"
|
||||
onClick={() => {
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "p",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
}}
|
||||
onClick={() => commandPaletteStore.toggleCreateProjectModal(true)}
|
||||
>
|
||||
<Plus className="h-5 w-5" />
|
||||
{!isCollapsed && "Add Project"}
|
||||
|
@ -20,7 +20,7 @@ export const ProjectViewsList = observer(() => {
|
||||
const router = useRouter();
|
||||
const { projectId } = router.query;
|
||||
|
||||
const { projectViews: projectViewsStore } = useMobxStore();
|
||||
const { projectViews: projectViewsStore, commandPalette: commandPaletteStore } = useMobxStore();
|
||||
|
||||
const viewsList = projectId ? projectViewsStore.viewsList[projectId.toString()] : undefined;
|
||||
|
||||
@ -66,12 +66,7 @@ export const ProjectViewsList = observer(() => {
|
||||
primaryButton={{
|
||||
icon: <Plus size={14} strokeWidth={2} />,
|
||||
text: "New View",
|
||||
onClick: () => {
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "v",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
},
|
||||
onClick: () => commandPaletteStore.toggleCreateViewModal(true),
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
@ -43,7 +43,7 @@ export interface WorkspaceHelpSectionProps {
|
||||
|
||||
export const WorkspaceHelpSection: React.FC<WorkspaceHelpSectionProps> = observer(() => {
|
||||
// store
|
||||
const { theme: themeStore } = useMobxStore();
|
||||
const { theme: themeStore, commandPalette: commandPaletteStore } = useMobxStore();
|
||||
// states
|
||||
const [isNeedHelpOpen, setIsNeedHelpOpen] = useState(false);
|
||||
// refs
|
||||
@ -71,12 +71,7 @@ export const WorkspaceHelpSection: React.FC<WorkspaceHelpSectionProps> = observe
|
||||
className={`grid place-items-center rounded-md p-1.5 text-custom-text-200 hover:text-custom-text-100 hover:bg-custom-background-90 outline-none ${
|
||||
isCollapsed ? "w-full" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "h",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
}}
|
||||
onClick={() => commandPaletteStore.toggleShortcutModal(true)}
|
||||
>
|
||||
<Zap className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
|
@ -8,14 +8,18 @@ import useLocalStorage from "hooks/use-local-storage";
|
||||
import { CreateUpdateDraftIssueModal } from "components/issues";
|
||||
// mobx store
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
import { observer } from "mobx-react-lite";
|
||||
|
||||
export const WorkspaceSidebarQuickAction = () => {
|
||||
const store: any = useMobxStore();
|
||||
|
||||
export const WorkspaceSidebarQuickAction = observer(() => {
|
||||
// states
|
||||
const [isDraftIssueModalOpen, setIsDraftIssueModalOpen] = useState(false);
|
||||
|
||||
const { theme: themeStore, commandPalette: commandPaletteStore } = useMobxStore();
|
||||
|
||||
const { storedValue, clearValue } = useLocalStorage<any>("draftedIssue", JSON.stringify({}));
|
||||
|
||||
const isSidebarCollapsed = themeStore.sidebarCollapsed;
|
||||
|
||||
return (
|
||||
<>
|
||||
<CreateUpdateDraftIssueModal
|
||||
@ -31,12 +35,12 @@ export const WorkspaceSidebarQuickAction = () => {
|
||||
|
||||
<div
|
||||
className={`flex items-center justify-between w-full cursor-pointer px-4 mt-4 ${
|
||||
store?.theme?.sidebarCollapsed ? "flex-col gap-1" : "gap-2"
|
||||
isSidebarCollapsed ? "flex-col gap-1" : "gap-2"
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
className={`relative flex items-center justify-between w-full rounded cursor-pointer px-2 gap-1 group ${
|
||||
store?.theme?.sidebarCollapsed
|
||||
isSidebarCollapsed
|
||||
? "px-2 hover:bg-custom-sidebar-background-80"
|
||||
: "px-3 shadow border-[0.5px] border-custom-border-300"
|
||||
}`}
|
||||
@ -44,29 +48,22 @@ export const WorkspaceSidebarQuickAction = () => {
|
||||
<button
|
||||
type="button"
|
||||
className={`relative flex items-center gap-2 flex-grow rounded flex-shrink-0 py-1.5 ${
|
||||
store?.theme?.sidebarCollapsed ? "justify-center" : ""
|
||||
isSidebarCollapsed ? "justify-center" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
const e = new KeyboardEvent("keydown", { key: "c" });
|
||||
document.dispatchEvent(e);
|
||||
}}
|
||||
onClick={() => commandPaletteStore.toggleCreateIssueModal(true)}
|
||||
>
|
||||
<PenSquare className="h-4 w-4 text-custom-sidebar-text-300" />
|
||||
{!store?.theme?.sidebarCollapsed && <span className="text-sm font-medium">New Issue</span>}
|
||||
{!isSidebarCollapsed && <span className="text-sm font-medium">New Issue</span>}
|
||||
</button>
|
||||
|
||||
{storedValue && Object.keys(JSON.parse(storedValue)).length > 0 && (
|
||||
<>
|
||||
<div
|
||||
className={`h-8 w-0.5 bg-custom-sidebar-background-80 ${
|
||||
store?.theme?.sidebarCollapsed ? "hidden" : "block"
|
||||
}`}
|
||||
/>
|
||||
<div className={`h-8 w-0.5 bg-custom-sidebar-background-80 ${isSidebarCollapsed ? "hidden" : "block"}`} />
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className={`flex items-center justify-center rounded flex-shrink-0 py-1.5 ml-1.5 ${
|
||||
store?.theme?.sidebarCollapsed ? "hidden" : "block"
|
||||
isSidebarCollapsed ? "hidden" : "block"
|
||||
}`}
|
||||
>
|
||||
<ChevronDown
|
||||
@ -77,7 +74,7 @@ export const WorkspaceSidebarQuickAction = () => {
|
||||
|
||||
<div
|
||||
className={`fixed h-10 pt-2 w-[203px] left-4 opacity-0 group-hover:opacity-100 mt-0 pointer-events-none group-hover:pointer-events-auto ${
|
||||
store?.theme?.sidebarCollapsed ? "top-[5.5rem]" : "top-24"
|
||||
isSidebarCollapsed ? "top-[5.5rem]" : "top-24"
|
||||
}`}
|
||||
>
|
||||
<div className="w-full h-full">
|
||||
@ -96,18 +93,15 @@ export const WorkspaceSidebarQuickAction = () => {
|
||||
|
||||
<button
|
||||
className={`flex items-center justify-center rounded flex-shrink-0 p-2 ${
|
||||
store?.theme?.sidebarCollapsed
|
||||
isSidebarCollapsed
|
||||
? "hover:bg-custom-sidebar-background-80"
|
||||
: "shadow border-[0.5px] border-custom-border-300"
|
||||
}`}
|
||||
onClick={() => {
|
||||
const e = new KeyboardEvent("keydown", { key: "k", ctrlKey: true, metaKey: true });
|
||||
document.dispatchEvent(e);
|
||||
}}
|
||||
onClick={() => commandPaletteStore.toggleCommandPaletteModal(true)}
|
||||
>
|
||||
<Search className="h-4 w-4 text-custom-sidebar-text-300" />
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
@ -25,6 +25,7 @@ export const ProjectAuthWrapper: FC<IProjectAuthWrapper> = observer((props) => {
|
||||
module: moduleStore,
|
||||
projectViews: projectViewsStore,
|
||||
inbox: inboxStore,
|
||||
commandPalette: commandPaletteStore,
|
||||
} = useMobxStore();
|
||||
// router
|
||||
const router = useRouter();
|
||||
@ -131,12 +132,7 @@ export const ProjectAuthWrapper: FC<IProjectAuthWrapper> = observer((props) => {
|
||||
image={emptyProject}
|
||||
primaryButton={{
|
||||
text: "Create Project",
|
||||
onClick: () => {
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "p",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
},
|
||||
onClick: () => commandPaletteStore.toggleCreateProjectModal(true),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
@ -28,7 +28,7 @@ const AnalyticsPage: NextPageWithLayout = observer(() => {
|
||||
const router = useRouter();
|
||||
const { workspaceSlug } = router.query;
|
||||
// store
|
||||
const { project: projectStore, user: userStore } = useMobxStore();
|
||||
const { project: projectStore, user: userStore, commandPalette: commandPaletteStore } = useMobxStore();
|
||||
|
||||
const user = userStore.currentUser;
|
||||
const projects = workspaceSlug ? projectStore.projects[workspaceSlug?.toString()] : null;
|
||||
@ -96,12 +96,7 @@ const AnalyticsPage: NextPageWithLayout = observer(() => {
|
||||
primaryButton={{
|
||||
icon: <Plus className="h-4 w-4" />,
|
||||
text: "New Project",
|
||||
onClick: () => {
|
||||
const e = new KeyboardEvent("keydown", {
|
||||
key: "p",
|
||||
});
|
||||
document.dispatchEvent(e);
|
||||
},
|
||||
onClick: () => commandPaletteStore.toggleCreateProjectModal(true),
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
|
Loading…
Reference in New Issue
Block a user