chore: merge helpers and layouts (#8624)

* fix: remove constants and services

* fix: formatting

* chore: merge helpers and layouts

* fix: workspace disbale flag handling
This commit is contained in:
sriram veeraghanta 2026-02-10 22:04:07 +05:30 committed by GitHub
parent 7793febcf8
commit 2b6e24d526
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 37 additions and 414 deletions

View file

@ -24,9 +24,10 @@ import { useAppTheme } from "@/hooks/store/use-app-theme";
import { useIssueDetail } from "@/hooks/store/use-issue-detail"; import { useIssueDetail } from "@/hooks/store/use-issue-detail";
import { useProject } from "@/hooks/store/use-project"; import { useProject } from "@/hooks/store/use-project";
import { useAppRouter } from "@/hooks/use-app-router"; import { useAppRouter } from "@/hooks/use-app-router";
// layouts
import { ProjectAuthWrapper } from "@/layouts/auth-layout/project-wrapper";
// plane web imports // plane web imports
import { useWorkItemProperties } from "@/plane-web/hooks/use-issue-properties"; import { useWorkItemProperties } from "@/plane-web/hooks/use-issue-properties";
import { ProjectAuthWrapper } from "@/plane-web/layouts/project-wrapper";
import { WorkItemDetailRoot } from "@/plane-web/components/browse/workItem-detail"; import { WorkItemDetailRoot } from "@/plane-web/components/browse/workItem-detail";
import type { Route } from "./+types/page"; import type { Route } from "./+types/page";

View file

@ -15,7 +15,8 @@ import { AppSidebarToggleButton } from "@/components/sidebar/sidebar-toggle-butt
// hooks // hooks
import { useAppTheme } from "@/hooks/store/use-app-theme"; import { useAppTheme } from "@/hooks/store/use-app-theme";
import { useProjectNavigationPreferences } from "@/hooks/use-navigation-preferences"; import { useProjectNavigationPreferences } from "@/hooks/use-navigation-preferences";
import { ProjectAuthWrapper } from "@/plane-web/layouts/project-wrapper"; // layouts
import { ProjectAuthWrapper } from "@/layouts/auth-layout/project-wrapper";
// local imports // local imports
import type { Route } from "./+types/layout"; import type { Route } from "./+types/layout";

View file

@ -10,8 +10,8 @@ import { Outlet } from "react-router";
// components // components
import { getProjectActivePath } from "@/components/settings/helper"; import { getProjectActivePath } from "@/components/settings/helper";
import { SettingsMobileNav } from "@/components/settings/mobile/nav"; import { SettingsMobileNav } from "@/components/settings/mobile/nav";
// plane web imports // layouts
import { ProjectAuthWrapper } from "@/plane-web/layouts/project-wrapper"; import { ProjectAuthWrapper } from "@/layouts/auth-layout/project-wrapper";
// types // types
import type { Route } from "./+types/layout"; import type { Route } from "./+types/layout";
import { ProjectSettingsSidebarRoot } from "@/components/settings/project/sidebar"; import { ProjectSettingsSidebarRoot } from "@/components/settings/project/sidebar";

View file

@ -20,7 +20,6 @@ import { useProject } from "@/hooks/store/use-project";
import { useUserPermissions } from "@/hooks/store/user"; import { useUserPermissions } from "@/hooks/store/user";
// plane web imports // plane web imports
import { ProjectTeamspaceList } from "@/plane-web/components/projects/teamspaces/teamspace-list"; import { ProjectTeamspaceList } from "@/plane-web/components/projects/teamspaces/teamspace-list";
import { getProjectSettingsPageLabelI18nKey } from "@/plane-web/helpers/project-settings";
// local imports // local imports
import type { Route } from "./+types/page"; import type { Route } from "./+types/page";
import { MembersProjectSettingsHeader } from "./header"; import { MembersProjectSettingsHeader } from "./header";
@ -49,7 +48,7 @@ function MembersSettingsPage({ params }: Route.ComponentProps) {
return ( return (
<SettingsContentWrapper header={<MembersProjectSettingsHeader />} hugging> <SettingsContentWrapper header={<MembersProjectSettingsHeader />} hugging>
<PageHead title={pageTitle} /> <PageHead title={pageTitle} />
<SettingsHeading title={t(getProjectSettingsPageLabelI18nKey("members", "common.members"))} /> <SettingsHeading title={t("common.members")} />
<ProjectSettingsMemberDefaults projectId={projectId} workspaceSlug={workspaceSlug} /> <ProjectSettingsMemberDefaults projectId={projectId} workspaceSlug={workspaceSlug} />
<ProjectTeamspaceList projectId={projectId} workspaceSlug={workspaceSlug} /> <ProjectTeamspaceList projectId={projectId} workspaceSlug={workspaceSlug} />
<ProjectMemberList projectId={projectId} workspaceSlug={workspaceSlug} /> <ProjectMemberList projectId={projectId} workspaceSlug={workspaceSlug} />

View file

@ -9,7 +9,7 @@ import { AuthenticationWrapper } from "@/lib/wrappers/authentication-wrapper";
import { WorkspaceContentWrapper } from "@/plane-web/components/workspace/content-wrapper"; import { WorkspaceContentWrapper } from "@/plane-web/components/workspace/content-wrapper";
import { AppRailVisibilityProvider } from "@/plane-web/hooks/app-rail"; import { AppRailVisibilityProvider } from "@/plane-web/hooks/app-rail";
import { GlobalModals } from "@/plane-web/components/common/modal/global"; import { GlobalModals } from "@/plane-web/components/common/modal/global";
import { WorkspaceAuthWrapper } from "@/plane-web/layouts/workspace-wrapper"; import { WorkspaceAuthWrapper } from "@/layouts/auth-layout/workspace-wrapper";
import type { Route } from "./+types/layout"; import type { Route } from "./+types/layout";
export default function WorkspaceLayout(props: Route.ComponentProps) { export default function WorkspaceLayout(props: Route.ComponentProps) {

View file

@ -18,17 +18,17 @@ import WorkspaceCreationDisabled from "@/app/assets/workspace/workspace-creation
import { CreateWorkspaceForm } from "@/components/workspace/create-workspace-form"; import { CreateWorkspaceForm } from "@/components/workspace/create-workspace-form";
// hooks // hooks
import { useUser, useUserProfile } from "@/hooks/store/user"; import { useUser, useUserProfile } from "@/hooks/store/user";
import { useInstance } from "@/hooks/store/use-instance";
import { useAppRouter } from "@/hooks/use-app-router"; import { useAppRouter } from "@/hooks/use-app-router";
// wrappers // wrappers
import { AuthenticationWrapper } from "@/lib/wrappers/authentication-wrapper"; import { AuthenticationWrapper } from "@/lib/wrappers/authentication-wrapper";
// plane web helpers
import { getIsWorkspaceCreationDisabled } from "@/plane-web/helpers/instance.helper";
const CreateWorkspacePage = observer(function CreateWorkspacePage() { const CreateWorkspacePage = observer(function CreateWorkspacePage() {
const { t } = useTranslation(); const { t } = useTranslation();
// router // router
const router = useAppRouter(); const router = useAppRouter();
// store hooks // store hooks
const { config } = useInstance();
const { data: currentUser } = useUser(); const { data: currentUser } = useUser();
const { updateUserProfile } = useUserProfile(); const { updateUserProfile } = useUserProfile();
// states // states
@ -38,7 +38,7 @@ const CreateWorkspacePage = observer(function CreateWorkspacePage() {
organization_size: "", organization_size: "",
}); });
// derived values // derived values
const isWorkspaceCreationDisabled = getIsWorkspaceCreationDisabled(); const isWorkspaceCreationDisabled = config?.is_workspace_creation_disabled ?? false;
// methods // methods
const getMailtoHref = () => { const getMailtoHref = () => {

View file

@ -1,112 +0,0 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import type { TCommandPaletteActionList, TCommandPaletteShortcut, TCommandPaletteShortcutList } from "@plane/types";
// store
import { store } from "@/lib/store-context";
export const getGlobalShortcutsList: () => TCommandPaletteActionList = () => {
const { toggleCreateIssueModal } = store.commandPalette;
return {
c: {
title: "Create a new work item",
description: "Create a new work item in the current project",
action: () => {
toggleCreateIssueModal(true);
},
},
};
};
export const getWorkspaceShortcutsList: () => TCommandPaletteActionList = () => {
const { toggleCreateProjectModal } = store.commandPalette;
return {
p: {
title: "Create a new project",
description: "Create a new project in the current workspace",
action: () => {
toggleCreateProjectModal(true);
},
},
};
};
export const getProjectShortcutsList: () => TCommandPaletteActionList = () => {
const {
toggleCreatePageModal,
toggleCreateModuleModal,
toggleCreateCycleModal,
toggleCreateViewModal,
toggleBulkDeleteIssueModal,
} = store.commandPalette;
return {
d: {
title: "Create a new page",
description: "Create a new page in the current project",
action: () => {
toggleCreatePageModal({ isOpen: true });
},
},
m: {
title: "Create a new module",
description: "Create a new module in the current project",
action: () => {
toggleCreateModuleModal(true);
},
},
q: {
title: "Create a new cycle",
description: "Create a new cycle in the current project",
action: () => {
toggleCreateCycleModal(true);
},
},
v: {
title: "Create a new view",
description: "Create a new view in the current project",
action: () => {
toggleCreateViewModal(true);
},
},
backspace: {
title: "Bulk delete work items",
description: "Bulk delete work items in the current project",
action: () => toggleBulkDeleteIssueModal(true),
},
delete: {
title: "Bulk delete work items",
description: "Bulk delete work items in the current project",
action: () => toggleBulkDeleteIssueModal(true),
},
};
};
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export const handleAdditionalKeyDownEvents = (e: KeyboardEvent) => null;
export const getNavigationShortcutsList = (): TCommandPaletteShortcut[] => [
{ keys: "Ctrl,K", description: "Open command menu" },
];
export const getCommonShortcutsList = (platform: string): TCommandPaletteShortcut[] => [
{ keys: "P", description: "Create project" },
{ keys: "C", description: "Create work item" },
{ keys: "Q", description: "Create cycle" },
{ keys: "M", description: "Create module" },
{ keys: "V", description: "Create view" },
{ keys: "D", description: "Create page" },
{ keys: "Delete", description: "Bulk delete work items" },
{ keys: "Shift,/", description: "Open shortcuts guide" },
{
keys: platform === "MacOS" ? "Ctrl,control,C" : "Ctrl,Alt,C",
description: "Copy work item URL from the work item details page",
},
];
export const getAdditionalShortcutsList = (): TCommandPaletteShortcutList[] => [];

View file

@ -1,21 +0,0 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import type { TEpicAnalyticsGroup } from "@plane/types";
export const updateEpicAnalytics = () => {
const updateAnalytics = (
workspaceSlug: string,
projectId: string,
epicId: string,
data: {
incrementStateGroupCount?: TEpicAnalyticsGroup;
decrementStateGroupCount?: TEpicAnalyticsGroup;
}
) => {};
return { updateAnalytics };
};

View file

@ -1,13 +0,0 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { store } from "@/lib/store-context";
export const getIsWorkspaceCreationDisabled = () => {
const instanceConfig = store.instance.config;
return instanceConfig?.is_workspace_creation_disabled;
};

View file

@ -1,28 +0,0 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import type { IssueActions } from "@/hooks/use-issues-actions";
export const useTeamIssueActions: () => IssueActions = () => ({
fetchIssues: () => Promise.resolve(undefined),
fetchNextIssues: () => Promise.resolve(undefined),
removeIssue: () => Promise.resolve(undefined),
updateFilters: () => Promise.resolve(undefined),
});
export const useTeamViewIssueActions: () => IssueActions = () => ({
fetchIssues: () => Promise.resolve(undefined),
fetchNextIssues: () => Promise.resolve(undefined),
removeIssue: () => Promise.resolve(undefined),
updateFilters: () => Promise.resolve(undefined),
});
export const useTeamProjectWorkItemsActions: () => IssueActions = () => ({
fetchIssues: () => Promise.resolve(undefined),
fetchNextIssues: () => Promise.resolve(undefined),
removeIssue: () => Promise.resolve(undefined),
updateFilters: () => Promise.resolve(undefined),
});

View file

@ -1,9 +0,0 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
export const hideFloatingBot = () => {};
export const showFloatingBot = () => {};

View file

@ -1,13 +0,0 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
/**
* @description Get the i18n key for the project settings page label
* @param _settingsKey - The key of the project settings page
* @param defaultLabelKey - The default i18n key for the project settings page label
* @returns The i18n key for the project settings page label
*/
export const getProjectSettingsPageLabelI18nKey = (_settingsKey: string, defaultLabelKey: string) => defaultLabelKey;

View file

@ -1,26 +0,0 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
// plane imports
import type { EIssuesStoreType } from "@plane/types";
// plane web imports
import type { TWorkItemFiltersEntityProps } from "@/plane-web/hooks/work-item-filters/use-work-item-filters-config";
export type TGetAdditionalPropsForProjectLevelFiltersHOCParams = {
entityType: EIssuesStoreType;
workspaceSlug: string;
projectId: string;
};
export type TGetAdditionalPropsForProjectLevelFiltersHOC = (
params: TGetAdditionalPropsForProjectLevelFiltersHOCParams
) => TWorkItemFiltersEntityProps;
export const getAdditionalProjectLevelFiltersHOCProps: TGetAdditionalPropsForProjectLevelFiltersHOC = ({
workspaceSlug,
}) => ({
workspaceSlug,
});

View file

@ -1,8 +0,0 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
export type TRenderSettingsLink = (workspaceSlug: string, settingKey: string) => boolean;
export const shouldRenderSettingLink: TRenderSettingsLink = (workspaceSlug, settingKey) => true;

View file

@ -1,26 +0,0 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { observer } from "mobx-react";
// layouts
import { ProjectAuthWrapper as CoreProjectAuthWrapper } from "@/layouts/auth-layout/project-wrapper";
export type IProjectAuthWrapper = {
workspaceSlug: string;
projectId: string;
children: React.ReactNode;
};
export const ProjectAuthWrapper = observer(function ProjectAuthWrapper(props: IProjectAuthWrapper) {
// props
const { workspaceSlug, projectId, children } = props;
return (
<CoreProjectAuthWrapper workspaceSlug={workspaceSlug} projectId={projectId}>
{children}
</CoreProjectAuthWrapper>
);
});

View file

@ -1,21 +0,0 @@
/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import type { FC } from "react";
import { observer } from "mobx-react";
// layouts
import { WorkspaceAuthWrapper as CoreWorkspaceAuthWrapper } from "@/layouts/auth-layout/workspace-wrapper";
export type IWorkspaceAuthWrapper = {
children: React.ReactNode;
};
export const WorkspaceAuthWrapper = observer(function WorkspaceAuthWrapper(props: IWorkspaceAuthWrapper) {
// props
const { children } = props;
return <CoreWorkspaceAuthWrapper>{children}</CoreWorkspaceAuthWrapper>;
});

View file

@ -5,7 +5,6 @@
*/ */
import { useMemo } from "react"; import { useMemo } from "react";
import { useParams } from "next/navigation";
// plane imports // plane imports
import { useTranslation } from "@plane/i18n"; import { useTranslation } from "@plane/i18n";
import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import { TOAST_TYPE, setToast } from "@plane/propel/toast";
@ -14,18 +13,12 @@ import { EIssueServiceType } from "@plane/types";
import { copyUrlToClipboard } from "@plane/utils"; import { copyUrlToClipboard } from "@plane/utils";
// hooks // hooks
import { useIssueDetail } from "@/hooks/store/use-issue-detail"; import { useIssueDetail } from "@/hooks/store/use-issue-detail";
import { useProjectState } from "@/hooks/store/use-project-state";
// plane web helpers
import { updateEpicAnalytics } from "@/plane-web/helpers/epic-analytics";
export const useSubIssueOperations = (issueServiceType: TIssueServiceType): TSubIssueOperations => { export const useSubIssueOperations = (issueServiceType: TIssueServiceType): TSubIssueOperations => {
// router
const { epicId: epicIdParam } = useParams();
// translation // translation
const { t } = useTranslation(); const { t } = useTranslation();
// store hooks // store hooks
const { const {
issue: { getIssueById },
subIssues: { setSubIssueHelpers }, subIssues: { setSubIssueHelpers },
createSubIssues, createSubIssues,
fetchSubIssues, fetchSubIssues,
@ -33,13 +26,6 @@ export const useSubIssueOperations = (issueServiceType: TIssueServiceType): TSub
deleteSubIssue, deleteSubIssue,
removeSubIssue, removeSubIssue,
} = useIssueDetail(issueServiceType); } = useIssueDetail(issueServiceType);
const { getStateById } = useProjectState();
const { peekIssue: epicPeekIssue } = useIssueDetail(EIssueServiceType.EPICS);
// const { updateEpicAnalytics } = useIssueTypes();
const { updateAnalytics } = updateEpicAnalytics();
// derived values
const epicId = epicIdParam || epicPeekIssue?.issueId;
const subIssueOperations: TSubIssueOperations = useMemo( const subIssueOperations: TSubIssueOperations = useMemo(
() => ({ () => ({
@ -110,30 +96,6 @@ export const useSubIssueOperations = (issueServiceType: TIssueServiceType): TSub
try { try {
setSubIssueHelpers(parentIssueId, "issue_loader", issueId); setSubIssueHelpers(parentIssueId, "issue_loader", issueId);
await updateSubIssue(workspaceSlug, projectId, parentIssueId, issueId, issueData, oldIssue, fromModal); await updateSubIssue(workspaceSlug, projectId, parentIssueId, issueId, issueData, oldIssue, fromModal);
if (issueServiceType === EIssueServiceType.EPICS) {
const oldState = getStateById(oldIssue?.state_id)?.group;
if (oldState && oldIssue && issueData && epicId) {
// Check if parent_id is changed if yes then decrement the epic analytics count
if (issueData.parent_id && oldIssue?.parent_id && issueData.parent_id !== oldIssue?.parent_id) {
updateAnalytics(workspaceSlug, projectId, epicId.toString(), {
decrementStateGroupCount: `${oldState}_issues`,
});
}
// Check if state_id is changed if yes then decrement the old state group count and increment the new state group count
if (issueData.state_id) {
const newState = getStateById(issueData.state_id)?.group;
if (oldState && newState && oldState !== newState) {
updateAnalytics(workspaceSlug, projectId, epicId.toString(), {
decrementStateGroupCount: `${oldState}_issues`,
incrementStateGroupCount: `${newState}_issues`,
});
}
}
}
}
setToast({ setToast({
type: TOAST_TYPE.SUCCESS, type: TOAST_TYPE.SUCCESS,
title: t("toast.success"), title: t("toast.success"),
@ -152,16 +114,6 @@ export const useSubIssueOperations = (issueServiceType: TIssueServiceType): TSub
try { try {
setSubIssueHelpers(parentIssueId, "issue_loader", issueId); setSubIssueHelpers(parentIssueId, "issue_loader", issueId);
await removeSubIssue(workspaceSlug, projectId, parentIssueId, issueId); await removeSubIssue(workspaceSlug, projectId, parentIssueId, issueId);
if (issueServiceType === EIssueServiceType.EPICS) {
const issueBeforeRemoval = getIssueById(issueId);
const oldState = getStateById(issueBeforeRemoval?.state_id)?.group;
if (epicId && oldState) {
updateAnalytics(workspaceSlug, projectId, epicId.toString(), {
decrementStateGroupCount: `${oldState}_issues`,
});
}
}
setToast({ setToast({
type: TOAST_TYPE.SUCCESS, type: TOAST_TYPE.SUCCESS,
title: t("toast.success"), title: t("toast.success"),
@ -189,9 +141,8 @@ export const useSubIssueOperations = (issueServiceType: TIssueServiceType): TSub
deleteSubIssue: async (workspaceSlug, projectId, parentIssueId, issueId) => { deleteSubIssue: async (workspaceSlug, projectId, parentIssueId, issueId) => {
try { try {
setSubIssueHelpers(parentIssueId, "issue_loader", issueId); setSubIssueHelpers(parentIssueId, "issue_loader", issueId);
return deleteSubIssue(workspaceSlug, projectId, parentIssueId, issueId).then(() => { await deleteSubIssue(workspaceSlug, projectId, parentIssueId, issueId);
setSubIssueHelpers(parentIssueId, "issue_loader", issueId); setSubIssueHelpers(parentIssueId, "issue_loader", issueId);
});
} catch (_error) { } catch (_error) {
setToast({ setToast({
type: TOAST_TYPE.ERROR, type: TOAST_TYPE.ERROR,
@ -209,15 +160,11 @@ export const useSubIssueOperations = (issueServiceType: TIssueServiceType): TSub
[ [
createSubIssues, createSubIssues,
deleteSubIssue, deleteSubIssue,
epicId,
fetchSubIssues, fetchSubIssues,
getIssueById,
getStateById,
issueServiceType, issueServiceType,
removeSubIssue, removeSubIssue,
setSubIssueHelpers, setSubIssueHelpers,
t, t,
updateAnalytics,
updateSubIssue, updateSubIssue,
] ]
); );

View file

@ -6,15 +6,12 @@
import React from "react"; import React from "react";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import { useParams } from "next/navigation";
// plane constants // plane constants
import { ISSUE_DISPLAY_PROPERTIES } from "@plane/constants"; import { ISSUE_DISPLAY_PROPERTIES } from "@plane/constants";
// plane i18n // plane i18n
import { useTranslation } from "@plane/i18n"; import { useTranslation } from "@plane/i18n";
// types // types
import type { IIssueDisplayProperties } from "@plane/types"; import type { IIssueDisplayProperties } from "@plane/types";
// plane web helpers
import { shouldRenderDisplayProperty } from "@/plane-web/helpers/issue-filter.helper";
// components // components
import { FilterHeader } from "../helpers/filter-header"; import { FilterHeader } from "../helpers/filter-header";
@ -38,12 +35,8 @@ export const FilterDisplayProperties = observer(function FilterDisplayProperties
} = props; } = props;
// hooks // hooks
const { t } = useTranslation(); const { t } = useTranslation();
// router
const { workspaceSlug, projectId: routerProjectId } = useParams();
// states // states
const [previewEnabled, setPreviewEnabled] = React.useState(true); const [previewEnabled, setPreviewEnabled] = React.useState(true);
// derived values
const projectId = routerProjectId ? routerProjectId?.toString() : undefined;
// Filter out "cycle" and "module" keys if cycleViewDisabled or moduleViewDisabled is true // Filter out "cycle" and "module" keys if cycleViewDisabled or moduleViewDisabled is true
// Also filter out display properties that should not be rendered // Also filter out display properties that should not be rendered
@ -55,7 +48,7 @@ export const FilterDisplayProperties = observer(function FilterDisplayProperties
case "modules": case "modules":
return !moduleViewDisabled; return !moduleViewDisabled;
default: default:
return shouldRenderDisplayProperty({ workspaceSlug: workspaceSlug?.toString(), projectId, key: property.key }); return true;
} }
}).map((property) => { }).map((property) => {
if (isEpic && property.key === "sub_issue_count") { if (isEpic && property.key === "sub_issue_count") {

View file

@ -10,7 +10,7 @@ import { observer } from "mobx-react";
import type { IIssueDisplayProperties, TIssue } from "@plane/types"; import type { IIssueDisplayProperties, TIssue } from "@plane/types";
// components // components
import { SPREADSHEET_COLUMNS } from "@/plane-web/components/issues/issue-layouts/utils"; import { SPREADSHEET_COLUMNS } from "@/plane-web/components/issues/issue-layouts/utils";
import { shouldRenderColumn } from "@/plane-web/helpers/issue-filter.helper"; import { shouldRenderColumn } from "@/helpers/issue-filter.helper";
import { WithDisplayPropertiesHOC } from "../properties/with-display-properties-HOC"; import { WithDisplayPropertiesHOC } from "../properties/with-display-properties-HOC";
type Props = { type Props = {

View file

@ -9,7 +9,7 @@ import { useRef } from "react";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import type { IIssueDisplayFilterOptions, IIssueDisplayProperties } from "@plane/types"; import type { IIssueDisplayFilterOptions, IIssueDisplayProperties } from "@plane/types";
//components //components
import { shouldRenderColumn } from "@/plane-web/helpers/issue-filter.helper"; import { shouldRenderColumn } from "@/helpers/issue-filter.helper";
import { WithDisplayPropertiesHOC } from "../properties/with-display-properties-HOC"; import { WithDisplayPropertiesHOC } from "../properties/with-display-properties-HOC";
import { HeaderColumn } from "./columns/header-column"; import { HeaderColumn } from "./columns/header-column";

View file

@ -4,7 +4,7 @@
* See the LICENSE file for details. * See the LICENSE file for details.
*/ */
import React, { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import { OctagonAlert } from "lucide-react"; import { OctagonAlert } from "lucide-react";
// plane imports // plane imports
@ -13,8 +13,7 @@ import type { IWorkspaceMemberInvitation, TOnboardingSteps } from "@plane/types"
import { LogoSpinner } from "@/components/common/logo-spinner"; import { LogoSpinner } from "@/components/common/logo-spinner";
// hooks // hooks
import { useUser } from "@/hooks/store/user"; import { useUser } from "@/hooks/store/user";
// plane web helpers import { useInstance } from "@/hooks/store/use-instance";
import { getIsWorkspaceCreationDisabled } from "@/plane-web/helpers/instance.helper";
// local imports // local imports
import { CreateWorkspace } from "./create-workspace"; import { CreateWorkspace } from "./create-workspace";
import { Invitations } from "./invitations"; import { Invitations } from "./invitations";
@ -33,13 +32,14 @@ type Props = {
}; };
export const CreateOrJoinWorkspaces = observer(function CreateOrJoinWorkspaces(props: Props) { export const CreateOrJoinWorkspaces = observer(function CreateOrJoinWorkspaces(props: Props) {
const { invitations, totalSteps, stepChange, finishOnboarding } = props; const { invitations, stepChange, finishOnboarding } = props;
// states // states
const [currentView, setCurrentView] = useState<ECreateOrJoinWorkspaceViews | null>(null); const [currentView, setCurrentView] = useState<ECreateOrJoinWorkspaceViews | null>(null);
// store hooks // store hooks
const { data: user } = useUser(); const { data: user } = useUser();
const { config } = useInstance();
// derived values // derived values
const isWorkspaceCreationEnabled = getIsWorkspaceCreationDisabled() === false; const isWorkspaceCreationDisabled = config?.is_workspace_creation_disabled ?? false;
useEffect(() => { useEffect(() => {
if (invitations.length > 0) { if (invitations.length > 0) {
@ -66,7 +66,7 @@ export const CreateOrJoinWorkspaces = observer(function CreateOrJoinWorkspaces(p
handleCurrentViewChange={() => setCurrentView(ECreateOrJoinWorkspaceViews.WORKSPACE_CREATE)} handleCurrentViewChange={() => setCurrentView(ECreateOrJoinWorkspaceViews.WORKSPACE_CREATE)}
/> />
) : currentView === ECreateOrJoinWorkspaceViews.WORKSPACE_CREATE ? ( ) : currentView === ECreateOrJoinWorkspaceViews.WORKSPACE_CREATE ? (
isWorkspaceCreationEnabled ? ( !isWorkspaceCreationDisabled ? (
<CreateWorkspace <CreateWorkspace
stepChange={stepChange} stepChange={stepChange}
user={user ?? undefined} user={user ?? undefined}

View file

@ -17,10 +17,10 @@ import type { IUser, IWorkspace } from "@plane/types";
import { Spinner } from "@plane/ui"; import { Spinner } from "@plane/ui";
import { cn } from "@plane/utils"; import { cn } from "@plane/utils";
// hooks // hooks
import { useInstance } from "@/hooks/store/use-instance";
import { useWorkspace } from "@/hooks/store/use-workspace"; import { useWorkspace } from "@/hooks/store/use-workspace";
import { useUserProfile, useUserSettings } from "@/hooks/store/user"; import { useUserProfile, useUserSettings } from "@/hooks/store/user";
// plane-web imports // services
import { getIsWorkspaceCreationDisabled } from "@/plane-web/helpers/instance.helper";
import { WorkspaceService } from "@/services/workspace.service"; import { WorkspaceService } from "@/services/workspace.service";
// local components // local components
import { CommonOnboardingHeader } from "../common"; import { CommonOnboardingHeader } from "../common";
@ -46,11 +46,12 @@ export const WorkspaceCreateStep = observer(function WorkspaceCreateStep({
// plane hooks // plane hooks
const { t } = useTranslation(); const { t } = useTranslation();
// store hooks // store hooks
const { config } = useInstance();
const { updateUserProfile } = useUserProfile(); const { updateUserProfile } = useUserProfile();
const { fetchCurrentUserSettings } = useUserSettings(); const { fetchCurrentUserSettings } = useUserSettings();
const { createWorkspace, fetchWorkspaces } = useWorkspace(); const { createWorkspace, fetchWorkspaces } = useWorkspace();
const isWorkspaceCreationEnabled = getIsWorkspaceCreationDisabled() === false; const isWorkspaceCreationDisabled = config?.is_workspace_creation_disabled ?? false;
// form info // form info
const { const {
@ -113,7 +114,7 @@ export const WorkspaceCreateStep = observer(function WorkspaceCreateStep({
const isButtonDisabled = !isValid || invalidSlug || isSubmitting; const isButtonDisabled = !isValid || invalidSlug || isSubmitting;
if (!isWorkspaceCreationEnabled) { if (isWorkspaceCreationDisabled) {
return ( return (
<div className="flex flex-col gap-10"> <div className="flex flex-col gap-10">
<span className="text-center text-14 text-tertiary"> <span className="text-center text-14 text-tertiary">

View file

@ -15,8 +15,7 @@ import type { TPowerKCommandConfig, TPowerKContext } from "@/components/power-k/
import { useCommandPalette } from "@/hooks/store/use-command-palette"; import { useCommandPalette } from "@/hooks/store/use-command-palette";
import { useProject } from "@/hooks/store/use-project"; import { useProject } from "@/hooks/store/use-project";
import { useUser } from "@/hooks/store/user"; import { useUser } from "@/hooks/store/user";
// plane web imports import { useInstance } from "@/hooks/store/use-instance";
import { getIsWorkspaceCreationDisabled } from "@/plane-web/helpers/instance.helper";
export type TPowerKCreationCommandKeys = export type TPowerKCreationCommandKeys =
| "create_work_item" | "create_work_item"
@ -32,6 +31,7 @@ export type TPowerKCreationCommandKeys =
*/ */
export const usePowerKCreationCommandsRecord = (): Record<TPowerKCreationCommandKeys, TPowerKCommandConfig> => { export const usePowerKCreationCommandsRecord = (): Record<TPowerKCreationCommandKeys, TPowerKCommandConfig> => {
// store // store
const { config } = useInstance();
const { const {
canPerformAnyCreateAction, canPerformAnyCreateAction,
permission: { allowPermissions }, permission: { allowPermissions },
@ -58,7 +58,7 @@ export const usePowerKCreationCommandsRecord = (): Record<TPowerKCreationCommand
ctx.params.workspaceSlug?.toString(), ctx.params.workspaceSlug?.toString(),
ctx.params.projectId?.toString() ctx.params.projectId?.toString()
); );
const isWorkspaceCreationDisabled = getIsWorkspaceCreationDisabled(); const isWorkspaceCreationDisabled = config?.is_workspace_creation_disabled ?? false;
const getProjectDetails = (ctx: TPowerKContext) => const getProjectDetails = (ctx: TPowerKContext) =>
ctx.params.projectId ? getPartialProjectById(ctx.params.projectId.toString()) : undefined; ctx.params.projectId ? getPartialProjectById(ctx.params.projectId.toString()) : undefined;

View file

@ -14,8 +14,6 @@ import { PowerKSettingsMenu } from "@/components/power-k/menus/settings";
import { WORKSPACE_SETTINGS_ICONS } from "@/components/settings/workspace/sidebar/item-icon"; import { WORKSPACE_SETTINGS_ICONS } from "@/components/settings/workspace/sidebar/item-icon";
// hooks // hooks
import { useUserPermissions } from "@/hooks/store/user"; import { useUserPermissions } from "@/hooks/store/user";
// plane web imports
import { shouldRenderSettingLink } from "@/plane-web/helpers/workspace.helper";
type Props = { type Props = {
context: TPowerKContext; context: TPowerKContext;
@ -32,7 +30,6 @@ export const PowerKOpenWorkspaceSettingsMenu = observer(function PowerKOpenWorks
const settingsList = Object.values(WORKSPACE_SETTINGS).filter( const settingsList = Object.values(WORKSPACE_SETTINGS).filter(
(setting) => (setting) =>
context.params.workspaceSlug && context.params.workspaceSlug &&
shouldRenderSettingLink(context.params.workspaceSlug?.toString(), setting.key) &&
allowPermissions(setting.access, EUserPermissionsLevel.WORKSPACE, context.params.workspaceSlug?.toString()) allowPermissions(setting.access, EUserPermissionsLevel.WORKSPACE, context.params.workspaceSlug?.toString())
); );
const settingsListWithIcons = settingsList.map((setting) => ({ const settingsListWithIcons = settingsList.map((setting) => ({

View file

@ -24,8 +24,6 @@ import { useProject } from "@/hooks/store/use-project";
import { useProjectState } from "@/hooks/store/use-project-state"; import { useProjectState } from "@/hooks/store/use-project-state";
import { useProjectView } from "@/hooks/store/use-project-view"; import { useProjectView } from "@/hooks/store/use-project-view";
import { useUser, useUserPermissions } from "@/hooks/store/user"; import { useUser, useUserPermissions } from "@/hooks/store/user";
// plane web imports
import { getAdditionalProjectLevelFiltersHOCProps } from "@/plane-web/helpers/work-item-filters/project-level";
// local imports // local imports
import { WorkItemFiltersHOC } from "./base"; import { WorkItemFiltersHOC } from "./base";
import type { TEnableSaveViewProps, TEnableUpdateViewProps, TSharedWorkItemFiltersHOCProps } from "./shared"; import type { TEnableSaveViewProps, TEnableUpdateViewProps, TSharedWorkItemFiltersHOCProps } from "./shared";
@ -203,11 +201,7 @@ export const ProjectLevelWorkItemFiltersHOC = observer(function ProjectLevelWork
/> />
<WorkItemFiltersHOC <WorkItemFiltersHOC
{...props} {...props}
{...getAdditionalProjectLevelFiltersHOCProps({ workspaceSlug={workspaceSlug}
entityType: props.entityType,
workspaceSlug,
projectId,
})}
cycleIds={getProjectCycleIds(projectId) ?? undefined} cycleIds={getProjectCycleIds(projectId) ?? undefined}
labelIds={getProjectLabelIds(projectId)} labelIds={getProjectLabelIds(projectId)}
memberIds={getProjectMemberIds(projectId, false) ?? undefined} memberIds={getProjectMemberIds(projectId, false) ?? undefined}

View file

@ -4,7 +4,7 @@
* See the LICENSE file for details. * See the LICENSE file for details.
*/ */
import React, { Fragment, useState, useEffect } from "react"; import { Fragment, useState, useEffect } from "react";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import Link from "next/link"; import Link from "next/link";
// icons // icons
@ -24,8 +24,7 @@ import { AppSidebarItem } from "@/components/sidebar/sidebar-item";
import { useAppTheme } from "@/hooks/store/use-app-theme"; import { useAppTheme } from "@/hooks/store/use-app-theme";
import { useWorkspace } from "@/hooks/store/use-workspace"; import { useWorkspace } from "@/hooks/store/use-workspace";
import { useUser, useUserProfile } from "@/hooks/store/user"; import { useUser, useUserProfile } from "@/hooks/store/user";
// plane web helpers import { useInstance } from "@/hooks/store/use-instance";
import { getIsWorkspaceCreationDisabled } from "@/plane-web/helpers/instance.helper";
// components // components
import { WorkspaceLogo } from "../logo"; import { WorkspaceLogo } from "../logo";
import SidebarDropdownItem from "./dropdown-item"; import SidebarDropdownItem from "./dropdown-item";
@ -38,12 +37,13 @@ export const WorkspaceMenuRoot = observer(function WorkspaceMenuRoot(props: Work
const { variant } = props; const { variant } = props;
// store hooks // store hooks
const { toggleSidebar, toggleAnySidebarDropdown } = useAppTheme(); const { toggleSidebar, toggleAnySidebarDropdown } = useAppTheme();
const { config } = useInstance();
const { data: currentUser } = useUser(); const { data: currentUser } = useUser();
const { signOut } = useUser(); const { signOut } = useUser();
const { updateUserProfile } = useUserProfile(); const { updateUserProfile } = useUserProfile();
const { currentWorkspace: activeWorkspace, workspaces } = useWorkspace(); const { currentWorkspace: activeWorkspace, workspaces } = useWorkspace();
// derived values // derived values
const isWorkspaceCreationEnabled = getIsWorkspaceCreationDisabled() === false; const isWorkspaceCreationDisabled = config?.is_workspace_creation_disabled ?? false;
// translation // translation
const { t } = useTranslation(); const { t } = useTranslation();
// local state // local state
@ -187,7 +187,7 @@ export const WorkspaceMenuRoot = observer(function WorkspaceMenuRoot(props: Work
)} )}
</div> </div>
<div className="w-full flex flex-col items-start justify-start gap-2 px-4 py-2 text-13"> <div className="w-full flex flex-col items-start justify-start gap-2 px-4 py-2 text-13">
{isWorkspaceCreationEnabled && ( {!isWorkspaceCreationDisabled && (
<Link href="/create-workspace" className="w-full"> <Link href="/create-workspace" className="w-full">
<Menu.Item <Menu.Item
as="div" as="div"

View file

@ -21,11 +21,6 @@ import type {
TSupportedFilterForUpdate, TSupportedFilterForUpdate,
} from "@plane/types"; } from "@plane/types";
import { EIssuesStoreType } from "@plane/types"; import { EIssuesStoreType } from "@plane/types";
import {
useTeamIssueActions,
useTeamProjectWorkItemsActions,
useTeamViewIssueActions,
} from "@/plane-web/helpers/issue-action-helper";
import { useIssues } from "./store/use-issues"; import { useIssues } from "./store/use-issues";
export interface IssueActions { export interface IssueActions {
@ -50,28 +45,21 @@ export interface IssueActions {
} }
export const useIssuesActions = (storeType: EIssuesStoreType): IssueActions => { export const useIssuesActions = (storeType: EIssuesStoreType): IssueActions => {
const teamIssueActions = useTeamIssueActions();
const projectIssueActions = useProjectIssueActions(); const projectIssueActions = useProjectIssueActions();
const projectEpicsActions = useProjectEpicsActions(); const projectEpicsActions = useProjectEpicsActions();
const cycleIssueActions = useCycleIssueActions(); const cycleIssueActions = useCycleIssueActions();
const moduleIssueActions = useModuleIssueActions(); const moduleIssueActions = useModuleIssueActions();
const teamViewIssueActions = useTeamViewIssueActions();
const projectViewIssueActions = useProjectViewIssueActions(); const projectViewIssueActions = useProjectViewIssueActions();
const globalIssueActions = useGlobalIssueActions(); const globalIssueActions = useGlobalIssueActions();
const profileIssueActions = useProfileIssueActions(); const profileIssueActions = useProfileIssueActions();
const archivedIssueActions = useArchivedIssueActions(); const archivedIssueActions = useArchivedIssueActions();
const workspaceDraftIssueActions = useWorkspaceDraftIssueActions(); const workspaceDraftIssueActions = useWorkspaceDraftIssueActions();
const teamProjectWorkItemsActions = useTeamProjectWorkItemsActions();
switch (storeType) { switch (storeType) {
case EIssuesStoreType.TEAM_VIEW:
return teamViewIssueActions;
case EIssuesStoreType.PROJECT_VIEW: case EIssuesStoreType.PROJECT_VIEW:
return projectViewIssueActions; return projectViewIssueActions;
case EIssuesStoreType.PROFILE: case EIssuesStoreType.PROFILE:
return profileIssueActions; return profileIssueActions;
case EIssuesStoreType.TEAM:
return teamIssueActions;
case EIssuesStoreType.ARCHIVED: case EIssuesStoreType.ARCHIVED:
return archivedIssueActions; return archivedIssueActions;
case EIssuesStoreType.CYCLE: case EIssuesStoreType.CYCLE:
@ -85,8 +73,6 @@ export const useIssuesActions = (storeType: EIssuesStoreType): IssueActions => {
return workspaceDraftIssueActions; return workspaceDraftIssueActions;
case EIssuesStoreType.EPIC: case EIssuesStoreType.EPIC:
return projectEpicsActions; return projectEpicsActions;
case EIssuesStoreType.TEAM_PROJECT_WORK_ITEMS:
return teamProjectWorkItemsActions;
case EIssuesStoreType.PROJECT: case EIssuesStoreType.PROJECT:
default: default:
return projectIssueActions; return projectIssueActions;

View file

@ -9,22 +9,6 @@ import type { IIssueDisplayProperties } from "@plane/types";
// lib // lib
import { store } from "@/lib/store-context"; import { store } from "@/lib/store-context";
export type TShouldRenderDisplayProperty = {
workspaceSlug: string;
projectId: string | undefined;
key: keyof IIssueDisplayProperties;
};
export const shouldRenderDisplayProperty = (props: TShouldRenderDisplayProperty) => {
const { key } = props;
switch (key) {
case "issue_type":
return false;
default:
return true;
}
};
export const shouldRenderColumn = (key: keyof IIssueDisplayProperties): boolean => { export const shouldRenderColumn = (key: keyof IIssueDisplayProperties): boolean => {
const isEstimateEnabled: boolean = store.projectRoot.project.currentProjectDetails?.estimate !== null; const isEstimateEnabled: boolean = store.projectRoot.project.currentProjectDetails?.estimate !== null;
switch (key) { switch (key) {

View file

@ -15,6 +15,7 @@ const VIEW_ACCESS_ICONS = {
[EViewAccess.PUBLIC]: GlobeIcon, [EViewAccess.PUBLIC]: GlobeIcon,
[EViewAccess.PRIVATE]: LockIcon, [EViewAccess.PRIVATE]: LockIcon,
}; };
export const VIEW_ACCESS_SPECIFIERS: { export const VIEW_ACCESS_SPECIFIERS: {
key: EViewAccess; key: EViewAccess;
i18n_label: string; i18n_label: string;

View file

@ -175,10 +175,6 @@ export const ISSUE_DISPLAY_PROPERTIES: {
key: "key", key: "key",
titleTranslationKey: "issue.display.properties.id", titleTranslationKey: "issue.display.properties.id",
}, },
{
key: "issue_type",
titleTranslationKey: "issue.display.properties.issue_type",
},
{ {
key: "assignee", key: "assignee",
titleTranslationKey: "common.assignee", titleTranslationKey: "common.assignee",