diff --git a/apiserver/plane/ee/views/app/issue_property/activity.py b/apiserver/plane/ee/views/app/issue_property/activity.py index de5e56afc5..983e702ea2 100644 --- a/apiserver/plane/ee/views/app/issue_property/activity.py +++ b/apiserver/plane/ee/views/app/issue_property/activity.py @@ -7,6 +7,8 @@ from plane.ee.serializers import IssuePropertyActivitySerializer from plane.ee.models import IssuePropertyActivity from plane.ee.views.base import BaseAPIView from plane.ee.permissions import ProjectEntityPermission +from plane.payment.flags.flag_decorator import check_feature_flag +from plane.payment.flags.flag import FeatureFlag class IssuePropertyActivityEndpoint(BaseAPIView): @@ -15,6 +17,7 @@ class IssuePropertyActivityEndpoint(BaseAPIView): ProjectEntityPermission, ] + @check_feature_flag(FeatureFlag.ISSUE_TYPE_DISPLAY) def get(self, request, slug, project_id, issue_id): # Get the order by order_by = request.GET.get("order_by", "-created_at") diff --git a/apiserver/plane/ee/views/app/issue_property/base.py b/apiserver/plane/ee/views/app/issue_property/base.py index 5ae28574ef..e02962e650 100644 --- a/apiserver/plane/ee/views/app/issue_property/base.py +++ b/apiserver/plane/ee/views/app/issue_property/base.py @@ -68,9 +68,6 @@ class IssuePropertyEndpoint(BaseAPIView): else: bulk_create_options.append(option) - if bulk_create_options: - self.create_options(issue_property, bulk_create_options) - if bulk_update_options: for option in bulk_update_options: issue_property_option = IssuePropertyOption.objects.get( @@ -83,9 +80,11 @@ class IssuePropertyEndpoint(BaseAPIView): issue_property_option, data=option, partial=True ) option_serializer.is_valid(raise_exception=True) - option_serializer.save() + if bulk_create_options: + self.create_options(issue_property, bulk_create_options) + def reset_options_default(self, issue_property): # Reset all the default options IssuePropertyOption.objects.filter( diff --git a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/settings/issue-types/page.tsx b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/settings/issue-types/page.tsx index a2e7337ff6..ec8fd3236a 100644 --- a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/settings/issue-types/page.tsx +++ b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/settings/issue-types/page.tsx @@ -16,7 +16,7 @@ const IssueTypesSettingsPage = observer(() => { const { currentProjectDetails } = useProject(); // derived values const isAdmin = currentProjectRole === EUserProjectRoles.ADMIN; - const pageTitle = currentProjectDetails?.name ? `${currentProjectDetails?.name} - Issue types` : undefined; + const pageTitle = currentProjectDetails?.name ? `${currentProjectDetails?.name} - Issue Types` : undefined; return ( <> diff --git a/web/ee/components/issue-types/common/issue-type-logo.tsx b/web/ee/components/issue-types/common/issue-type-logo.tsx index c633b7eb09..167226cb42 100644 --- a/web/ee/components/issue-types/common/issue-type-logo.tsx +++ b/web/ee/components/issue-types/common/issue-type-logo.tsx @@ -20,6 +20,9 @@ export const IssueTypeLogo: FC = (props) => { // derived values const LucideIcon = LUCIDE_ICONS_LIST.find((item) => item.name === icon_props?.name); + // if no value, return empty fragment + if (!icon_props?.name && !isDefault) return <>; + return ( <> = (props) => { color: icon_props?.color ?? "#ffffff", // fallback color }} /> - ) : LucideIcon ? ( - ) : ( - // fallback icon - + LucideIcon && ( + + ) )} diff --git a/web/ee/components/issue-types/create-update/modal.tsx b/web/ee/components/issue-types/create-update/modal.tsx index 458fd9cf86..1a8cb4bf29 100644 --- a/web/ee/components/issue-types/create-update/modal.tsx +++ b/web/ee/components/issue-types/create-update/modal.tsx @@ -75,11 +75,11 @@ export const CreateOrUpdateIssueTypeModal: FC = (props) => { message: `Issue type created successfully.`, }); }) - .catch(() => { + .catch((error) => { setToast({ type: TOAST_TYPE.ERROR, title: "Error!", - message: `Failed to create issue type. Please try again!`, + message: error?.error ?? `Failed to create issue type. Please try again!`, }); }) .finally(() => { @@ -101,11 +101,11 @@ export const CreateOrUpdateIssueTypeModal: FC = (props) => { message: `Issue type ${issueTypeFormData?.name} updated successfully.`, }); }) - .catch(() => { + .catch((error) => { setToast({ type: TOAST_TYPE.ERROR, title: "Error!", - message: `Failed to update issue type. Please try again!`, + message: error?.error ?? `Failed to update issue type. Please try again!`, }); }) .finally(() => { diff --git a/web/ee/components/issue-types/empty-state.tsx b/web/ee/components/issue-types/empty-state.tsx index a72090f076..5423e83109 100644 --- a/web/ee/components/issue-types/empty-state.tsx +++ b/web/ee/components/issue-types/empty-state.tsx @@ -4,6 +4,8 @@ import Image from "next/image"; import { useTheme } from "next-themes"; // ui import { Button, setToast, TOAST_TYPE } from "@plane/ui"; +// components +import { ComicBoxButton } from "@/components/empty-state"; // helpers import { cn } from "@/helpers/common.helper"; // plane web hooks @@ -55,11 +57,11 @@ export const IssueTypeEmptyState: FC = observer((props) =>

- {isIssueTypeSettingsEnabled ? "Enable issue types" : "Upgrade to enable issue types"} + {isIssueTypeSettingsEnabled ? "Enable Issue Types" : "Upgrade to enable Issue Types."}

- Issue types distinguish different kinds of work in unique ways, helping you to identify, categorize, and - report on your team{"’"}s work more effectively. + Shape issues to your work with Issue Types. Customize with icons, backgrounds, and properties and configure + them for this project.

= observer((props) => />
{isIssueTypeSettingsEnabled ? ( - + handleEnableIssueTypes()} + /> ) : ( @@ -71,7 +71,7 @@ export const IssuePropertyQuickActions = observer((props: TIssuePropertyQuickAct onClick={onDiscard} disabled={isSubmitting} > - + @@ -80,9 +80,9 @@ export const IssuePropertyQuickActions = observer((props: TIssuePropertyQuickAct @@ -90,7 +90,7 @@ export const IssuePropertyQuickActions = observer((props: TIssuePropertyQuickAct className="p-1 border-[0.5px] border-custom-border-300 rounded bg-custom-background-100 hover:bg-custom-background-90" onClick={() => setIsDeleteModalOpen(true)} > - + diff --git a/web/ee/components/issue-types/quick-actions.tsx b/web/ee/components/issue-types/quick-actions.tsx index f73b441fa2..4eb9a83916 100644 --- a/web/ee/components/issue-types/quick-actions.tsx +++ b/web/ee/components/issue-types/quick-actions.tsx @@ -54,16 +54,7 @@ export const IssueTypeQuickActions: React.FC = observer((props) => { return ( <> -
- -
- -
-
+
+ +
+ +
+
); diff --git a/web/ee/components/issue-types/root.tsx b/web/ee/components/issue-types/root.tsx index dffce8b846..43d941f5fe 100644 --- a/web/ee/components/issue-types/root.tsx +++ b/web/ee/components/issue-types/root.tsx @@ -30,7 +30,7 @@ export const IssueTypesRoot = observer(() => { return (
-

Issue types

+

Issue Types

{isIssueTypeSettingsEnabled && currentProjectDetails?.is_issue_type_enabled && (