Compare commits

...
Author SHA1 Message Date
pablohashescobar b45d6d695d fix: handle missing comments in create_comment_reaction_activity and format cycle dates in IssueExportSchema 2025-10-22 16:03:24 +05:30
sriramveeraghanta 98b81d7ebb chore(deps): happy dom version bump 2025-10-16 14:55:57 +05:30
AaronandGitHub 00807d2d62 [WEB-5157] chore: fix propel icon clip paths #7975 2025-10-16 14:03:26 +05:30
Vamsi KrishnaandGitHub 9d757ccc6a [WEB-5156] fix: activity filters bug #7971 2025-10-15 19:57:52 +05:30
Anmol Singh BhatiaandGitHub a8c253acfe [WEB-5154] chore: nav button text colour updated #7970 2025-10-15 19:27:10 +05:30
Vamsi KrishnaandGitHub 2b106cbd66 [WEB-5054]feat: added activity filters for state and assignee activities (#7918)
* feat: added activity filters for state and assignee

* chore: removed unused funtion

* chore: lint fix
2025-10-15 17:12:03 +05:30
sriramveeraghanta f9cca8e2cb fix: live server log 2025-10-15 16:18:42 +05:30
ee176efae3 [WEB-5095]chore: updated delete modal info content (#7967)
* chore: updated delete modal info content

* chore: added language support for modal content

---------

Co-authored-by: sriramveeraghanta <veeraghanta.sriram@gmail.com>
2025-10-15 16:05:55 +05:30
Akshita GoyalandGitHub 44a483f895 [WEB-5142] fix: Issue modal styling #7961 2025-10-15 15:19:40 +05:30
sriramveeraghanta 196baf099a chore: lint errors 2025-10-15 15:15:48 +05:30
NikhilandGitHub 1a9ebc8b68 [WEB-5071] chore: implement webhook logging to MongoDB and fallback to database (#7896)
* feat: implement webhook logging to MongoDB and fallback to database (#7887)

- Added a new function `save_webhook_log` to log webhook requests and responses to MongoDB, with a fallback to the database if the MongoDB save fails.
- Updated the `webhook_send_task` to utilize the new logging function.
- Modified the `get_webhook_logs_queryset` to order logs by creation date and adjusted the chunk size for iteration.

* refactor: clean up log data formatting in save_webhook_log function

* fix: update retry_count type in save_webhook_log function
2025-10-15 14:53:43 +05:30
Vamsi KrishnaandGitHub 97e662215a [WEB-5125] fix: suspended user view #7964 2025-10-14 17:35:39 +05:30
Bavisetti NarayanandGitHub 606e34ec81 [WIKI-730] chore: handle body too large error (#7963)
* chore: added middleware to handle body too large

* chore: added middleware to handle body too large

* chore: indentend the code

* chore: changed the response structure

* chore: changed the response structure

* chore: created a new file for middleware

* chore: added a standardized error key
2025-10-14 17:21:11 +05:30
Anmol Singh BhatiaandGitHub a3019ebd46 [WEB-5092] feat: app sidebar enhancements (#7946)
* chore: project sidebar and settings sidebar improvement

* chore: navigationitem ui improvement

* chore: workspace level new icon added

* chore: propel icon migration

* chore: code refactor

* chore: dashboard icon updated

* chore: code refactor

* chore: icons updated

* chore: code refactor

* chore: code refactor

* chore: scroll area component refactor

* chore: sidebar enhancements

* chore: add and archive icon updated

* chore: code refactor

* chore: code refactor

* chore: code refactor
2025-10-14 17:20:20 +05:30
Prateek ShouryaandGitHub 9cfde896b3 [WEB-5134] refactor: update web ESLint configuration and refactor imports to use type imports (#7957)
* [WEB-5134] refactor: update `web` ESLint configuration and refactor imports to use type imports

- Enhanced ESLint configuration by adding new rules for import consistency and type imports.
- Refactored multiple files to replace regular imports with type imports for better clarity and performance.
- Ensured consistent use of type imports across the application to align with TypeScript best practices.

* refactor: standardize type imports across components

- Updated multiple files to replace regular imports with type imports for improved clarity and consistency.
- Ensured adherence to TypeScript best practices in the rich filters and issue layouts components.
2025-10-14 16:45:07 +05:30
1123 changed files with 5948 additions and 5087 deletions
+2 -1
View File
@@ -410,7 +410,8 @@ def get_webhook_logs_queryset():
"response_headers",
"retry_count",
)
.iterator(chunk_size=BATCH_SIZE)
.order_by("created_at")
.iterator(chunk_size=100)
)
@@ -1154,7 +1154,10 @@ def create_comment_reaction_activity(
.values_list("id", "comment__id")
.first()
)
comment = IssueComment.objects.get(pk=comment_id, project_id=project_id)
comment = IssueComment.objects.filter(pk=comment_id, project_id=project_id).first()
if comment is None:
return
if comment is not None and comment_reaction_id is not None and comment_id is not None:
issue_activities.append(
IssueActivity(
+71 -19
View File
@@ -48,6 +48,8 @@ from plane.db.models import (
)
from plane.license.utils.instance_value import get_email_configuration
from plane.utils.exception_logger import log_exception
from plane.settings.mongo import MongoConnection
SERIALIZER_MAPPER = {
"project": ProjectSerializer,
@@ -84,6 +86,58 @@ def get_issue_prefetches():
]
def save_webhook_log(
webhook: Webhook,
request_method: str,
request_headers: str,
request_body: str,
response_status: str,
response_headers: str,
response_body: str,
retry_count: int,
event_type: str,
) -> None:
# webhook_logs
mongo_collection = MongoConnection.get_collection("webhook_logs")
log_data = {
"workspace_id": str(webhook.workspace_id),
"webhook": str(webhook.id),
"event_type": str(event_type),
"request_method": str(request_method),
"request_headers": str(request_headers),
"request_body": str(request_body),
"response_status": str(response_status),
"response_headers": str(response_headers),
"response_body": str(response_body),
"retry_count": retry_count,
}
mongo_save_success = False
if mongo_collection is not None:
try:
# insert the log data into the mongo collection
mongo_collection.insert_one(log_data)
logger.info("Webhook log saved successfully to mongo")
mongo_save_success = True
except Exception as e:
log_exception(e)
logger.error(f"Failed to save webhook log: {e}")
mongo_save_success = False
# if the mongo save is not successful, save the log data into the database
if not mongo_save_success:
try:
# insert the log data into the database
WebhookLog.objects.create(**log_data)
logger.info("Webhook log saved successfully to database")
except Exception as e:
log_exception(e)
logger.error(f"Failed to save webhook log: {e}")
def get_model_data(event: str, event_id: Union[str, List[str]], many: bool = False) -> Dict[str, Any]:
"""
Retrieve and serialize model data based on the event type.
@@ -273,32 +327,30 @@ def webhook_send_task(
response = requests.post(webhook.url, headers=headers, json=payload, timeout=30)
# Log the webhook request
WebhookLog.objects.create(
workspace_id=str(webhook.workspace_id),
webhook=str(webhook.id),
event_type=str(event),
request_method=str(action),
request_headers=str(headers),
request_body=str(payload),
response_status=str(response.status_code),
response_headers=str(response.headers),
response_body=str(response.text),
retry_count=str(self.request.retries),
save_webhook_log(
webhook=webhook,
request_method=action,
request_headers=headers,
request_body=payload,
response_status=response.status_code,
response_headers=response.headers,
response_body=response.text,
retry_count=self.request.retries,
event_type=event,
)
logger.info(f"Webhook {webhook.id} sent successfully")
except requests.RequestException as e:
# Log the failed webhook request
WebhookLog.objects.create(
workspace_id=str(webhook.workspace_id),
webhook=str(webhook.id),
event_type=str(event),
request_method=str(action),
request_headers=str(headers),
request_body=str(payload),
save_webhook_log(
webhook=webhook,
request_method=action,
request_headers=headers,
request_body=payload,
response_status=500,
response_headers="",
response_body=str(e),
retry_count=str(self.request.retries),
retry_count=self.request.retries,
event_type=event,
)
logger.error(f"Webhook {webhook.id} failed with error: {e}")
# Retry logic
-1
View File
@@ -12,7 +12,6 @@ from rest_framework.request import Request
from plane.utils.ip_address import get_client_ip
from plane.db.models import APIActivityLog
api_logger = logging.getLogger("plane.api.request")
@@ -0,0 +1,27 @@
from django.core.exceptions import RequestDataTooBig
from django.http import JsonResponse
class RequestBodySizeLimitMiddleware:
"""
Middleware to catch RequestDataTooBig exceptions and return
413 Request Entity Too Large instead of 400 Bad Request.
"""
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
try:
_ = request.body
except RequestDataTooBig:
return JsonResponse(
{
"error": "REQUEST_BODY_TOO_LARGE",
"detail": "The size of the request body exceeds the maximum allowed size.",
},
status=413,
)
# If body size is OK, continue with the request
return self.get_response(request)
+1
View File
@@ -62,6 +62,7 @@ MIDDLEWARE = [
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"crum.CurrentRequestUserMiddleware",
"django.middleware.gzip.GZipMiddleware",
"plane.middleware.request_body_size.RequestBodySizeLimitMiddleware",
"plane.middleware.logger.APITokenLogMiddleware",
"plane.middleware.logger.RequestLoggerMiddleware",
]
@@ -169,12 +169,17 @@ class IssueExportSchema(ExportSchema):
def prepare_cycle_start_date(self, i):
cycles_dict = self.context.get("cycles_dict") or {}
last_cycle = cycles_dict.get(i.id)
return last_cycle.cycle.start_date if last_cycle else None
if last_cycle and last_cycle.cycle.start_date:
return self._format_date(last_cycle.cycle.start_date)
return ""
def prepare_cycle_end_date(self, i):
cycles_dict = self.context.get("cycles_dict") or {}
last_cycle = cycles_dict.get(i.id)
return last_cycle.cycle.end_date if last_cycle else None
if last_cycle and last_cycle.cycle.end_date:
return self._format_date(last_cycle.cycle.end_date)
return ""
def prepare_parent(self, i):
if not i.parent:
+1 -2
View File
@@ -1,6 +1,5 @@
import * as dotenv from "@dotenvx/dotenvx";
import { z } from "zod";
import { logger } from "@plane/logger";
dotenv.config();
@@ -28,7 +27,7 @@ const envSchema = z.object({
const validateEnv = () => {
const result = envSchema.safeParse(process.env);
if (!result.success) {
logger.error("❌ Invalid environment variables:", JSON.stringify(result.error.format(), null, 4));
console.error("❌ Invalid environment variables:", JSON.stringify(result.error.format(), null, 4));
process.exit(1);
}
return result.data;
+14
View File
@@ -1,4 +1,18 @@
module.exports = {
root: true,
extends: ["@plane/eslint-config/next.js"],
rules: {
"no-duplicate-imports": "off",
"import/no-duplicates": ["error", { "prefer-inline": false }],
"import/consistent-type-specifier-style": ["error", "prefer-top-level"],
"@typescript-eslint/no-import-type-side-effects": "error",
"@typescript-eslint/consistent-type-imports": [
"error",
{
prefer: "type-imports",
fixStyle: "separate-type-imports",
disallowTypeAnnotations: false,
},
],
},
};
@@ -1,5 +1,6 @@
"use client";
import { FC, useState } from "react";
import type { FC } from "react";
import { useState } from "react";
import { observer } from "mobx-react";
// plane imports
import { SIDEBAR_WIDTH } from "@plane/constants";
@@ -6,7 +6,8 @@ import { useRouter } from "next/navigation";
// plane package imports
import { EUserPermissions, EUserPermissionsLevel, PROJECT_TRACKER_ELEMENTS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { type TabItem, Tabs } from "@plane/ui";
import { Tabs } from "@plane/ui";
import type { TabItem } from "@plane/ui";
// components
import AnalyticsFilterActions from "@/components/analytics/analytics-filter-actions";
import { PageHead } from "@/components/core/page-title";
@@ -17,7 +17,7 @@ import { SidebarProjectsListItem } from "@/components/workspace/sidebar/projects
import { useAppTheme } from "@/hooks/store/use-app-theme";
import { useProject } from "@/hooks/store/use-project";
import { useUserPermissions } from "@/hooks/store/user";
import { TProject } from "@/plane-web/types";
import type { TProject } from "@/plane-web/types";
import { ExtendedSidebarWrapper } from "./extended-sidebar-wrapper";
export const ExtendedProjectSidebar = observer(() => {
@@ -1,6 +1,7 @@
"use client";
import React, { FC } from "react";
import type { FC } from "react";
import React from "react";
import { observer } from "mobx-react";
// plane imports
import { EXTENDED_SIDEBAR_WIDTH, SIDEBAR_WIDTH } from "@plane/constants";
@@ -5,7 +5,7 @@ import { observer } from "mobx-react";
import { useParams } from "next/navigation";
// plane imports
import { WORKSPACE_SIDEBAR_DYNAMIC_NAVIGATION_ITEMS_LINKS } from "@plane/constants";
import { EUserWorkspaceRoles } from "@plane/types";
import type { EUserWorkspaceRoles } from "@plane/types";
// hooks
import { useAppTheme } from "@/hooks/store/use-app-theme";
import { useWorkspace } from "@/hooks/store/use-workspace";
@@ -1,14 +1,14 @@
"use client";
// ui
import { FC } from "react";
import type { FC } from "react";
import { observer } from "mobx-react";
import { useParams, useRouter } from "next/navigation";
import { ChevronDown, PanelRight } from "lucide-react";
import { PROFILE_VIEWER_TAB, PROFILE_ADMINS_TAB, EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { YourWorkIcon } from "@plane/propel/icons";
import { IUserProfileProjectSegregation } from "@plane/types";
import type { IUserProfileProjectSegregation } from "@plane/types";
import { Breadcrumbs, Header, CustomMenu } from "@plane/ui";
import { cn } from "@plane/utils";
// components
@@ -10,13 +10,13 @@ import { EIssueFilterType, ISSUE_LAYOUTS, ISSUE_DISPLAY_FILTERS_BY_PAGE } from "
// plane i18n
import { useTranslation } from "@plane/i18n";
// types
import {
EIssuesStoreType,
import type {
IIssueDisplayFilterOptions,
IIssueDisplayProperties,
TIssueLayouts,
EIssueLayoutTypes,
} from "@plane/types";
import { EIssuesStoreType } from "@plane/types";
// ui
import { CustomMenu } from "@plane/ui";
// components
@@ -5,7 +5,7 @@ import useSWR from "swr";
// plane imports
import { GROUP_CHOICES } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { IUserStateDistribution, TStateGroups } from "@plane/types";
import type { IUserStateDistribution, TStateGroups } from "@plane/types";
import { ContentWrapper } from "@plane/ui";
// components
import { PageHead } from "@/components/core/page-title";
@@ -1,6 +1,6 @@
"use client";
import { FC } from "react";
import type { FC } from "react";
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
import { ArchiveIcon, CycleIcon, ModuleIcon, WorkItemsIcon } from "@plane/propel/icons";
@@ -19,13 +19,8 @@ import { useTranslation } from "@plane/i18n";
import { Button } from "@plane/propel/button";
import { CycleIcon } from "@plane/propel/icons";
import { Tooltip } from "@plane/propel/tooltip";
import {
EIssuesStoreType,
ICustomSearchSelectOption,
IIssueDisplayFilterOptions,
IIssueDisplayProperties,
EIssueLayoutTypes,
} from "@plane/types";
import type { ICustomSearchSelectOption, IIssueDisplayFilterOptions, IIssueDisplayProperties } from "@plane/types";
import { EIssuesStoreType, EIssueLayoutTypes } from "@plane/types";
import { Breadcrumbs, BreadcrumbNavigationSearchDropdown, Header } from "@plane/ui";
import { cn } from "@plane/utils";
// components
@@ -7,7 +7,8 @@ import { Calendar, ChevronDown, Kanban, List } from "lucide-react";
// plane imports
import { EIssueFilterType, ISSUE_LAYOUTS, ISSUE_DISPLAY_FILTERS_BY_PAGE } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { EIssuesStoreType, IIssueDisplayFilterOptions, IIssueDisplayProperties, EIssueLayoutTypes } from "@plane/types";
import type { IIssueDisplayFilterOptions, IIssueDisplayProperties, EIssueLayoutTypes } from "@plane/types";
import { EIssuesStoreType } from "@plane/types";
import { CustomMenu } from "@plane/ui";
// components
import { WorkItemsModal } from "@/components/analytics/work-items/modal";
@@ -1,6 +1,6 @@
"use client";
import { FC } from "react";
import type { FC } from "react";
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
// ui
@@ -2,9 +2,10 @@
import { observer } from "mobx-react";
// ui
import { GanttChartSquare, LayoutGrid, List, type LucideIcon } from "lucide-react";
import { GanttChartSquare, LayoutGrid, List } from "lucide-react";
import type { LucideIcon } from "lucide-react";
// plane package imports
import { TCycleLayoutOptions } from "@plane/types";
import type { TCycleLayoutOptions } from "@plane/types";
import { CustomMenu } from "@plane/ui";
// hooks
import { useCycleFilter } from "@/hooks/store/use-cycle-filter";
@@ -6,7 +6,8 @@ import { useParams } from "next/navigation";
// plane imports
import { EUserPermissionsLevel, CYCLE_TRACKER_ELEMENTS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { EUserProjectRoles, TCycleFilters } from "@plane/types";
import type { TCycleFilters } from "@plane/types";
import { EUserProjectRoles } from "@plane/types";
// components
import { Header, EHeaderVariant } from "@plane/ui";
import { calculateTotalFilters } from "@plane/utils";
@@ -7,7 +7,8 @@ import { ChevronDown } from "lucide-react";
// plane imports
import { EIssueFilterType, ISSUE_DISPLAY_FILTERS_BY_PAGE } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { EIssuesStoreType, IIssueDisplayFilterOptions, IIssueDisplayProperties, EIssueLayoutTypes } from "@plane/types";
import type { IIssueDisplayFilterOptions, IIssueDisplayProperties } from "@plane/types";
import { EIssuesStoreType, EIssueLayoutTypes } from "@plane/types";
// components
import { WorkItemsModal } from "@/components/analytics/work-items/modal";
import {
@@ -17,13 +17,8 @@ import {
import { Button } from "@plane/propel/button";
import { ModuleIcon } from "@plane/propel/icons";
import { Tooltip } from "@plane/propel/tooltip";
import {
EIssuesStoreType,
ICustomSearchSelectOption,
IIssueDisplayFilterOptions,
IIssueDisplayProperties,
EIssueLayoutTypes,
} from "@plane/types";
import type { ICustomSearchSelectOption, IIssueDisplayFilterOptions, IIssueDisplayProperties } from "@plane/types";
import { EIssuesStoreType, EIssueLayoutTypes } from "@plane/types";
import { Breadcrumbs, Header, BreadcrumbNavigationSearchDropdown } from "@plane/ui";
import { cn } from "@plane/utils";
// components
@@ -8,7 +8,8 @@ import { Calendar, ChevronDown, Kanban, List } from "lucide-react";
// plane imports
import { EIssueFilterType, ISSUE_LAYOUTS, ISSUE_DISPLAY_FILTERS_BY_PAGE } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { EIssuesStoreType, IIssueDisplayFilterOptions, IIssueDisplayProperties, EIssueLayoutTypes } from "@plane/types";
import type { IIssueDisplayFilterOptions, IIssueDisplayProperties, EIssueLayoutTypes } from "@plane/types";
import { EIssuesStoreType } from "@plane/types";
import { CustomMenu } from "@plane/ui";
// components
import { WorkItemsModal } from "@/components/analytics/work-items/modal";
@@ -6,7 +6,8 @@ import { useParams } from "next/navigation";
// types
import { EUserPermissionsLevel } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { EUserProjectRoles, TModuleFilters } from "@plane/types";
import type { TModuleFilters } from "@plane/types";
import { EUserProjectRoles } from "@plane/types";
// components
import { calculateTotalFilters } from "@plane/utils";
import { PageHead } from "@/components/core/page-title";
@@ -7,7 +7,8 @@ import { useParams } from "next/navigation";
import useSWR from "swr";
// plane types
import { getButtonStyling } from "@plane/propel/button";
import { EFileAssetType, TSearchEntityRequestPayload, TWebhookConnectionQueryParams } from "@plane/types";
import type { TSearchEntityRequestPayload, TWebhookConnectionQueryParams } from "@plane/types";
import { EFileAssetType } from "@plane/types";
// plane ui
// plane utils
import { cn } from "@plane/utils";
@@ -15,7 +16,8 @@ import { cn } from "@plane/utils";
import { LogoSpinner } from "@/components/common/logo-spinner";
import { PageHead } from "@/components/core/page-title";
import { IssuePeekOverview } from "@/components/issues/peek-overview";
import { PageRoot, TPageRootConfig, TPageRootHandlers } from "@/components/pages/editor/page-root";
import type { TPageRootConfig, TPageRootHandlers } from "@/components/pages/editor/page-root";
import { PageRoot } from "@/components/pages/editor/page-root";
// hooks
import { useEditorConfig } from "@/hooks/editor";
import { useEditorAsset } from "@/hooks/store/use-editor-asset";
@@ -4,7 +4,7 @@ import { useParams } from "next/navigation";
import { EProjectFeatureKey } from "@plane/constants";
import { PageIcon } from "@plane/propel/icons";
// types
import { ICustomSearchSelectOption } from "@plane/types";
import type { ICustomSearchSelectOption } from "@plane/types";
// ui
import { Breadcrumbs, Header, BreadcrumbNavigationSearchDropdown } from "@plane/ui";
// components
@@ -13,7 +13,7 @@ import {
// plane types
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { TPage } from "@plane/types";
import type { TPage } from "@plane/types";
// plane ui
import { Breadcrumbs, Header } from "@plane/ui";
// helpers
@@ -1,6 +1,6 @@
"use client";
import { ReactNode } from "react";
import type { ReactNode } from "react";
// components
import { AppHeader } from "@/components/core/app-header";
import { ContentWrapper } from "@/components/core/content-wrapper";
@@ -5,7 +5,8 @@ import { useParams, useSearchParams } from "next/navigation";
// plane imports
import { EUserPermissionsLevel } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { EUserProjectRoles, TPageNavigationTabs } from "@plane/types";
import type { TPageNavigationTabs } from "@plane/types";
import { EUserProjectRoles } from "@plane/types";
// components
import { PageHead } from "@/components/core/page-title";
import { DetailedEmptyState } from "@/components/empty-state/detailed-empty-state-root";
@@ -17,14 +17,8 @@ import {
import { Button } from "@plane/propel/button";
import { ViewsIcon } from "@plane/propel/icons";
import { Tooltip } from "@plane/propel/tooltip";
import {
EIssuesStoreType,
EViewAccess,
ICustomSearchSelectOption,
IIssueDisplayFilterOptions,
IIssueDisplayProperties,
EIssueLayoutTypes,
} from "@plane/types";
import type { ICustomSearchSelectOption, IIssueDisplayFilterOptions, IIssueDisplayProperties } from "@plane/types";
import { EIssuesStoreType, EViewAccess, EIssueLayoutTypes } from "@plane/types";
// ui
import { Breadcrumbs, Header, BreadcrumbNavigationSearchDropdown } from "@plane/ui";
// components
@@ -6,7 +6,8 @@ import { useParams } from "next/navigation";
// components
import { EUserPermissionsLevel } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { EUserProjectRoles, EViewAccess, TViewFilterProps } from "@plane/types";
import type { EViewAccess, TViewFilterProps } from "@plane/types";
import { EUserProjectRoles } from "@plane/types";
import { Header, EHeaderVariant } from "@plane/ui";
import { calculateTotalFilters } from "@plane/utils";
import { PageHead } from "@/components/core/page-title";
@@ -1,6 +1,6 @@
"use client";
import { ReactNode } from "react";
import type { ReactNode } from "react";
// components
import { AppHeader } from "@/components/core/app-header";
import { ContentWrapper } from "@/components/core/content-wrapper";
@@ -1,6 +1,6 @@
"use client";
import { ReactNode } from "react";
import type { ReactNode } from "react";
import { useParams } from "next/navigation";
// plane web layouts
import { ProjectAuthWrapper } from "@/plane-web/layouts/project-wrapper";
@@ -1,6 +1,6 @@
"use client";
import { ReactNode } from "react";
import type { ReactNode } from "react";
// components
import { AppHeader } from "@/components/core/app-header";
import { ContentWrapper } from "@/components/core/content-wrapper";
@@ -1,4 +1,4 @@
import { FC } from "react";
import type { FC } from "react";
import { isEmpty } from "lodash-es";
import { observer } from "mobx-react";
// plane helpers
@@ -13,13 +13,8 @@ import {
import { useTranslation } from "@plane/i18n";
import { Button } from "@plane/propel/button";
import { ViewsIcon } from "@plane/propel/icons";
import {
EIssuesStoreType,
IIssueDisplayFilterOptions,
IIssueDisplayProperties,
ICustomSearchSelectOption,
EIssueLayoutTypes,
} from "@plane/types";
import type { IIssueDisplayFilterOptions, IIssueDisplayProperties, ICustomSearchSelectOption } from "@plane/types";
import { EIssuesStoreType, EIssueLayoutTypes } from "@plane/types";
import { Breadcrumbs, Header, BreadcrumbNavigationSearchDropdown } from "@plane/ui";
// components
import { BreadcrumbLink } from "@/components/common/breadcrumb-link";
@@ -1,11 +1,11 @@
"use client";
import { FC, ReactNode } from "react";
import type { FC, ReactNode } from "react";
import { observer } from "mobx-react";
import { usePathname } from "next/navigation";
// constants
import { WORKSPACE_SETTINGS_ACCESS } from "@plane/constants";
import { EUserWorkspaceRoles } from "@plane/types";
import type { EUserWorkspaceRoles } from "@plane/types";
// components
import { NotAuthorizedView } from "@/components/auth-screens/not-authorized-view";
import { getWorkspaceActivePath, pathnameToAccessKey } from "@/components/settings/helper";
@@ -14,7 +14,7 @@ import {
import { useTranslation } from "@plane/i18n";
import { Button } from "@plane/propel/button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { IWorkspaceBulkInviteFormData } from "@plane/types";
import type { IWorkspaceBulkInviteFormData } from "@plane/types";
import { cn } from "@plane/utils";
// components
import { NotAuthorizedView } from "@/components/auth-screens/not-authorized-view";
@@ -7,7 +7,7 @@ import {
EUserPermissions,
WORKSPACE_SETTINGS_CATEGORY,
} from "@plane/constants";
import { EUserWorkspaceRoles } from "@plane/types";
import type { EUserWorkspaceRoles } from "@plane/types";
import { SettingsSidebar } from "@/components/settings/sidebar";
import { useUserPermissions } from "@/hooks/store/user";
import { shouldRenderSettingLink } from "@/plane-web/helpers/workspace.helper";
@@ -6,7 +6,7 @@ import { useParams } from "next/navigation";
import useSWR from "swr";
import { EUserPermissions, EUserPermissionsLevel, WORKSPACE_SETTINGS_TRACKER_EVENTS } from "@plane/constants";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { IWebhook } from "@plane/types";
import type { IWebhook } from "@plane/types";
// ui
// components
import { LogoSpinner } from "@/components/common/logo-spinner";
@@ -1,6 +1,6 @@
"use client";
import { ReactNode } from "react";
import type { ReactNode } from "react";
import { observer } from "mobx-react";
import { usePathname } from "next/navigation";
// components
@@ -15,7 +15,8 @@ import { getPasswordStrength } from "@plane/utils";
import { PageHead } from "@/components/core/page-title";
import { ProfileSettingContentHeader } from "@/components/profile/profile-setting-content-header";
// helpers
import { authErrorHandler, type EAuthenticationErrorCodes } from "@/helpers/authentication.helper";
import { authErrorHandler } from "@/helpers/authentication.helper";
import type { EAuthenticationErrorCodes } from "@/helpers/authentication.helper";
// hooks
import { useUser } from "@/hooks/store/user";
// services
@@ -6,7 +6,7 @@ import { useParams } from "next/navigation";
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import { IProject } from "@plane/types";
import type { IProject } from "@plane/types";
// ui
// components
import { NotAuthorizedView } from "@/components/auth-screens/not-authorized-view";
@@ -1,6 +1,7 @@
"use client";
import { ReactNode, useEffect } from "react";
import type { ReactNode } from "react";
import { useEffect } from "react";
import { observer } from "mobx-react";
import { useParams, usePathname } from "next/navigation";
// components
@@ -1,4 +1,4 @@
import { Metadata } from "next";
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Forgot Password - Plane",
@@ -1,4 +1,4 @@
import { Metadata } from "next";
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Reset Password - Plane",
@@ -1,4 +1,4 @@
import { Metadata } from "next";
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Set Password - Plane",
@@ -1,4 +1,4 @@
import { Metadata } from "next";
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Create Workspace",
+1 -1
View File
@@ -8,7 +8,7 @@ import Link from "next/link";
import { useTranslation } from "@plane/i18n";
import { Button, getButtonStyling } from "@plane/propel/button";
import { PlaneLogo } from "@plane/propel/icons";
import { IWorkspace } from "@plane/types";
import type { IWorkspace } from "@plane/types";
// components
import { CreateWorkspaceForm } from "@/components/workspace/create-workspace-form";
// hooks
+1 -1
View File
@@ -1,4 +1,4 @@
import { Metadata } from "next";
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Invitations",
+1 -1
View File
@@ -1,4 +1,4 @@
import { Metadata, Viewport } from "next";
import type { Metadata, Viewport } from "next";
import { PreloadResources } from "./layout.preload";
+1 -1
View File
@@ -1,4 +1,4 @@
import { Metadata } from "next";
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Onboarding",
@@ -4,10 +4,11 @@ import { useEffect, useState } from "react";
import { observer } from "mobx-react";
import { useTheme } from "next-themes";
// plane imports
import { I_THEME_OPTION, THEME_OPTIONS } from "@plane/constants";
import type { I_THEME_OPTION } from "@plane/constants";
import { THEME_OPTIONS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { setPromiseToast } from "@plane/propel/toast";
import { IUserTheme } from "@plane/types";
import type { IUserTheme } from "@plane/types";
// components
import { applyTheme, unsetCustomCssVariables } from "@plane/utils";
import { LogoSpinner } from "@/components/common/logo-spinner";
+1 -1
View File
@@ -1,6 +1,6 @@
"use client";
import { ReactNode } from "react";
import type { ReactNode } from "react";
// components
import { CommandPalette } from "@/components/command-palette";
// wrappers
+2 -1
View File
@@ -16,7 +16,8 @@ import { PageHead } from "@/components/core/page-title";
import { ProfileSettingContentHeader } from "@/components/profile/profile-setting-content-header";
import { ProfileSettingContentWrapper } from "@/components/profile/profile-setting-content-wrapper";
// helpers
import { authErrorHandler, type EAuthenticationErrorCodes } from "@/helpers/authentication.helper";
import { authErrorHandler } from "@/helpers/authentication.helper";
import type { EAuthenticationErrorCodes } from "@/helpers/authentication.helper";
// hooks
import { useUser } from "@/hooks/store/user";
// services
+1 -1
View File
@@ -1,4 +1,4 @@
import { Metadata } from "next";
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Sign up - Plane",
@@ -1,4 +1,4 @@
import { Metadata } from "next";
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Workspace Invitations",
+1 -1
View File
@@ -1,4 +1,4 @@
import { Metadata, Viewport } from "next";
import type { Metadata, Viewport } from "next";
export const metadata: Metadata = {
robots: {
+1 -1
View File
@@ -1,4 +1,4 @@
import { Metadata, Viewport } from "next";
import type { Metadata, Viewport } from "next";
import Script from "next/script";
// styles
+1 -1
View File
@@ -1,7 +1,7 @@
"use client";
import React from "react";
import { Metadata } from "next";
import type { Metadata } from "next";
import Image from "next/image";
import Link from "next/link";
// ui
+1 -1
View File
@@ -1,6 +1,6 @@
"use client";
import { FC, ReactNode } from "react";
import type { FC, ReactNode } from "react";
import { AppProgressProvider as ProgressProvider } from "@bprogress/next";
import dynamic from "next/dynamic";
import { useTheme, ThemeProvider } from "next-themes";
+1 -1
View File
@@ -1,4 +1,4 @@
import { AnalyticsTab } from "@plane/types";
import type { AnalyticsTab } from "@plane/types";
import { Overview } from "@/components/analytics/overview";
import { WorkItems } from "@/components/analytics/work-items";
+2 -1
View File
@@ -1,6 +1,7 @@
"use client";
import React, { FC } from "react";
import type { FC } from "react";
import React from "react";
export type TCustomAutomationsRootProps = {
projectId: string;
@@ -1,8 +1,8 @@
"use client";
import { FC } from "react";
import type { FC } from "react";
// plane imports
import { EProjectFeatureKey } from "@plane/constants";
import type { EProjectFeatureKey } from "@plane/constants";
// local components
import { ProjectBreadcrumb } from "./project";
import { ProjectFeatureBreadcrumb } from "./project-feature";
@@ -1,10 +1,10 @@
"use client";
import { FC } from "react";
import type { FC } from "react";
import { observer } from "mobx-react";
// plane imports
import { EProjectFeatureKey } from "@plane/constants";
import { ISvgIcons } from "@plane/propel/icons";
import type { ISvgIcons } from "@plane/propel/icons";
import { BreadcrumbNavigationDropdown, Breadcrumbs } from "@plane/ui";
// components
import { SwitcherLabel } from "@/components/common/switcher-label";
@@ -3,7 +3,7 @@
import { observer } from "mobx-react";
import { ProjectIcon } from "@plane/propel/icons";
// plane imports
import { ICustomSearchSelectOption } from "@plane/types";
import type { ICustomSearchSelectOption } from "@plane/types";
import { BreadcrumbNavigationSearchDropdown, Breadcrumbs } from "@plane/ui";
// components
import { Logo } from "@/components/common/logo";
@@ -11,7 +11,7 @@ import { SwitcherLabel } from "@/components/common/switcher-label";
// hooks
import { useProject } from "@/hooks/store/use-project";
import { useAppRouter } from "@/hooks/use-app-router";
import { TProject } from "@/plane-web/types";
import type { TProject } from "@/plane-web/types";
type TProjectBreadcrumbProps = {
workspaceSlug: string;
@@ -1,17 +1,15 @@
"use client";
// types
import { LayoutGrid } from "lucide-react";
// plane imports
import { CycleIcon, ModuleIcon, PageIcon, ProjectIcon, ViewsIcon } from "@plane/propel/icons";
import {
import type {
IWorkspaceDefaultSearchResult,
IWorkspaceIssueSearchResult,
IWorkspacePageSearchResult,
IWorkspaceProjectSearchResult,
IWorkspaceSearchResult,
} from "@plane/types";
// ui
// helpers
import { generateWorkItemLink } from "@plane/utils";
// plane web components
import { IssueIdentifier } from "@/plane-web/components/issues/issue-details/issue-identifier";
@@ -1,8 +1,9 @@
import { FC } from "react";
import type { FC } from "react";
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
// plane imports
import { EIssueServiceType, EIssuesStoreType, TIssue } from "@plane/types";
import type { TIssue } from "@plane/types";
import { EIssueServiceType, EIssuesStoreType } from "@plane/types";
// components
import { BulkDeleteIssuesModal } from "@/components/core/modals/bulk-delete-issues-modal";
import { DeleteIssueModal } from "@/components/issues/delete-issue-modal";
@@ -1,8 +1,10 @@
import { FC, ReactNode, useRef } from "react";
import type { FC, ReactNode } from "react";
import { useRef } from "react";
import { observer } from "mobx-react";
// plane imports
import { useTranslation } from "@plane/i18n";
import { EIssueCommentAccessSpecifier, TIssueComment } from "@plane/types";
import type { TIssueComment } from "@plane/types";
import { EIssueCommentAccessSpecifier } from "@plane/types";
import { Avatar, Tooltip } from "@plane/ui";
import { calculateTimeAgo, cn, getFileURL, renderFormattedDate, renderFormattedTime } from "@plane/utils";
// hooks
@@ -1,4 +1,4 @@
import { ReactNode } from "react";
import type { ReactNode } from "react";
import { observer } from "mobx-react";
import { AppSidebarToggleButton } from "@/components/sidebar/sidebar-toggle-button";
import { useAppTheme } from "@/hooks/store/use-app-theme";
@@ -1,4 +1,4 @@
import { IWorkspace } from "@plane/types";
import type { IWorkspace } from "@plane/types";
type TProps = {
workspace?: IWorkspace;
@@ -17,7 +17,7 @@ import { DetailedEmptyState } from "@/components/empty-state/detailed-empty-stat
// hooks
import { useCycle } from "@/hooks/store/use-cycle";
import { useResolvedAssetPath } from "@/hooks/use-resolved-asset-path";
import { ActiveCycleIssueDetails } from "@/store/issue/cycle";
import type { ActiveCycleIssueDetails } from "@/store/issue/cycle";
interface IActiveCycleDetails {
workspaceSlug: string;
@@ -1,4 +1,4 @@
import { FC } from "react";
import type { FC } from "react";
import { observer } from "mobx-react";
type Props = {
cycleId: string;
@@ -1,9 +1,10 @@
"use client";
import { FC, Fragment } from "react";
import type { FC } from "react";
import { Fragment } from "react";
import { observer } from "mobx-react";
// plane imports
import { useTranslation } from "@plane/i18n";
import { TCycleEstimateType } from "@plane/types";
import type { TCycleEstimateType } from "@plane/types";
import { Loader } from "@plane/ui";
import { getDate } from "@plane/utils";
// components
@@ -1,5 +1,6 @@
"use client";
import React, { FC } from "react";
import type { FC } from "react";
import React from "react";
// components
import { SidebarChart } from "./base";
@@ -1,5 +1,6 @@
"use client";
import React, { FC } from "react";
import type { FC } from "react";
import React from "react";
// local components
type TDeDupeButtonRoot = {
@@ -1,8 +1,8 @@
"use-client";
import { FC } from "react";
import type { FC } from "react";
// types
import { TDeDupeIssue } from "@plane/types";
import type { TDeDupeIssue } from "@plane/types";
type TDuplicateModalRootProps = {
workspaceSlug: string;
@@ -1,9 +1,10 @@
"use client";
import React, { FC } from "react";
import type { FC } from "react";
import React from "react";
import { observer } from "mobx-react";
// types
import { TDeDupeIssue } from "@plane/types";
import type { TDeDupeIssue } from "@plane/types";
import type { TIssueOperations } from "@/components/issues/issue-detail";
type TDeDupeIssuePopoverRootProps = {
@@ -1,6 +1,6 @@
"use client";
import { FC } from "react";
import type { FC } from "react";
type TDeDupeIssueButtonLabelProps = {
isOpen: boolean;
@@ -1,6 +1,7 @@
"use client";
import React, { FC } from "react";
import { TIssue } from "@plane/types";
import type { FC } from "react";
import React from "react";
import type { TIssue } from "@plane/types";
export interface EpicModalProps {
data?: Partial<TIssue>;
@@ -1,4 +1,4 @@
import { FC } from "react";
import type { FC } from "react";
import { observer } from "mobx-react";
import { Pen, Trash } from "lucide-react";
import { PROJECT_SETTINGS_TRACKER_ELEMENTS } from "@plane/constants";
+2 -1
View File
@@ -1,4 +1,5 @@
import { TEstimateSystemKeys, EEstimateSystem } from "@plane/types";
import type { TEstimateSystemKeys } from "@plane/types";
import { EEstimateSystem } from "@plane/types";
export const isEstimateSystemEnabled = (key: TEstimateSystemKeys) => {
switch (key) {
@@ -1,4 +1,4 @@
import { FC } from "react";
import type { FC } from "react";
export type TEstimateTimeInputProps = {
value?: number;
@@ -1,8 +1,8 @@
"use client";
import { FC } from "react";
import type { FC } from "react";
import { TEstimatePointsObject, TEstimateSystemKeys, TEstimateTypeErrorObject } from "@plane/types";
import type { TEstimatePointsObject, TEstimateSystemKeys, TEstimateTypeErrorObject } from "@plane/types";
export type TEstimatePointDelete = {
workspaceSlug: string;
@@ -1,6 +1,6 @@
"use client";
import { FC } from "react";
import type { FC } from "react";
import { observer } from "mobx-react";
type TUpdateEstimateModal = {
@@ -1,11 +1,11 @@
import { FC } from "react";
import type { FC } from "react";
// components
import type { IBlockUpdateData, IGanttBlock } from "@plane/types";
import RenderIfVisible from "@/components/core/render-if-visible-HOC";
// hooks
import { BlockRow } from "@/components/gantt-chart/blocks/block-row";
import { BLOCK_HEIGHT } from "@/components/gantt-chart/constants";
import { TSelectionHelper } from "@/hooks/use-multiple-select";
import type { TSelectionHelper } from "@/hooks/use-multiple-select";
// types
export type GanttChartBlocksProps = {
@@ -1,4 +1,4 @@
import { FC } from "react";
import type { FC } from "react";
//
import type { IBlockUpdateDependencyData } from "@plane/types";
import { GanttChartBlock } from "@/components/gantt-chart/blocks/block";
@@ -1,4 +1,4 @@
import { RefObject } from "react";
import type { RefObject } from "react";
import type { IGanttBlock } from "@plane/types";
type LeftDependencyDraggableProps = {
@@ -1,4 +1,4 @@
import { RefObject } from "react";
import type { RefObject } from "react";
import type { IGanttBlock } from "@plane/types";
type RightDependencyDraggableProps = {
@@ -1,4 +1,4 @@
import { FC } from "react";
import type { FC } from "react";
type Props = {
isEpic?: boolean;
+1 -1
View File
@@ -1,4 +1,4 @@
import { EInboxIssueSource } from "@plane/types";
import type { EInboxIssueSource } from "@plane/types";
export type TInboxSourcePill = {
source: EInboxIssueSource;
@@ -3,7 +3,7 @@ import { observer } from "mobx-react";
import { BulkOperationsUpgradeBanner } from "@/components/issues/bulk-operations/upgrade-banner";
// hooks
import { useMultipleSelectStore } from "@/hooks/store/use-multiple-select-store";
import { TSelectionHelper } from "@/hooks/use-multiple-select";
import type { TSelectionHelper } from "@/hooks/use-multiple-select";
type Props = {
className?: string;
@@ -1,6 +1,6 @@
"use client";
import React from "react";
import type React from "react";
import { observer } from "mobx-react";
type Props = {
@@ -1,6 +1,6 @@
"use client";
import React from "react";
import type React from "react";
import { observer } from "mobx-react";
type Props = {
@@ -1,6 +1,6 @@
import { FC } from "react";
import type { FC } from "react";
// plane types
import { TIssueServiceType, TWorkItemWidgets } from "@plane/types";
import type { TIssueServiceType, TWorkItemWidgets } from "@plane/types";
export type TWorkItemAdditionalWidgetActionButtonsProps = {
disabled: boolean;
@@ -1,6 +1,6 @@
import { FC } from "react";
import type { FC } from "react";
// plane types
import { TIssueServiceType, TWorkItemWidgets } from "@plane/types";
import type { TIssueServiceType, TWorkItemWidgets } from "@plane/types";
export type TWorkItemAdditionalWidgetCollapsiblesProps = {
disabled: boolean;
@@ -1,6 +1,6 @@
import { FC } from "react";
import type { FC } from "react";
// plane types
import { TIssueServiceType, TWorkItemWidgets } from "@plane/types";
import type { TIssueServiceType, TWorkItemWidgets } from "@plane/types";
export type TWorkItemAdditionalWidgetModalsProps = {
hideWidgets: TWorkItemWidgets[];

Some files were not shown because too many files have changed in this diff Show More