snapshot of https://github.com/makeplane/plane.git @ d868349a55de79979eb8b98701bf1702c67ad634 (2026-09-15)
Some checks failed
CodeQL / Analyze (javascript) (push) Failing after 16s
CodeQL / Analyze (python) (push) Failing after 3s
i18n sync check / check:sync (push) Failing after 3s
React Doctor / react-doctor (push) Failing after 16s
Branch Build CE / Build-Push Admin Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Admin Manifest (push) Has been cancelled
Branch Build CE / Build-Push Web Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Web Manifest (push) Has been cancelled
Branch Build CE / Build-Push Space Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Proxy Manifest (push) Has been cancelled
Branch Build CE / Merge Space Manifest (push) Has been cancelled
Branch Build CE / Prepare AIO Assets (push) Has been cancelled
Branch Build CE / Build Setup (push) Has been cancelled
Branch Build CE / Build-Push Live Collaboration Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Live Collaboration Manifest (push) Has been cancelled
Branch Build CE / Build-Push API Server Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge API Server Manifest (push) Has been cancelled
Branch Build CE / Build-Push Proxy Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Build-Push AIO Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge AIO Manifest (push) Has been cancelled
Branch Build CE / Upload Build Assets (push) Has been cancelled
Branch Build CE / Build Release (push) Has been cancelled
Some checks failed
CodeQL / Analyze (javascript) (push) Failing after 16s
CodeQL / Analyze (python) (push) Failing after 3s
i18n sync check / check:sync (push) Failing after 3s
React Doctor / react-doctor (push) Failing after 16s
Branch Build CE / Build-Push Admin Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Admin Manifest (push) Has been cancelled
Branch Build CE / Build-Push Web Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Web Manifest (push) Has been cancelled
Branch Build CE / Build-Push Space Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Proxy Manifest (push) Has been cancelled
Branch Build CE / Merge Space Manifest (push) Has been cancelled
Branch Build CE / Prepare AIO Assets (push) Has been cancelled
Branch Build CE / Build Setup (push) Has been cancelled
Branch Build CE / Build-Push Live Collaboration Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Live Collaboration Manifest (push) Has been cancelled
Branch Build CE / Build-Push API Server Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge API Server Manifest (push) Has been cancelled
Branch Build CE / Build-Push Proxy Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Build-Push AIO Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge AIO Manifest (push) Has been cancelled
Branch Build CE / Upload Build Assets (push) Has been cancelled
Branch Build CE / Build Release (push) Has been cancelled
This commit is contained in:
64
apps/web/core/components/power-k/config/account-commands.ts
Normal file
64
apps/web/core/components/power-k/config/account-commands.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { useCallback } from "react";
|
||||
import { LogOutOutline, MailOutline } from "@makeplane/propel/icons";
|
||||
// plane imports
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { setToast, TOAST_TYPE } from "@plane/propel/toast";
|
||||
// components
|
||||
import type { TPowerKCommandConfig } from "@/components/power-k/core/types";
|
||||
// hooks
|
||||
import { useUser } from "@/hooks/store/user";
|
||||
import { useAppRouter } from "@/hooks/use-app-router";
|
||||
|
||||
/**
|
||||
* Account commands - Account related commands
|
||||
*/
|
||||
export const usePowerKAccountCommands = (): TPowerKCommandConfig[] => {
|
||||
// navigation
|
||||
const router = useAppRouter();
|
||||
// store
|
||||
const { signOut } = useUser();
|
||||
// translation
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleSignOut = useCallback(() => {
|
||||
signOut().catch(() =>
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: t("auth.sign_out.toast.error.title"),
|
||||
message: t("auth.sign_out.toast.error.message"),
|
||||
})
|
||||
);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [signOut]);
|
||||
|
||||
return [
|
||||
{
|
||||
id: "workspace_invites",
|
||||
type: "action",
|
||||
group: "account",
|
||||
i18n_title: "power_k.account_actions.workspace_invites",
|
||||
icon: MailOutline,
|
||||
action: () => router.push("/invitations"),
|
||||
isEnabled: () => true,
|
||||
isVisible: () => true,
|
||||
closeOnSelect: true,
|
||||
},
|
||||
{
|
||||
id: "sign_out",
|
||||
type: "action",
|
||||
group: "account",
|
||||
i18n_title: "power_k.account_actions.sign_out",
|
||||
icon: LogOutOutline,
|
||||
action: handleSignOut,
|
||||
isEnabled: () => true,
|
||||
isVisible: () => true,
|
||||
closeOnSelect: true,
|
||||
},
|
||||
];
|
||||
};
|
||||
35
apps/web/core/components/power-k/config/commands.ts
Normal file
35
apps/web/core/components/power-k/config/commands.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
// local imports
|
||||
import type { TPowerKCommandConfig } from "../core/types";
|
||||
import { usePowerKContextBasedActions } from "../ui/pages/context-based";
|
||||
import { usePowerKAccountCommands } from "./account-commands";
|
||||
import { usePowerKCreationCommands } from "./creation/root";
|
||||
import { usePowerKHelpCommands } from "./help-commands";
|
||||
import { usePowerKMiscellaneousCommands } from "./miscellaneous-commands";
|
||||
import { usePowerKNavigationCommands } from "./navigation/root";
|
||||
import { usePowerKPreferencesCommands } from "./preferences-commands";
|
||||
|
||||
export const useProjectsAppPowerKCommands = (): TPowerKCommandConfig[] => {
|
||||
const navigationCommands = usePowerKNavigationCommands();
|
||||
const creationCommands = usePowerKCreationCommands();
|
||||
const contextualCommands = usePowerKContextBasedActions();
|
||||
const accountCommands = usePowerKAccountCommands();
|
||||
const miscellaneousCommands = usePowerKMiscellaneousCommands();
|
||||
const preferencesCommands = usePowerKPreferencesCommands();
|
||||
const helpCommands = usePowerKHelpCommands();
|
||||
|
||||
return [
|
||||
...navigationCommands,
|
||||
...creationCommands,
|
||||
...contextualCommands,
|
||||
...accountCommands,
|
||||
...miscellaneousCommands,
|
||||
...preferencesCommands,
|
||||
...helpCommands,
|
||||
];
|
||||
};
|
||||
163
apps/web/core/components/power-k/config/creation/command.ts
Normal file
163
apps/web/core/components/power-k/config/creation/command.ts
Normal file
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { SquarePlus } from "lucide-react";
|
||||
import {
|
||||
CreateFolderOutline,
|
||||
CyclesOutline,
|
||||
DocumentationOutline,
|
||||
ModuleOutline,
|
||||
WorkItemsOutline,
|
||||
} from "@makeplane/propel/icons";
|
||||
// plane imports
|
||||
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
|
||||
// components
|
||||
import { EUserProjectRoles } from "@plane/types";
|
||||
import type { TPowerKCommandConfig, TPowerKContext } from "@/components/power-k/core/types";
|
||||
// hooks
|
||||
import { useCommandPalette } from "@/hooks/store/use-command-palette";
|
||||
import { useProject } from "@/hooks/store/use-project";
|
||||
import { useUser } from "@/hooks/store/user";
|
||||
import { useInstance } from "@/hooks/store/use-instance";
|
||||
|
||||
export type TPowerKCreationCommandKeys =
|
||||
| "create_work_item"
|
||||
| "create_page"
|
||||
| "create_view"
|
||||
| "create_cycle"
|
||||
| "create_module"
|
||||
| "create_project"
|
||||
| "create_workspace";
|
||||
|
||||
/**
|
||||
* Creation commands - Create any entity in the app
|
||||
*/
|
||||
export const usePowerKCreationCommandsRecord = (): Record<TPowerKCreationCommandKeys, TPowerKCommandConfig> => {
|
||||
// store
|
||||
const { config } = useInstance();
|
||||
const {
|
||||
canPerformAnyCreateAction,
|
||||
permission: { allowPermissions },
|
||||
} = useUser();
|
||||
const { workspaceProjectIds, getPartialProjectById } = useProject();
|
||||
const {
|
||||
toggleCreateIssueModal,
|
||||
toggleCreateProjectModal,
|
||||
toggleCreateCycleModal,
|
||||
toggleCreateModuleModal,
|
||||
toggleCreateViewModal,
|
||||
toggleCreatePageModal,
|
||||
} = useCommandPalette();
|
||||
// derived values
|
||||
const canCreateWorkItem = canPerformAnyCreateAction && workspaceProjectIds && workspaceProjectIds.length > 0;
|
||||
const canCreateProject = allowPermissions(
|
||||
[EUserPermissions.ADMIN, EUserPermissions.MEMBER],
|
||||
EUserPermissionsLevel.WORKSPACE
|
||||
);
|
||||
const hasProjectMemberLevelPermissions = (ctx: TPowerKContext) =>
|
||||
allowPermissions(
|
||||
[EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER],
|
||||
EUserPermissionsLevel.PROJECT,
|
||||
ctx.params.workspaceSlug?.toString(),
|
||||
ctx.params.projectId?.toString()
|
||||
);
|
||||
const isWorkspaceCreationDisabled = config?.is_workspace_creation_disabled ?? false;
|
||||
|
||||
const getProjectDetails = (ctx: TPowerKContext) =>
|
||||
ctx.params.projectId ? getPartialProjectById(ctx.params.projectId.toString()) : undefined;
|
||||
|
||||
return {
|
||||
create_work_item: {
|
||||
id: "create_work_item",
|
||||
type: "action",
|
||||
group: "create",
|
||||
i18n_title: "power_k.creation_actions.create_work_item",
|
||||
icon: WorkItemsOutline,
|
||||
keySequence: "ni",
|
||||
action: () => toggleCreateIssueModal(true),
|
||||
isEnabled: () => Boolean(canCreateWorkItem),
|
||||
isVisible: () => Boolean(canCreateWorkItem),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
create_page: {
|
||||
id: "create_page",
|
||||
type: "action",
|
||||
group: "create",
|
||||
i18n_title: "power_k.creation_actions.create_page",
|
||||
icon: DocumentationOutline,
|
||||
keySequence: "nd",
|
||||
action: () => toggleCreatePageModal({ isOpen: true }),
|
||||
isEnabled: (ctx) => Boolean(getProjectDetails(ctx)?.page_view && hasProjectMemberLevelPermissions(ctx)),
|
||||
isVisible: (ctx) =>
|
||||
Boolean(ctx.params.projectId && getProjectDetails(ctx)?.page_view && hasProjectMemberLevelPermissions(ctx)),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
create_view: {
|
||||
id: "create_view",
|
||||
type: "action",
|
||||
group: "create",
|
||||
i18n_title: "power_k.creation_actions.create_view",
|
||||
icon: WorkItemsOutline,
|
||||
keySequence: "nv",
|
||||
action: () => toggleCreateViewModal(true),
|
||||
isEnabled: (ctx) => Boolean(getProjectDetails(ctx)?.issue_views_view && hasProjectMemberLevelPermissions(ctx)),
|
||||
isVisible: (ctx) =>
|
||||
Boolean(
|
||||
ctx.params.projectId && getProjectDetails(ctx)?.issue_views_view && hasProjectMemberLevelPermissions(ctx)
|
||||
),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
create_cycle: {
|
||||
id: "create_cycle",
|
||||
type: "action",
|
||||
group: "create",
|
||||
i18n_title: "power_k.creation_actions.create_cycle",
|
||||
icon: CyclesOutline,
|
||||
keySequence: "nc",
|
||||
action: () => toggleCreateCycleModal(true),
|
||||
isEnabled: (ctx) => Boolean(getProjectDetails(ctx)?.cycle_view && hasProjectMemberLevelPermissions(ctx)),
|
||||
isVisible: (ctx) =>
|
||||
Boolean(ctx.params.projectId && getProjectDetails(ctx)?.cycle_view && hasProjectMemberLevelPermissions(ctx)),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
create_module: {
|
||||
id: "create_module",
|
||||
type: "action",
|
||||
group: "create",
|
||||
i18n_title: "power_k.creation_actions.create_module",
|
||||
icon: ModuleOutline,
|
||||
keySequence: "nm",
|
||||
action: () => toggleCreateModuleModal(true),
|
||||
isEnabled: (ctx) => Boolean(getProjectDetails(ctx)?.module_view && hasProjectMemberLevelPermissions(ctx)),
|
||||
isVisible: (ctx) =>
|
||||
Boolean(ctx.params.projectId && getProjectDetails(ctx)?.module_view && hasProjectMemberLevelPermissions(ctx)),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
create_project: {
|
||||
id: "create_project",
|
||||
type: "action",
|
||||
group: "create",
|
||||
i18n_title: "power_k.creation_actions.create_project",
|
||||
icon: CreateFolderOutline,
|
||||
keySequence: "np",
|
||||
action: () => toggleCreateProjectModal(true),
|
||||
isEnabled: () => Boolean(canCreateProject),
|
||||
isVisible: () => Boolean(canCreateProject),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
create_workspace: {
|
||||
id: "create_workspace",
|
||||
type: "action",
|
||||
group: "create",
|
||||
i18n_title: "power_k.creation_actions.create_workspace",
|
||||
icon: SquarePlus,
|
||||
action: (ctx) => ctx.router.push("/create-workspace"),
|
||||
isEnabled: () => Boolean(!isWorkspaceCreationDisabled),
|
||||
isVisible: () => Boolean(!isWorkspaceCreationDisabled),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
};
|
||||
};
|
||||
24
apps/web/core/components/power-k/config/creation/root.ts
Normal file
24
apps/web/core/components/power-k/config/creation/root.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
// types
|
||||
import type { TPowerKCommandConfig } from "@/components/power-k/core/types";
|
||||
// local imports
|
||||
import { usePowerKCreationCommandsRecord } from "./command";
|
||||
import type { TPowerKCreationCommandKeys } from "./command";
|
||||
|
||||
export const usePowerKCreationCommands = (): TPowerKCommandConfig[] => {
|
||||
const optionsList: Record<TPowerKCreationCommandKeys, TPowerKCommandConfig> = usePowerKCreationCommandsRecord();
|
||||
return [
|
||||
optionsList["create_work_item"],
|
||||
optionsList["create_page"],
|
||||
optionsList["create_view"],
|
||||
optionsList["create_cycle"],
|
||||
optionsList["create_module"],
|
||||
optionsList["create_project"],
|
||||
optionsList["create_workspace"],
|
||||
];
|
||||
};
|
||||
73
apps/web/core/components/power-k/config/help-commands.ts
Normal file
73
apps/web/core/components/power-k/config/help-commands.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { ChatOutline, DocumentationOutline, Github, RocketOutline } from "@makeplane/propel/icons";
|
||||
// components
|
||||
import type { TPowerKCommandConfig } from "@/components/power-k/core/types";
|
||||
// hooks
|
||||
import { usePowerK } from "@/hooks/store/use-power-k";
|
||||
|
||||
/**
|
||||
* Help commands - Help related commands
|
||||
*/
|
||||
export const usePowerKHelpCommands = (): TPowerKCommandConfig[] => {
|
||||
// store
|
||||
const { toggleShortcutsListModal } = usePowerK();
|
||||
|
||||
return [
|
||||
{
|
||||
id: "open_keyboard_shortcuts",
|
||||
type: "action",
|
||||
group: "help",
|
||||
i18n_title: "power_k.help_actions.open_keyboard_shortcuts",
|
||||
icon: RocketOutline,
|
||||
modifierShortcut: "cmd+/",
|
||||
action: () => toggleShortcutsListModal(true),
|
||||
isEnabled: () => true,
|
||||
isVisible: () => true,
|
||||
closeOnSelect: true,
|
||||
},
|
||||
{
|
||||
id: "open_plane_documentation",
|
||||
type: "action",
|
||||
group: "help",
|
||||
i18n_title: "power_k.help_actions.open_plane_documentation",
|
||||
icon: DocumentationOutline,
|
||||
action: () => {
|
||||
window.open("https://docs.plane.so/", "_blank", "noopener,noreferrer");
|
||||
},
|
||||
isEnabled: () => true,
|
||||
isVisible: () => true,
|
||||
closeOnSelect: true,
|
||||
},
|
||||
{
|
||||
id: "join_forum",
|
||||
type: "action",
|
||||
group: "help",
|
||||
i18n_title: "power_k.help_actions.join_forum",
|
||||
icon: ChatOutline,
|
||||
action: () => {
|
||||
window.open("https://forum.plane.so", "_blank", "noopener,noreferrer");
|
||||
},
|
||||
isEnabled: () => true,
|
||||
isVisible: () => true,
|
||||
closeOnSelect: true,
|
||||
},
|
||||
{
|
||||
id: "report_bug",
|
||||
type: "action",
|
||||
group: "help",
|
||||
i18n_title: "power_k.help_actions.report_bug",
|
||||
icon: Github,
|
||||
action: () => {
|
||||
window.open("https://github.com/makeplane/plane/issues/new/choose", "_blank", "noopener,noreferrer");
|
||||
},
|
||||
isEnabled: () => true,
|
||||
isVisible: () => true,
|
||||
closeOnSelect: true,
|
||||
},
|
||||
];
|
||||
};
|
||||
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { useCallback } from "react";
|
||||
import { LeftSidePaneOutline, LinkOutline, SearchOutline } from "@makeplane/propel/icons";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
// plane imports
|
||||
import { setToast, TOAST_TYPE } from "@plane/propel/toast";
|
||||
import { copyTextToClipboard } from "@plane/utils";
|
||||
// components
|
||||
import type { TPowerKCommandConfig } from "@/components/power-k/core/types";
|
||||
// hooks
|
||||
import { useAppTheme } from "@/hooks/store/use-app-theme";
|
||||
import { usePowerK } from "@/hooks/store/use-power-k";
|
||||
|
||||
export const usePowerKMiscellaneousCommands = (): TPowerKCommandConfig[] => {
|
||||
// store hooks
|
||||
const { toggleSidebar } = useAppTheme();
|
||||
const { topNavInputRef, topNavSearchInputRef } = usePowerK();
|
||||
// translation
|
||||
const { t } = useTranslation();
|
||||
|
||||
const copyCurrentPageUrlToClipboard = useCallback(() => {
|
||||
const url = new URL(window.location.href);
|
||||
copyTextToClipboard(url.href)
|
||||
.then(() => {
|
||||
setToast({
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
title: t("power_k.miscellaneous_actions.copy_current_page_url_toast_success"),
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: t("power_k.miscellaneous_actions.copy_current_page_url_toast_error"),
|
||||
});
|
||||
});
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
const focusTopNavSearch = useCallback(() => {
|
||||
// Focus PowerK input if available, otherwise focus regular search input
|
||||
if (topNavSearchInputRef?.current) {
|
||||
topNavSearchInputRef.current.focus();
|
||||
} else if (topNavInputRef?.current) {
|
||||
topNavInputRef.current.focus();
|
||||
}
|
||||
}, [topNavInputRef, topNavSearchInputRef]);
|
||||
|
||||
return [
|
||||
{
|
||||
id: "toggle_app_sidebar",
|
||||
group: "miscellaneous",
|
||||
type: "action",
|
||||
i18n_title: "power_k.miscellaneous_actions.toggle_app_sidebar",
|
||||
icon: LeftSidePaneOutline,
|
||||
action: () => toggleSidebar(),
|
||||
modifierShortcut: "cmd+b",
|
||||
isEnabled: () => true,
|
||||
isVisible: () => true,
|
||||
closeOnSelect: true,
|
||||
},
|
||||
{
|
||||
id: "copy_current_page_url",
|
||||
group: "miscellaneous",
|
||||
type: "action",
|
||||
i18n_title: "power_k.miscellaneous_actions.copy_current_page_url",
|
||||
icon: LinkOutline,
|
||||
action: copyCurrentPageUrlToClipboard,
|
||||
modifierShortcut: "cmd+shift+c",
|
||||
isEnabled: () => true,
|
||||
isVisible: () => true,
|
||||
closeOnSelect: true,
|
||||
},
|
||||
{
|
||||
id: "focus_top_nav_search",
|
||||
group: "miscellaneous",
|
||||
type: "action",
|
||||
i18n_title: "power_k.miscellaneous_actions.focus_top_nav_search",
|
||||
icon: SearchOutline,
|
||||
action: focusTopNavSearch,
|
||||
modifierShortcut: "cmd+f",
|
||||
isEnabled: () => true,
|
||||
isVisible: () => true,
|
||||
closeOnSelect: true,
|
||||
},
|
||||
];
|
||||
};
|
||||
538
apps/web/core/components/power-k/config/navigation/commands.ts
Normal file
538
apps/web/core/components/power-k/config/navigation/commands.ts
Normal file
@@ -0,0 +1,538 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import {
|
||||
ActivityOutline,
|
||||
ArchiveOutline,
|
||||
BarOutline,
|
||||
CyclesOutline,
|
||||
DocumentationOutline,
|
||||
EditOutline,
|
||||
HomeOutline,
|
||||
InboxOutline,
|
||||
IntakeOutline,
|
||||
ModuleOutline,
|
||||
ProjectsOutline,
|
||||
SettingsOutline,
|
||||
WorkItemsOutline,
|
||||
} from "@makeplane/propel/icons";
|
||||
// plane imports
|
||||
import { EUserPermissionsLevel } from "@plane/constants";
|
||||
import type { ICycle, IModule, IPartialProject, IProjectView, IWorkspace } from "@plane/types";
|
||||
import { EUserProjectRoles, EUserWorkspaceRoles } from "@plane/types";
|
||||
// components
|
||||
import type { TPowerKCommandConfig, TPowerKContext } from "@/components/power-k/core/types";
|
||||
import { handlePowerKNavigate } from "@/components/power-k/utils/navigation";
|
||||
// hooks
|
||||
import { useProject } from "@/hooks/store/use-project";
|
||||
import { useUser } from "@/hooks/store/user";
|
||||
|
||||
export type TPowerKNavigationCommandKeys =
|
||||
| "open_workspace"
|
||||
| "nav_home"
|
||||
| "nav_inbox"
|
||||
| "nav_your_work"
|
||||
| "nav_account_settings"
|
||||
| "open_project"
|
||||
| "nav_projects_list"
|
||||
| "nav_all_workspace_work_items"
|
||||
| "nav_assigned_workspace_work_items"
|
||||
| "nav_created_workspace_work_items"
|
||||
| "nav_subscribed_workspace_work_items"
|
||||
| "nav_workspace_analytics"
|
||||
| "nav_workspace_drafts"
|
||||
| "nav_workspace_archives"
|
||||
| "open_workspace_setting"
|
||||
| "nav_workspace_settings"
|
||||
| "nav_project_work_items"
|
||||
| "open_project_cycle"
|
||||
| "nav_project_cycles"
|
||||
| "open_project_module"
|
||||
| "nav_project_modules"
|
||||
| "open_project_view"
|
||||
| "nav_project_views"
|
||||
| "nav_project_pages"
|
||||
| "nav_project_intake"
|
||||
| "nav_project_archives"
|
||||
| "open_project_setting"
|
||||
| "nav_project_settings";
|
||||
|
||||
/**
|
||||
* Navigation commands - Navigate to all pages in the app
|
||||
*/
|
||||
export const usePowerKNavigationCommandsRecord = (): Record<TPowerKNavigationCommandKeys, TPowerKCommandConfig> => {
|
||||
// store hooks
|
||||
const {
|
||||
data: currentUser,
|
||||
permission: { allowPermissions },
|
||||
} = useUser();
|
||||
const { getPartialProjectById } = useProject();
|
||||
// derived values
|
||||
const hasWorkspaceMemberLevelPermissions = (ctx: TPowerKContext) =>
|
||||
allowPermissions(
|
||||
[EUserWorkspaceRoles.ADMIN, EUserWorkspaceRoles.MEMBER],
|
||||
EUserPermissionsLevel.WORKSPACE,
|
||||
ctx.params.workspaceSlug?.toString()
|
||||
);
|
||||
const hasProjectMemberLevelPermissions = (ctx: TPowerKContext) =>
|
||||
allowPermissions(
|
||||
[EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER],
|
||||
EUserPermissionsLevel.PROJECT,
|
||||
ctx.params.workspaceSlug?.toString(),
|
||||
ctx.params.projectId?.toString()
|
||||
);
|
||||
const baseWorkspaceConditions = (ctx: TPowerKContext) => Boolean(ctx.params.workspaceSlug?.toString());
|
||||
const baseProjectConditions = (ctx: TPowerKContext) =>
|
||||
Boolean(ctx.params.workspaceSlug?.toString() && ctx.params.projectId?.toString());
|
||||
const getContextProject = (ctx: TPowerKContext) => getPartialProjectById(ctx.params.projectId?.toString());
|
||||
|
||||
return {
|
||||
open_workspace: {
|
||||
id: "open_workspace",
|
||||
type: "change-page",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.open_workspace",
|
||||
icon: ProjectsOutline,
|
||||
keySequence: "ow",
|
||||
page: "open-workspace",
|
||||
onSelect: (data, ctx) => {
|
||||
const workspaceDetails = data as IWorkspace;
|
||||
handlePowerKNavigate(ctx, [workspaceDetails.slug]);
|
||||
},
|
||||
isEnabled: (ctx) => baseWorkspaceConditions(ctx),
|
||||
isVisible: (ctx) => baseWorkspaceConditions(ctx),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
nav_home: {
|
||||
id: "nav_home",
|
||||
type: "action",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.nav_home",
|
||||
icon: HomeOutline,
|
||||
keySequence: "gh",
|
||||
action: (ctx) => handlePowerKNavigate(ctx, [ctx.params.workspaceSlug?.toString()]),
|
||||
isEnabled: (ctx) => baseWorkspaceConditions(ctx),
|
||||
isVisible: (ctx) => baseWorkspaceConditions(ctx),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
nav_inbox: {
|
||||
id: "nav_inbox",
|
||||
type: "action",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.nav_inbox",
|
||||
icon: InboxOutline,
|
||||
keySequence: "gx",
|
||||
action: (ctx) => handlePowerKNavigate(ctx, [ctx.params.workspaceSlug?.toString(), "notifications"]),
|
||||
isEnabled: (ctx) => baseWorkspaceConditions(ctx),
|
||||
isVisible: (ctx) => baseWorkspaceConditions(ctx),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
nav_your_work: {
|
||||
id: "nav_your_work",
|
||||
type: "action",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.nav_your_work",
|
||||
icon: ActivityOutline,
|
||||
keySequence: "gy",
|
||||
action: (ctx) => handlePowerKNavigate(ctx, [ctx.params.workspaceSlug?.toString(), "profile", currentUser?.id]),
|
||||
isEnabled: (ctx) => baseWorkspaceConditions(ctx) && hasWorkspaceMemberLevelPermissions(ctx),
|
||||
isVisible: (ctx) => baseWorkspaceConditions(ctx) && hasWorkspaceMemberLevelPermissions(ctx),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
nav_account_settings: {
|
||||
id: "nav_account_settings",
|
||||
type: "action",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.nav_account_settings",
|
||||
icon: SettingsOutline,
|
||||
action: (ctx) => handlePowerKNavigate(ctx, [ctx.params.workspaceSlug?.toString(), "settings", "account"]),
|
||||
isEnabled: (ctx) => baseWorkspaceConditions(ctx),
|
||||
isVisible: (ctx) => baseWorkspaceConditions(ctx),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
open_project: {
|
||||
id: "open_project",
|
||||
type: "change-page",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.open_project",
|
||||
icon: ProjectsOutline,
|
||||
keySequence: "op",
|
||||
page: "open-project",
|
||||
onSelect: (data, ctx) => {
|
||||
const projectDetails = data as IPartialProject;
|
||||
handlePowerKNavigate(ctx, [ctx.params.workspaceSlug?.toString(), "projects", projectDetails.id, "issues"]);
|
||||
},
|
||||
isEnabled: (ctx) => baseWorkspaceConditions(ctx),
|
||||
isVisible: (ctx) => baseWorkspaceConditions(ctx),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
nav_projects_list: {
|
||||
id: "nav_projects_list",
|
||||
type: "action",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.nav_projects_list",
|
||||
icon: ProjectsOutline,
|
||||
keySequence: "gp",
|
||||
action: (ctx) => handlePowerKNavigate(ctx, [ctx.params.workspaceSlug?.toString(), "projects"]),
|
||||
isEnabled: (ctx) => baseWorkspaceConditions(ctx),
|
||||
isVisible: (ctx) => baseWorkspaceConditions(ctx),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
nav_all_workspace_work_items: {
|
||||
id: "nav_all_workspace_work_items",
|
||||
type: "action",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.nav_all_workspace_work_items",
|
||||
icon: WorkItemsOutline,
|
||||
action: (ctx) =>
|
||||
handlePowerKNavigate(ctx, [ctx.params.workspaceSlug?.toString(), "workspace-views", "all-issues"]),
|
||||
isEnabled: (ctx) => baseWorkspaceConditions(ctx),
|
||||
isVisible: (ctx) => baseWorkspaceConditions(ctx),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
nav_assigned_workspace_work_items: {
|
||||
id: "nav_assigned_workspace_work_items",
|
||||
type: "action",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.nav_assigned_workspace_work_items",
|
||||
icon: WorkItemsOutline,
|
||||
action: (ctx) => handlePowerKNavigate(ctx, [ctx.params.workspaceSlug?.toString(), "workspace-views", "assigned"]),
|
||||
isEnabled: (ctx) => baseWorkspaceConditions(ctx),
|
||||
isVisible: (ctx) => baseWorkspaceConditions(ctx),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
nav_created_workspace_work_items: {
|
||||
id: "nav_created_workspace_work_items",
|
||||
type: "action",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.nav_created_workspace_work_items",
|
||||
icon: WorkItemsOutline,
|
||||
action: (ctx) => handlePowerKNavigate(ctx, [ctx.params.workspaceSlug?.toString(), "workspace-views", "created"]),
|
||||
isEnabled: (ctx) => baseWorkspaceConditions(ctx),
|
||||
isVisible: (ctx) => baseWorkspaceConditions(ctx),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
nav_subscribed_workspace_work_items: {
|
||||
id: "nav_subscribed_workspace_work_items",
|
||||
type: "action",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.nav_subscribed_workspace_work_items",
|
||||
icon: WorkItemsOutline,
|
||||
action: (ctx) =>
|
||||
handlePowerKNavigate(ctx, [ctx.params.workspaceSlug?.toString(), "workspace-views", "subscribed"]),
|
||||
isEnabled: (ctx) => baseWorkspaceConditions(ctx),
|
||||
isVisible: (ctx) => baseWorkspaceConditions(ctx),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
nav_workspace_analytics: {
|
||||
id: "nav_workspace_analytics",
|
||||
type: "action",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.nav_workspace_analytics",
|
||||
icon: BarOutline,
|
||||
keySequence: "ga",
|
||||
action: (ctx) => handlePowerKNavigate(ctx, [ctx.params.workspaceSlug?.toString(), "analytics", "overview"]),
|
||||
isEnabled: (ctx) => baseWorkspaceConditions(ctx) && hasWorkspaceMemberLevelPermissions(ctx),
|
||||
isVisible: (ctx) => baseWorkspaceConditions(ctx) && hasWorkspaceMemberLevelPermissions(ctx),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
nav_workspace_drafts: {
|
||||
id: "nav_workspace_drafts",
|
||||
type: "action",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.nav_workspace_drafts",
|
||||
icon: EditOutline,
|
||||
keySequence: "gj",
|
||||
action: (ctx) => handlePowerKNavigate(ctx, [ctx.params.workspaceSlug?.toString(), "drafts"]),
|
||||
isEnabled: (ctx) => baseWorkspaceConditions(ctx) && hasWorkspaceMemberLevelPermissions(ctx),
|
||||
isVisible: (ctx) => baseWorkspaceConditions(ctx) && hasWorkspaceMemberLevelPermissions(ctx),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
nav_workspace_archives: {
|
||||
id: "nav_workspace_archives",
|
||||
type: "action",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.nav_workspace_archives",
|
||||
icon: ArchiveOutline,
|
||||
keySequence: "gr",
|
||||
action: (ctx) => handlePowerKNavigate(ctx, [ctx.params.workspaceSlug?.toString(), "projects", "archives"]),
|
||||
isEnabled: (ctx) =>
|
||||
baseWorkspaceConditions(ctx) && !baseProjectConditions(ctx) && hasWorkspaceMemberLevelPermissions(ctx),
|
||||
isVisible: (ctx) =>
|
||||
baseWorkspaceConditions(ctx) && !baseProjectConditions(ctx) && hasWorkspaceMemberLevelPermissions(ctx),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
open_workspace_setting: {
|
||||
id: "open_workspace_setting",
|
||||
type: "change-page",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.open_workspace_setting",
|
||||
icon: SettingsOutline,
|
||||
keySequence: "os",
|
||||
page: "open-workspace-setting",
|
||||
onSelect: (data, ctx) => {
|
||||
const settingsHref = data as string;
|
||||
handlePowerKNavigate(ctx, [ctx.params.workspaceSlug?.toString(), settingsHref]);
|
||||
},
|
||||
isEnabled: (ctx) => baseWorkspaceConditions(ctx) && !baseProjectConditions(ctx),
|
||||
isVisible: (ctx) => baseWorkspaceConditions(ctx) && !baseProjectConditions(ctx),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
nav_workspace_settings: {
|
||||
id: "nav_workspace_settings",
|
||||
type: "action",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.nav_workspace_settings",
|
||||
icon: SettingsOutline,
|
||||
keySequence: "gs",
|
||||
action: (ctx) => handlePowerKNavigate(ctx, [ctx.params.workspaceSlug?.toString(), "settings"]),
|
||||
isEnabled: (ctx) => baseWorkspaceConditions(ctx) && !baseProjectConditions(ctx),
|
||||
isVisible: (ctx) => baseWorkspaceConditions(ctx) && !baseProjectConditions(ctx),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
nav_project_work_items: {
|
||||
id: "nav_project_work_items",
|
||||
type: "action",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.nav_project_work_items",
|
||||
icon: WorkItemsOutline,
|
||||
keySequence: "gi",
|
||||
action: (ctx) =>
|
||||
handlePowerKNavigate(ctx, [
|
||||
ctx.params.workspaceSlug?.toString(),
|
||||
"projects",
|
||||
ctx.params.projectId?.toString(),
|
||||
"issues",
|
||||
]),
|
||||
isEnabled: (ctx) => baseProjectConditions(ctx),
|
||||
isVisible: (ctx) => baseProjectConditions(ctx),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
open_project_cycle: {
|
||||
id: "open_project_cycle",
|
||||
type: "change-page",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.open_project_cycle",
|
||||
icon: CyclesOutline,
|
||||
keySequence: "oc",
|
||||
page: "open-project-cycle",
|
||||
onSelect: (data, ctx) => {
|
||||
const cycleDetails = data as ICycle;
|
||||
handlePowerKNavigate(ctx, [
|
||||
ctx.params.workspaceSlug?.toString(),
|
||||
"projects",
|
||||
ctx.params.projectId?.toString(),
|
||||
"cycles",
|
||||
cycleDetails.id,
|
||||
]);
|
||||
},
|
||||
isEnabled: (ctx) =>
|
||||
baseProjectConditions(ctx) && hasProjectMemberLevelPermissions(ctx) && !!getContextProject(ctx)?.cycle_view,
|
||||
isVisible: (ctx) =>
|
||||
baseProjectConditions(ctx) && hasProjectMemberLevelPermissions(ctx) && !!getContextProject(ctx)?.cycle_view,
|
||||
closeOnSelect: true,
|
||||
},
|
||||
nav_project_cycles: {
|
||||
id: "nav_project_cycles",
|
||||
type: "action",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.nav_project_cycles",
|
||||
icon: CyclesOutline,
|
||||
keySequence: "gc",
|
||||
action: (ctx) =>
|
||||
handlePowerKNavigate(ctx, [
|
||||
ctx.params.workspaceSlug?.toString(),
|
||||
"projects",
|
||||
ctx.params.projectId?.toString(),
|
||||
"cycles",
|
||||
]),
|
||||
isEnabled: (ctx) =>
|
||||
baseProjectConditions(ctx) && hasProjectMemberLevelPermissions(ctx) && !!getContextProject(ctx)?.cycle_view,
|
||||
isVisible: (ctx) =>
|
||||
baseProjectConditions(ctx) && hasProjectMemberLevelPermissions(ctx) && !!getContextProject(ctx)?.cycle_view,
|
||||
closeOnSelect: true,
|
||||
},
|
||||
open_project_module: {
|
||||
id: "open_project_module",
|
||||
type: "change-page",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.open_project_module",
|
||||
icon: ModuleOutline,
|
||||
keySequence: "om",
|
||||
page: "open-project-module",
|
||||
onSelect: (data, ctx) => {
|
||||
const moduleDetails = data as IModule;
|
||||
handlePowerKNavigate(ctx, [
|
||||
ctx.params.workspaceSlug?.toString(),
|
||||
"projects",
|
||||
ctx.params.projectId?.toString(),
|
||||
"modules",
|
||||
moduleDetails.id,
|
||||
]);
|
||||
},
|
||||
isEnabled: (ctx) =>
|
||||
baseProjectConditions(ctx) && hasProjectMemberLevelPermissions(ctx) && !!getContextProject(ctx)?.module_view,
|
||||
isVisible: (ctx) =>
|
||||
baseProjectConditions(ctx) && hasProjectMemberLevelPermissions(ctx) && !!getContextProject(ctx)?.module_view,
|
||||
closeOnSelect: true,
|
||||
},
|
||||
nav_project_modules: {
|
||||
id: "nav_project_modules",
|
||||
type: "action",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.nav_project_modules",
|
||||
icon: ModuleOutline,
|
||||
keySequence: "gm",
|
||||
action: (ctx) =>
|
||||
handlePowerKNavigate(ctx, [
|
||||
ctx.params.workspaceSlug?.toString(),
|
||||
"projects",
|
||||
ctx.params.projectId?.toString(),
|
||||
"modules",
|
||||
]),
|
||||
isEnabled: (ctx) =>
|
||||
baseProjectConditions(ctx) && hasProjectMemberLevelPermissions(ctx) && !!getContextProject(ctx)?.module_view,
|
||||
isVisible: (ctx) =>
|
||||
baseProjectConditions(ctx) && hasProjectMemberLevelPermissions(ctx) && !!getContextProject(ctx)?.module_view,
|
||||
closeOnSelect: true,
|
||||
},
|
||||
open_project_view: {
|
||||
id: "open_project_view",
|
||||
type: "change-page",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.open_project_view",
|
||||
icon: WorkItemsOutline,
|
||||
keySequence: "ov",
|
||||
page: "open-project-view",
|
||||
onSelect: (data, ctx) => {
|
||||
const viewDetails = data as IProjectView;
|
||||
handlePowerKNavigate(ctx, [
|
||||
ctx.params.workspaceSlug?.toString(),
|
||||
"projects",
|
||||
ctx.params.projectId?.toString(),
|
||||
"views",
|
||||
viewDetails.id,
|
||||
]);
|
||||
},
|
||||
isEnabled: (ctx) => baseProjectConditions(ctx) && !!getContextProject(ctx)?.issue_views_view,
|
||||
isVisible: (ctx) => baseProjectConditions(ctx) && !!getContextProject(ctx)?.issue_views_view,
|
||||
closeOnSelect: true,
|
||||
},
|
||||
nav_project_views: {
|
||||
id: "nav_project_views",
|
||||
type: "action",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.nav_project_views",
|
||||
icon: WorkItemsOutline,
|
||||
keySequence: "gv",
|
||||
action: (ctx) =>
|
||||
handlePowerKNavigate(ctx, [
|
||||
ctx.params.workspaceSlug?.toString(),
|
||||
"projects",
|
||||
ctx.params.projectId?.toString(),
|
||||
"views",
|
||||
]),
|
||||
isEnabled: (ctx) => baseProjectConditions(ctx) && !!getContextProject(ctx)?.issue_views_view,
|
||||
isVisible: (ctx) => baseProjectConditions(ctx) && !!getContextProject(ctx)?.issue_views_view,
|
||||
closeOnSelect: true,
|
||||
},
|
||||
nav_project_pages: {
|
||||
id: "nav_project_pages",
|
||||
type: "action",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.nav_project_pages",
|
||||
icon: DocumentationOutline,
|
||||
keySequence: "gd",
|
||||
action: (ctx) =>
|
||||
handlePowerKNavigate(ctx, [
|
||||
ctx.params.workspaceSlug?.toString(),
|
||||
"projects",
|
||||
ctx.params.projectId?.toString(),
|
||||
"pages",
|
||||
]),
|
||||
isEnabled: (ctx) => baseProjectConditions(ctx) && !!getContextProject(ctx)?.page_view,
|
||||
isVisible: (ctx) => baseProjectConditions(ctx) && !!getContextProject(ctx)?.page_view,
|
||||
closeOnSelect: true,
|
||||
},
|
||||
nav_project_intake: {
|
||||
id: "nav_project_intake",
|
||||
type: "action",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.nav_project_intake",
|
||||
icon: IntakeOutline,
|
||||
keySequence: "gk",
|
||||
action: (ctx) =>
|
||||
handlePowerKNavigate(ctx, [
|
||||
ctx.params.workspaceSlug?.toString(),
|
||||
"projects",
|
||||
ctx.params.projectId?.toString(),
|
||||
"intake",
|
||||
]),
|
||||
isEnabled: (ctx) => baseProjectConditions(ctx) && !!getContextProject(ctx)?.inbox_view,
|
||||
isVisible: (ctx) => baseProjectConditions(ctx) && !!getContextProject(ctx)?.inbox_view,
|
||||
closeOnSelect: true,
|
||||
},
|
||||
nav_project_archives: {
|
||||
id: "nav_project_archives",
|
||||
type: "action",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.nav_project_archives",
|
||||
icon: ArchiveOutline,
|
||||
keySequence: "gr",
|
||||
action: (ctx) =>
|
||||
handlePowerKNavigate(ctx, [
|
||||
ctx.params.workspaceSlug?.toString(),
|
||||
"projects",
|
||||
ctx.params.projectId?.toString(),
|
||||
"archives",
|
||||
"issues",
|
||||
]),
|
||||
isEnabled: (ctx) => baseProjectConditions(ctx) && hasProjectMemberLevelPermissions(ctx),
|
||||
isVisible: (ctx) => baseProjectConditions(ctx) && hasProjectMemberLevelPermissions(ctx),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
open_project_setting: {
|
||||
id: "open_project_setting",
|
||||
type: "change-page",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.open_project_setting",
|
||||
icon: SettingsOutline,
|
||||
keySequence: "os",
|
||||
page: "open-project-setting",
|
||||
onSelect: (data, ctx) => {
|
||||
const settingsHref = data as string;
|
||||
handlePowerKNavigate(ctx, [
|
||||
ctx.params.workspaceSlug?.toString(),
|
||||
"settings",
|
||||
"projects",
|
||||
ctx.params.projectId?.toString(),
|
||||
settingsHref,
|
||||
]);
|
||||
},
|
||||
isEnabled: (ctx) => baseProjectConditions(ctx),
|
||||
isVisible: (ctx) => baseProjectConditions(ctx),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
nav_project_settings: {
|
||||
id: "nav_project_settings",
|
||||
type: "action",
|
||||
group: "navigation",
|
||||
i18n_title: "power_k.navigation_actions.nav_project_settings",
|
||||
icon: SettingsOutline,
|
||||
keySequence: "gs",
|
||||
action: (ctx) =>
|
||||
handlePowerKNavigate(ctx, [
|
||||
ctx.params.workspaceSlug?.toString(),
|
||||
"settings",
|
||||
"projects",
|
||||
ctx.params.projectId?.toString(),
|
||||
]),
|
||||
isEnabled: (ctx) => baseProjectConditions(ctx),
|
||||
isVisible: (ctx) => baseProjectConditions(ctx),
|
||||
closeOnSelect: true,
|
||||
},
|
||||
};
|
||||
};
|
||||
51
apps/web/core/components/power-k/config/navigation/root.ts
Normal file
51
apps/web/core/components/power-k/config/navigation/root.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
// components
|
||||
import type { TPowerKCommandConfig } from "@/components/power-k/core/types";
|
||||
// local imports
|
||||
import type { TPowerKNavigationCommandKeys } from "./commands";
|
||||
import { usePowerKNavigationCommandsRecord } from "./commands";
|
||||
|
||||
export const usePowerKNavigationCommands = (): TPowerKCommandConfig[] => {
|
||||
const optionsList: Record<TPowerKNavigationCommandKeys, TPowerKCommandConfig> = usePowerKNavigationCommandsRecord();
|
||||
|
||||
return [
|
||||
// Open actions from lowest to highest scope
|
||||
optionsList["open_project_cycle"],
|
||||
optionsList["open_project_module"],
|
||||
optionsList["open_project_view"],
|
||||
optionsList["open_project_setting"],
|
||||
optionsList["open_project"],
|
||||
optionsList["open_workspace_setting"],
|
||||
optionsList["open_workspace"],
|
||||
// User-Level Navigation
|
||||
optionsList["nav_home"],
|
||||
optionsList["nav_inbox"],
|
||||
optionsList["nav_your_work"],
|
||||
// Project-Level Navigation (Only visible in project context)
|
||||
optionsList["nav_project_work_items"],
|
||||
optionsList["nav_project_pages"],
|
||||
optionsList["nav_project_cycles"],
|
||||
optionsList["nav_project_modules"],
|
||||
optionsList["nav_project_views"],
|
||||
optionsList["nav_project_intake"],
|
||||
optionsList["nav_project_settings"],
|
||||
optionsList["nav_project_archives"],
|
||||
// Navigate to workspace-level pages
|
||||
optionsList["nav_all_workspace_work_items"],
|
||||
optionsList["nav_assigned_workspace_work_items"],
|
||||
optionsList["nav_created_workspace_work_items"],
|
||||
optionsList["nav_subscribed_workspace_work_items"],
|
||||
optionsList["nav_workspace_analytics"],
|
||||
optionsList["nav_workspace_settings"],
|
||||
optionsList["nav_workspace_drafts"],
|
||||
optionsList["nav_workspace_archives"],
|
||||
optionsList["nav_projects_list"],
|
||||
// Account-Level Navigation
|
||||
optionsList["nav_account_settings"],
|
||||
];
|
||||
};
|
||||
168
apps/web/core/components/power-k/config/preferences-commands.ts
Normal file
168
apps/web/core/components/power-k/config/preferences-commands.ts
Normal file
@@ -0,0 +1,168 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { useCallback } from "react";
|
||||
import { useTheme } from "next-themes";
|
||||
import { Languages } from "lucide-react";
|
||||
import { CalendarOutline, GlobeOutline, PaletteOutline } from "@makeplane/propel/icons";
|
||||
// plane imports
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { setToast, TOAST_TYPE } from "@plane/propel/toast";
|
||||
import type { EStartOfTheWeek, TUserProfile } from "@plane/types";
|
||||
// components
|
||||
import type { TPowerKCommandConfig } from "@/components/power-k/core/types";
|
||||
// hooks
|
||||
import { useUser, useUserProfile } from "@/hooks/store/user";
|
||||
|
||||
/**
|
||||
* Preferences commands - Preferences related commands
|
||||
*/
|
||||
export const usePowerKPreferencesCommands = (): TPowerKCommandConfig[] => {
|
||||
// store hooks
|
||||
const { setTheme } = useTheme();
|
||||
const { updateCurrentUser } = useUser();
|
||||
const { updateUserProfile, updateUserTheme } = useUserProfile();
|
||||
// translation
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleUpdateTheme = useCallback(
|
||||
async (newTheme: string) => {
|
||||
setTheme(newTheme);
|
||||
return updateUserTheme({ theme: newTheme })
|
||||
.then(() => {
|
||||
setToast({
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
title: "Theme updated",
|
||||
message: "Reloading to apply changes...",
|
||||
});
|
||||
// reload the page after showing the toast
|
||||
window.location.reload();
|
||||
return;
|
||||
})
|
||||
.catch(() => {
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: t("toast.error"),
|
||||
message: t("power_k.preferences_actions.toast.theme.error"),
|
||||
});
|
||||
return;
|
||||
});
|
||||
},
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[setTheme, updateUserTheme]
|
||||
);
|
||||
|
||||
const handleUpdateTimezone = useCallback(
|
||||
(value: string) => {
|
||||
updateCurrentUser({ user_timezone: value })
|
||||
.then(() => {
|
||||
setToast({
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
title: t("toast.success"),
|
||||
message: t("power_k.preferences_actions.toast.timezone.success"),
|
||||
});
|
||||
return;
|
||||
})
|
||||
.catch(() => {
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: t("toast.error"),
|
||||
message: t("power_k.preferences_actions.toast.timezone.error"),
|
||||
});
|
||||
return;
|
||||
});
|
||||
},
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[updateCurrentUser]
|
||||
);
|
||||
|
||||
const handleUpdateUserProfile = useCallback(
|
||||
(payload: Partial<TUserProfile>) => {
|
||||
updateUserProfile(payload)
|
||||
.then(() => {
|
||||
setToast({
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
title: t("toast.success"),
|
||||
message: t("power_k.preferences_actions.toast.generic.success"),
|
||||
});
|
||||
return;
|
||||
})
|
||||
.catch(() => {
|
||||
setToast({
|
||||
type: TOAST_TYPE.ERROR,
|
||||
title: t("toast.error"),
|
||||
message: t("power_k.preferences_actions.toast.generic.error"),
|
||||
});
|
||||
return;
|
||||
});
|
||||
},
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[updateUserProfile]
|
||||
);
|
||||
|
||||
return [
|
||||
{
|
||||
id: "update_interface_theme",
|
||||
group: "preferences",
|
||||
type: "change-page",
|
||||
page: "update-theme",
|
||||
i18n_title: "power_k.preferences_actions.update_theme",
|
||||
icon: PaletteOutline,
|
||||
onSelect: (data) => {
|
||||
const theme = data as string;
|
||||
void handleUpdateTheme(theme);
|
||||
},
|
||||
isEnabled: () => true,
|
||||
isVisible: () => true,
|
||||
closeOnSelect: true,
|
||||
},
|
||||
{
|
||||
id: "update_timezone",
|
||||
group: "preferences",
|
||||
page: "update-timezone",
|
||||
type: "change-page",
|
||||
i18n_title: "power_k.preferences_actions.update_timezone",
|
||||
icon: GlobeOutline,
|
||||
onSelect: (data) => {
|
||||
const timezone = data as string;
|
||||
handleUpdateTimezone(timezone);
|
||||
},
|
||||
isEnabled: () => true,
|
||||
isVisible: () => true,
|
||||
closeOnSelect: true,
|
||||
},
|
||||
{
|
||||
id: "update_start_of_week",
|
||||
group: "preferences",
|
||||
page: "update-start-of-week",
|
||||
type: "change-page",
|
||||
i18n_title: "power_k.preferences_actions.update_start_of_week",
|
||||
icon: CalendarOutline,
|
||||
onSelect: (data) => {
|
||||
const startOfWeek = data as EStartOfTheWeek;
|
||||
handleUpdateUserProfile({ start_of_the_week: startOfWeek });
|
||||
},
|
||||
isEnabled: () => true,
|
||||
isVisible: () => true,
|
||||
closeOnSelect: true,
|
||||
},
|
||||
{
|
||||
id: "update_interface_language",
|
||||
group: "preferences",
|
||||
page: "update-language",
|
||||
type: "change-page",
|
||||
i18n_title: "power_k.preferences_actions.update_language",
|
||||
icon: Languages,
|
||||
onSelect: (data) => {
|
||||
const language = data as string;
|
||||
handleUpdateUserProfile({ language });
|
||||
},
|
||||
isEnabled: () => true,
|
||||
isVisible: () => true,
|
||||
closeOnSelect: true,
|
||||
},
|
||||
];
|
||||
};
|
||||
Reference in New Issue
Block a user