diff --git a/apiserver/plane/app/urls/__init__.py b/apiserver/plane/app/urls/__init__.py index 8798e80440e..3be75536b2f 100644 --- a/apiserver/plane/app/urls/__init__.py +++ b/apiserver/plane/app/urls/__init__.py @@ -17,6 +17,7 @@ from .views import urlpatterns as view_urls from .webhook import urlpatterns as webhook_urls from .workspace import urlpatterns as workspace_urls +from .timezone import urlpatterns as timezone_urls urlpatterns = [ *analytic_urls, @@ -38,4 +39,5 @@ *workspace_urls, *api_urls, *webhook_urls, + *timezone_urls, ] diff --git a/apiserver/plane/app/urls/timezone.py b/apiserver/plane/app/urls/timezone.py new file mode 100644 index 00000000000..ff14d029f2e --- /dev/null +++ b/apiserver/plane/app/urls/timezone.py @@ -0,0 +1,8 @@ +from django.urls import path + +from plane.app.views import TimezoneEndpoint + +urlpatterns = [ + # timezone endpoint + path("timezones/", TimezoneEndpoint.as_view(), name="timezone-list") +] diff --git a/apiserver/plane/app/views/__init__.py b/apiserver/plane/app/views/__init__.py index 6dcc09952a7..56ea78b4130 100644 --- a/apiserver/plane/app/views/__init__.py +++ b/apiserver/plane/app/views/__init__.py @@ -204,3 +204,5 @@ from .notification.base import MarkAllReadNotificationViewSet from .user.base import AccountEndpoint, ProfileEndpoint, UserSessionEndpoint + +from .timezone.base import TimezoneEndpoint diff --git a/apiserver/plane/app/views/asset/v2.py b/apiserver/plane/app/views/asset/v2.py index 827c9590840..3c1442022fc 100644 --- a/apiserver/plane/app/views/asset/v2.py +++ b/apiserver/plane/app/views/asset/v2.py @@ -126,7 +126,13 @@ def post(self, request): ) # Check if the file type is allowed - allowed_types = ["image/jpeg", "image/png", "image/webp", "image/jpg"] + allowed_types = [ + "image/jpeg", + "image/png", + "image/webp", + "image/jpg", + "image/gif", + ] if type not in allowed_types: return Response( { diff --git a/apiserver/plane/app/views/timezone/base.py b/apiserver/plane/app/views/timezone/base.py new file mode 100644 index 00000000000..77c87704736 --- /dev/null +++ b/apiserver/plane/app/views/timezone/base.py @@ -0,0 +1,247 @@ +# Python imports +import pytz +from datetime import datetime + +# Django imports +from django.utils.decorators import method_decorator +from django.views.decorators.cache import cache_page + +# Third party imports +from rest_framework import status +from rest_framework.response import Response +from rest_framework.permissions import AllowAny +from rest_framework.views import APIView + +# Module imports +from plane.authentication.rate_limit import AuthenticationThrottle + + +class TimezoneEndpoint(APIView): + permission_classes = [AllowAny] + + throttle_classes = [AuthenticationThrottle] + + @method_decorator(cache_page(60 * 60 * 24)) + def get(self, request): + timezone_mapping = { + "-1100": [ + ("Midway Island", "Pacific/Midway"), + ("American Samoa", "Pacific/Pago_Pago"), + ], + "-1000": [ + ("Hawaii", "Pacific/Honolulu"), + ("Aleutian Islands", "America/Adak"), + ], + "-0930": [("Marquesas Islands", "Pacific/Marquesas")], + "-0900": [ + ("Alaska", "America/Anchorage"), + ("Gambier Islands", "Pacific/Gambier"), + ], + "-0800": [ + ("Pacific Time (US and Canada)", "America/Los_Angeles"), + ("Baja California", "America/Tijuana"), + ], + "-0700": [ + ("Mountain Time (US and Canada)", "America/Denver"), + ("Arizona", "America/Phoenix"), + ("Chihuahua, Mazatlan", "America/Chihuahua"), + ], + "-0600": [ + ("Central Time (US and Canada)", "America/Chicago"), + ("Saskatchewan", "America/Regina"), + ("Guadalajara, Mexico City, Monterrey", "America/Mexico_City"), + ("Tegucigalpa, Honduras", "America/Tegucigalpa"), + ("Costa Rica", "America/Costa_Rica"), + ], + "-0500": [ + ("Eastern Time (US and Canada)", "America/New_York"), + ("Lima", "America/Lima"), + ("Bogota", "America/Bogota"), + ("Quito", "America/Guayaquil"), + ("Chetumal", "America/Cancun"), + ], + "-0430": [("Caracas (Old Venezuela Time)", "America/Caracas")], + "-0400": [ + ("Atlantic Time (Canada)", "America/Halifax"), + ("Caracas", "America/Caracas"), + ("Santiago", "America/Santiago"), + ("La Paz", "America/La_Paz"), + ("Manaus", "America/Manaus"), + ("Georgetown", "America/Guyana"), + ("Bermuda", "Atlantic/Bermuda"), + ], + "-0330": [("Newfoundland Time (Canada)", "America/St_Johns")], + "-0300": [ + ("Buenos Aires", "America/Argentina/Buenos_Aires"), + ("Brasilia", "America/Sao_Paulo"), + ("Greenland", "America/Godthab"), + ("Montevideo", "America/Montevideo"), + ("Falkland Islands", "Atlantic/Stanley"), + ], + "-0200": [ + ( + "South Georgia and the South Sandwich Islands", + "Atlantic/South_Georgia", + ) + ], + "-0100": [ + ("Azores", "Atlantic/Azores"), + ("Cape Verde Islands", "Atlantic/Cape_Verde"), + ], + "+0000": [ + ("Dublin", "Europe/Dublin"), + ("Reykjavik", "Atlantic/Reykjavik"), + ("Lisbon", "Europe/Lisbon"), + ("Monrovia", "Africa/Monrovia"), + ("Casablanca", "Africa/Casablanca"), + ], + "+0100": [ + ("Central European Time (Berlin, Rome, Paris)", "Europe/Paris"), + ("West Central Africa", "Africa/Lagos"), + ("Algiers", "Africa/Algiers"), + ("Lagos", "Africa/Lagos"), + ("Tunis", "Africa/Tunis"), + ], + "+0200": [ + ("Eastern European Time (Cairo, Helsinki, Kyiv)", "Europe/Kiev"), + ("Athens", "Europe/Athens"), + ("Jerusalem", "Asia/Jerusalem"), + ("Johannesburg", "Africa/Johannesburg"), + ("Harare, Pretoria", "Africa/Harare"), + ], + "+0300": [ + ("Moscow Time", "Europe/Moscow"), + ("Baghdad", "Asia/Baghdad"), + ("Nairobi", "Africa/Nairobi"), + ("Kuwait, Riyadh", "Asia/Riyadh"), + ], + "+0330": [("Tehran", "Asia/Tehran")], + "+0400": [ + ("Abu Dhabi", "Asia/Dubai"), + ("Baku", "Asia/Baku"), + ("Yerevan", "Asia/Yerevan"), + ("Astrakhan", "Europe/Astrakhan"), + ("Tbilisi", "Asia/Tbilisi"), + ("Mauritius", "Indian/Mauritius"), + ], + "+0500": [ + ("Islamabad", "Asia/Karachi"), + ("Karachi", "Asia/Karachi"), + ("Tashkent", "Asia/Tashkent"), + ("Yekaterinburg", "Asia/Yekaterinburg"), + ("Maldives", "Indian/Maldives"), + ("Chagos", "Indian/Chagos"), + ], + "+0530": [ + ("Chennai", "Asia/Kolkata"), + ("Kolkata", "Asia/Kolkata"), + ("Mumbai", "Asia/Kolkata"), + ("New Delhi", "Asia/Kolkata"), + ("Sri Jayawardenepura", "Asia/Colombo"), + ], + "+0545": [("Kathmandu", "Asia/Kathmandu")], + "+0600": [ + ("Dhaka", "Asia/Dhaka"), + ("Almaty", "Asia/Almaty"), + ("Bishkek", "Asia/Bishkek"), + ("Thimphu", "Asia/Thimphu"), + ], + "+0630": [ + ("Yangon (Rangoon)", "Asia/Yangon"), + ("Cocos Islands", "Indian/Cocos"), + ], + "+0700": [ + ("Bangkok", "Asia/Bangkok"), + ("Hanoi", "Asia/Ho_Chi_Minh"), + ("Jakarta", "Asia/Jakarta"), + ("Novosibirsk", "Asia/Novosibirsk"), + ("Krasnoyarsk", "Asia/Krasnoyarsk"), + ], + "+0800": [ + ("Beijing", "Asia/Shanghai"), + ("Singapore", "Asia/Singapore"), + ("Perth", "Australia/Perth"), + ("Hong Kong", "Asia/Hong_Kong"), + ("Ulaanbaatar", "Asia/Ulaanbaatar"), + ("Palau", "Pacific/Palau"), + ], + "+0845": [("Eucla", "Australia/Eucla")], + "+0900": [ + ("Tokyo", "Asia/Tokyo"), + ("Seoul", "Asia/Seoul"), + ("Yakutsk", "Asia/Yakutsk"), + ], + "+0930": [ + ("Adelaide", "Australia/Adelaide"), + ("Darwin", "Australia/Darwin"), + ], + "+1000": [ + ("Sydney", "Australia/Sydney"), + ("Brisbane", "Australia/Brisbane"), + ("Guam", "Pacific/Guam"), + ("Vladivostok", "Asia/Vladivostok"), + ("Tahiti", "Pacific/Tahiti"), + ], + "+1030": [("Lord Howe Island", "Australia/Lord_Howe")], + "+1100": [ + ("Solomon Islands", "Pacific/Guadalcanal"), + ("Magadan", "Asia/Magadan"), + ("Norfolk Island", "Pacific/Norfolk"), + ("Bougainville Island", "Pacific/Bougainville"), + ("Chokurdakh", "Asia/Srednekolymsk"), + ], + "+1200": [ + ("Auckland", "Pacific/Auckland"), + ("Wellington", "Pacific/Auckland"), + ("Fiji Islands", "Pacific/Fiji"), + ("Anadyr", "Asia/Anadyr"), + ], + "+1245": [("Chatham Islands", "Pacific/Chatham")], + "+1300": [("Nuku'alofa", "Pacific/Tongatapu"), ("Samoa", "Pacific/Apia")], + "+1400": [("Kiritimati Island", "Pacific/Kiritimati")], + } + + timezone_list = [] + now = datetime.now() + + # Process timezone mapping + for offset, locations in timezone_mapping.items(): + sign = "-" if offset.startswith("-") else "+" + hours = offset[1:3] + minutes = offset[3:] if len(offset) > 3 else "00" + + for friendly_name, tz_identifier in locations: + try: + tz = pytz.timezone(tz_identifier) + current_offset = now.astimezone(tz).strftime("%z") + + # converting and formatting UTC offset to GMT offset + current_utc_offset = now.astimezone(tz).utcoffset() + total_seconds = int(current_utc_offset.total_seconds()) + hours_offset = total_seconds // 3600 + minutes_offset = abs(total_seconds % 3600) // 60 + gmt_offset = ( + f"GMT{'+' if hours_offset >= 0 else '-'}" + f"{abs(hours_offset):02}:{minutes_offset:02}" + ) + + timezone_value = { + "offset": int(current_offset), + "utc_offset": f"UTC{sign}{hours}:{minutes}", + "gmt_offset": gmt_offset, + "value": tz_identifier, + "label": f"{friendly_name}", + } + + timezone_list.append(timezone_value) + except pytz.exceptions.UnknownTimeZoneError: + continue + + # Sort by offset and then by label + timezone_list.sort(key=lambda x: (x["offset"], x["label"])) + + # Remove offset from final output + for tz in timezone_list: + del tz["offset"] + + return Response({"timezones": timezone_list}, status=status.HTTP_200_OK) diff --git a/apiserver/plane/space/utils/grouper.py b/apiserver/plane/space/utils/grouper.py index 250b54e8915..2740588422e 100644 --- a/apiserver/plane/space/utils/grouper.py +++ b/apiserver/plane/space/utils/grouper.py @@ -91,6 +91,7 @@ def issue_on_results(issues, group_by, sub_group_by): Case( When( votes__isnull=False, + votes__deleted_at__isnull=True, then=JSONObject( vote=F("votes__vote"), actor_details=JSONObject( @@ -117,13 +118,14 @@ def issue_on_results(issues, group_by, sub_group_by): default=None, output_field=JSONField(), ), - filter=Q(votes__isnull=False), + filter=Q(votes__isnull=False,votes__deleted_at__isnull=True), distinct=True, ), reaction_items=ArrayAgg( Case( When( issue_reactions__isnull=False, + issue_reactions__deleted_at__isnull=True, then=JSONObject( reaction=F("issue_reactions__reaction"), actor_details=JSONObject( @@ -150,7 +152,7 @@ def issue_on_results(issues, group_by, sub_group_by): default=None, output_field=JSONField(), ), - filter=Q(issue_reactions__isnull=False), + filter=Q(issue_reactions__isnull=False, issue_reactions__deleted_at__isnull=True), distinct=True, ), ).values(*required_fields, "vote_items", "reaction_items") diff --git a/apiserver/plane/space/views/asset.py b/apiserver/plane/space/views/asset.py index 2c672203843..3e1d4d6f782 100644 --- a/apiserver/plane/space/views/asset.py +++ b/apiserver/plane/space/views/asset.py @@ -86,7 +86,13 @@ def post(self, request, anchor): ) # Check if the file type is allowed - allowed_types = ["image/jpeg", "image/png", "image/webp"] + allowed_types = [ + "image/jpeg", + "image/png", + "image/webp", + "image/jpg", + "image/gif", + ] if type not in allowed_types: return Response( { diff --git a/apiserver/plane/space/views/issue.py b/apiserver/plane/space/views/issue.py index a1ab332f91b..699253ae524 100644 --- a/apiserver/plane/space/views/issue.py +++ b/apiserver/plane/space/views/issue.py @@ -701,6 +701,7 @@ def get(self, request, anchor, issue_id): Case( When( votes__isnull=False, + votes__deleted_at__isnull=True, then=JSONObject( vote=F("votes__vote"), actor_details=JSONObject( @@ -732,7 +733,11 @@ def get(self, request, anchor, issue_id): output_field=JSONField(), ), filter=Case( - When(votes__isnull=False, then=True), + When( + votes__isnull=False, + votes__deleted_at__isnull=True, + then=True, + ), default=False, output_field=JSONField(), ), @@ -742,6 +747,7 @@ def get(self, request, anchor, issue_id): Case( When( issue_reactions__isnull=False, + issue_reactions__deleted_at__isnull=True, then=JSONObject( reaction=F("issue_reactions__reaction"), actor_details=JSONObject( @@ -775,7 +781,11 @@ def get(self, request, anchor, issue_id): output_field=JSONField(), ), filter=Case( - When(issue_reactions__isnull=False, then=True), + When( + issue_reactions__isnull=False, + issue_reactions__deleted_at__isnull=True, + then=True, + ), default=False, output_field=JSONField(), ), diff --git a/packages/constants/src/issue.ts b/packages/constants/src/issue.ts index 9aa65d13e38..ea3cd65d464 100644 --- a/packages/constants/src/issue.ts +++ b/packages/constants/src/issue.ts @@ -44,3 +44,46 @@ export enum EIssueServiceType { ISSUES = "issues", EPICS = "epics", } + +export enum EIssueLayoutTypes { + LIST = "list", + KANBAN = "kanban", + CALENDAR = "calendar", + GANTT = "gantt_chart", + SPREADSHEET = "spreadsheet", +} + +export enum EIssuesStoreType { + GLOBAL = "GLOBAL", + PROFILE = "PROFILE", + TEAM = "TEAM", + PROJECT = "PROJECT", + CYCLE = "CYCLE", + MODULE = "MODULE", + TEAM_VIEW = "TEAM_VIEW", + PROJECT_VIEW = "PROJECT_VIEW", + ARCHIVED = "ARCHIVED", + DRAFT = "DRAFT", + DEFAULT = "DEFAULT", + WORKSPACE_DRAFT = "WORKSPACE_DRAFT", + EPIC = "EPIC", +} + +export enum EIssueFilterType { + FILTERS = "filters", + DISPLAY_FILTERS = "display_filters", + DISPLAY_PROPERTIES = "display_properties", + KANBAN_FILTERS = "kanban_filters", +} + +export enum EIssueCommentAccessSpecifier { + EXTERNAL = "EXTERNAL", + INTERNAL = "INTERNAL", +} + +export enum EIssueListRow { + HEADER = "HEADER", + ISSUE = "ISSUE", + NO_ISSUES = "NO_ISSUES", + QUICK_ADD = "QUICK_ADD", +} diff --git a/packages/editor/package.json b/packages/editor/package.json index a05ec26d0cc..e9ef145a0c4 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -58,7 +58,6 @@ "@tiptap/starter-kit": "^2.1.13", "@tiptap/suggestion": "^2.0.13", "class-variance-authority": "^0.7.0", - "clsx": "^1.2.1", "highlight.js": "^11.8.0", "jsx-dom-cjs": "^8.0.3", "linkifyjs": "^4.1.3", @@ -67,7 +66,6 @@ "prosemirror-codemark": "^0.4.2", "prosemirror-utils": "^1.2.2", "react-moveable": "^0.54.2", - "tailwind-merge": "^1.14.0", "tippy.js": "^6.3.7", "tiptap-markdown": "^0.8.9", "uuid": "^10.0.0", diff --git a/packages/editor/src/core/components/editors/document/collaborative-editor.tsx b/packages/editor/src/core/components/editors/document/collaborative-editor.tsx index cd7d6f35489..44c18c2f680 100644 --- a/packages/editor/src/core/components/editors/document/collaborative-editor.tsx +++ b/packages/editor/src/core/components/editors/document/collaborative-editor.tsx @@ -19,6 +19,7 @@ const CollaborativeDocumentEditor = (props: ICollaborativeDocumentEditor) => { containerClassName, disabledExtensions, displayConfig = DEFAULT_DISPLAY_CONFIG, + editable, editorClassName = "", embedHandler, fileHandler, @@ -44,8 +45,8 @@ const CollaborativeDocumentEditor = (props: ICollaborativeDocumentEditor) => { // use document editor const { editor, hasServerConnectionFailed, hasServerSynced } = useCollaborativeEditor({ - onTransaction, disabledExtensions, + editable, editorClassName, embedHandler, extensions, @@ -54,6 +55,7 @@ const CollaborativeDocumentEditor = (props: ICollaborativeDocumentEditor) => { handleEditorReady, id, mentionHandler, + onTransaction, placeholder, realtimeConfig, serverHandler, diff --git a/packages/editor/src/core/components/editors/document/collaborative-read-only-editor.tsx b/packages/editor/src/core/components/editors/document/collaborative-read-only-editor.tsx deleted file mode 100644 index 89acace7b70..00000000000 --- a/packages/editor/src/core/components/editors/document/collaborative-read-only-editor.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import { forwardRef, MutableRefObject } from "react"; -// components -import { DocumentContentLoader, PageRenderer } from "@/components/editors"; -// constants -import { DEFAULT_DISPLAY_CONFIG } from "@/constants/config"; -// extensions -import { IssueWidget } from "@/extensions"; -// helpers -import { getEditorClassNames } from "@/helpers/common"; -// hooks -import { useReadOnlyCollaborativeEditor } from "@/hooks/use-read-only-collaborative-editor"; -// types -import { EditorReadOnlyRefApi, ICollaborativeDocumentReadOnlyEditor } from "@/types"; - -const CollaborativeDocumentReadOnlyEditor = (props: ICollaborativeDocumentReadOnlyEditor) => { - const { - containerClassName, - disabledExtensions, - displayConfig = DEFAULT_DISPLAY_CONFIG, - editorClassName = "", - embedHandler, - fileHandler, - forwardedRef, - handleEditorReady, - id, - mentionHandler, - realtimeConfig, - serverHandler, - user, - } = props; - const extensions = []; - if (embedHandler?.issue) { - extensions.push( - IssueWidget({ - widgetCallback: embedHandler.issue.widgetCallback, - }) - ); - } - - const { editor, hasServerConnectionFailed, hasServerSynced } = useReadOnlyCollaborativeEditor({ - disabledExtensions, - editorClassName, - extensions, - fileHandler, - forwardedRef, - handleEditorReady, - id, - mentionHandler, - realtimeConfig, - serverHandler, - user, - }); - - const editorContainerClassName = getEditorClassNames({ - containerClassName, - }); - - if (!editor) return null; - - if (!hasServerSynced && !hasServerConnectionFailed) return ; - - return ( - - ); -}; - -const CollaborativeDocumentReadOnlyEditorWithRef = forwardRef< - EditorReadOnlyRefApi, - ICollaborativeDocumentReadOnlyEditor ->((props, ref) => ( - } /> -)); - -CollaborativeDocumentReadOnlyEditorWithRef.displayName = "CollaborativeDocumentReadOnlyEditorWithRef"; - -export { CollaborativeDocumentReadOnlyEditorWithRef }; diff --git a/packages/editor/src/core/components/editors/document/index.ts b/packages/editor/src/core/components/editors/document/index.ts index 514b620e3a2..571cb7e9a1f 100644 --- a/packages/editor/src/core/components/editors/document/index.ts +++ b/packages/editor/src/core/components/editors/document/index.ts @@ -1,5 +1,4 @@ export * from "./collaborative-editor"; -export * from "./collaborative-read-only-editor"; export * from "./loader"; export * from "./page-renderer"; export * from "./read-only-editor"; diff --git a/packages/editor/src/core/components/editors/document/page-renderer.tsx b/packages/editor/src/core/components/editors/document/page-renderer.tsx index d1ff3b3d014..f291c8b3a3f 100644 --- a/packages/editor/src/core/components/editors/document/page-renderer.tsx +++ b/packages/editor/src/core/components/editors/document/page-renderer.tsx @@ -140,10 +140,10 @@ export const PageRenderer = (props: IPageRenderer) => { > {editor.isEditable && ( - <> +
- +
)} diff --git a/packages/editor/src/core/components/editors/editor-container.tsx b/packages/editor/src/core/components/editors/editor-container.tsx index e070d7e45e5..d6563f7b085 100644 --- a/packages/editor/src/core/components/editors/editor-container.tsx +++ b/packages/editor/src/core/components/editors/editor-container.tsx @@ -1,9 +1,9 @@ import { FC, ReactNode } from "react"; import { Editor } from "@tiptap/react"; +// plane utils +import { cn } from "@plane/utils"; // constants import { DEFAULT_DISPLAY_CONFIG } from "@/constants/config"; -// helpers -import { cn } from "@/helpers/common"; // types import { TDisplayConfig } from "@/types"; diff --git a/packages/editor/src/core/components/editors/editor-wrapper.tsx b/packages/editor/src/core/components/editors/editor-wrapper.tsx index 59c65e5c63c..9d1297e239e 100644 --- a/packages/editor/src/core/components/editors/editor-wrapper.tsx +++ b/packages/editor/src/core/components/editors/editor-wrapper.tsx @@ -38,6 +38,7 @@ export const EditorWrapper: React.FC = (props) => { } = props; const editor = useEditor({ + editable: true, disabledExtensions, editorClassName, enableHistory: true, diff --git a/packages/editor/src/core/components/menus/ai-menu.tsx b/packages/editor/src/core/components/menus/ai-menu.tsx index 43793fae35d..42b45509f72 100644 --- a/packages/editor/src/core/components/menus/ai-menu.tsx +++ b/packages/editor/src/core/components/menus/ai-menu.tsx @@ -1,7 +1,7 @@ import { useCallback, useEffect, useRef, useState } from "react"; import tippy, { Instance } from "tippy.js"; -// helpers -import { cn } from "@/helpers/common"; +// plane utils +import { cn } from "@plane/utils"; // types import { TAIHandler } from "@/types"; diff --git a/packages/editor/src/core/components/menus/bubble-menu/alignment-selector.tsx b/packages/editor/src/core/components/menus/bubble-menu/alignment-selector.tsx index e3ccc6cf62b..24dfeceafdf 100644 --- a/packages/editor/src/core/components/menus/bubble-menu/alignment-selector.tsx +++ b/packages/editor/src/core/components/menus/bubble-menu/alignment-selector.tsx @@ -1,9 +1,9 @@ import { Editor } from "@tiptap/core"; import { AlignCenter, AlignLeft, AlignRight, LucideIcon } from "lucide-react"; +// plane utils +import { cn } from "@plane/utils"; // components import { TextAlignItem } from "@/components/menus"; -// helpers -import { cn } from "@/helpers/common"; // types import { TEditorCommands } from "@/types"; diff --git a/packages/editor/src/core/components/menus/bubble-menu/color-selector.tsx b/packages/editor/src/core/components/menus/bubble-menu/color-selector.tsx index bc7f5a56f12..ba9278b675f 100644 --- a/packages/editor/src/core/components/menus/bubble-menu/color-selector.tsx +++ b/packages/editor/src/core/components/menus/bubble-menu/color-selector.tsx @@ -1,10 +1,11 @@ import { Dispatch, FC, SetStateAction } from "react"; import { Editor } from "@tiptap/react"; import { ALargeSmall, Ban } from "lucide-react"; +// plane utils +import { cn } from "@plane/utils"; // constants import { COLORS_LIST } from "@/constants/common"; // helpers -import { cn } from "@/helpers/common"; import { BackgroundColorItem, TextColorItem } from "../menu-items"; type Props = { diff --git a/packages/editor/src/core/components/menus/bubble-menu/link-selector.tsx b/packages/editor/src/core/components/menus/bubble-menu/link-selector.tsx index eaa20ed26bb..fe651fa4e15 100644 --- a/packages/editor/src/core/components/menus/bubble-menu/link-selector.tsx +++ b/packages/editor/src/core/components/menus/bubble-menu/link-selector.tsx @@ -1,8 +1,10 @@ import { Dispatch, FC, SetStateAction, useCallback, useEffect, useRef } from "react"; import { Editor } from "@tiptap/core"; import { Check, Link, Trash } from "lucide-react"; +// plane utils +import { cn } from "@plane/utils"; // helpers -import { cn, isValidHttpUrl } from "@/helpers/common"; +import { isValidHttpUrl } from "@/helpers/common"; import { setLinkEditor, unsetLinkEditor } from "@/helpers/editor-commands"; type Props = { diff --git a/packages/editor/src/core/components/menus/bubble-menu/node-selector.tsx b/packages/editor/src/core/components/menus/bubble-menu/node-selector.tsx index a121c48ef12..7d1378800c9 100644 --- a/packages/editor/src/core/components/menus/bubble-menu/node-selector.tsx +++ b/packages/editor/src/core/components/menus/bubble-menu/node-selector.tsx @@ -1,6 +1,8 @@ import { Dispatch, FC, SetStateAction } from "react"; import { Editor } from "@tiptap/react"; import { Check, ChevronDown } from "lucide-react"; +// plane utils +import { cn } from "@plane/utils"; // components import { BulletListItem, @@ -17,8 +19,6 @@ import { HeadingSixItem, EditorMenuItem, } from "@/components/menus"; -// helpers -import { cn } from "@/helpers/common"; // types import { TEditorCommands } from "@/types"; diff --git a/packages/editor/src/core/components/menus/bubble-menu/root.tsx b/packages/editor/src/core/components/menus/bubble-menu/root.tsx index 18079f089e1..4ed3709f408 100644 --- a/packages/editor/src/core/components/menus/bubble-menu/root.tsx +++ b/packages/editor/src/core/components/menus/bubble-menu/root.tsx @@ -1,5 +1,7 @@ import { FC, useEffect, useState } from "react"; import { BubbleMenu, BubbleMenuProps, Editor, isNodeSelection } from "@tiptap/react"; +// plane utils +import { cn } from "@plane/utils"; // components import { BoldItem, @@ -13,8 +15,6 @@ import { } from "@/components/menus"; // extensions import { isCellSelection } from "@/extensions/table/table/utilities/is-cell-selection"; -// helpers -import { cn } from "@/helpers/common"; // local components import { TextAlignmentSelector } from "./alignment-selector"; diff --git a/packages/editor/src/core/constants/config.ts b/packages/editor/src/core/constants/config.ts index 5a9577044c0..bd4712de99a 100644 --- a/packages/editor/src/core/constants/config.ts +++ b/packages/editor/src/core/constants/config.ts @@ -5,3 +5,6 @@ export const DEFAULT_DISPLAY_CONFIG: TDisplayConfig = { fontSize: "large-font", fontStyle: "sans-serif", }; + +export const ACCEPTED_FILE_MIME_TYPES = ["image/jpeg", "image/jpg", "image/png", "image/webp", "image/gif"]; +export const ACCEPTED_FILE_EXTENSIONS = ACCEPTED_FILE_MIME_TYPES.map((type) => `.${type.split("/")[1]}`); diff --git a/packages/editor/src/core/extensions/callout/color-selector.tsx b/packages/editor/src/core/extensions/callout/color-selector.tsx index 489b051666e..ddc3b879cf5 100644 --- a/packages/editor/src/core/extensions/callout/color-selector.tsx +++ b/packages/editor/src/core/extensions/callout/color-selector.tsx @@ -1,8 +1,8 @@ import { Ban, ChevronDown } from "lucide-react"; +// plane utils +import { cn } from "@plane/utils"; // constants import { COLORS_LIST } from "@/constants/common"; -// helpers -import { cn } from "@/helpers/common"; type Props = { disabled: boolean; diff --git a/packages/editor/src/core/extensions/callout/logo-selector.tsx b/packages/editor/src/core/extensions/callout/logo-selector.tsx index 4c78a2c0470..8ea47d50d0a 100644 --- a/packages/editor/src/core/extensions/callout/logo-selector.tsx +++ b/packages/editor/src/core/extensions/callout/logo-selector.tsx @@ -2,8 +2,8 @@ import { convertHexEmojiToDecimal } from "@plane/utils"; // plane ui import { EmojiIconPicker, EmojiIconPickerTypes, Logo, TEmojiLogoProps } from "@plane/ui"; -// helpers -import { cn } from "@/helpers/common"; +// plane utils +import { cn } from "@plane/utils"; // types import { TCalloutBlockAttributes } from "./types"; // utils diff --git a/packages/editor/src/core/extensions/code/code-block-node-view.tsx b/packages/editor/src/core/extensions/code/code-block-node-view.tsx index 8dbdb044f11..a06d839908a 100644 --- a/packages/editor/src/core/extensions/code/code-block-node-view.tsx +++ b/packages/editor/src/core/extensions/code/code-block-node-view.tsx @@ -8,8 +8,8 @@ import { common, createLowlight } from "lowlight"; import { CopyIcon, CheckIcon } from "lucide-react"; // ui import { Tooltip } from "@plane/ui"; -// helpers -import { cn } from "@/helpers/common"; +// plane utils +import { cn } from "@plane/utils"; // we just have ts support for now const lowlight = createLowlight(common); diff --git a/packages/editor/src/core/extensions/custom-image/components/image-block.tsx b/packages/editor/src/core/extensions/custom-image/components/image-block.tsx index b5b27e27185..89194aae0c3 100644 --- a/packages/editor/src/core/extensions/custom-image/components/image-block.tsx +++ b/packages/editor/src/core/extensions/custom-image/components/image-block.tsx @@ -1,9 +1,9 @@ import React, { useRef, useState, useCallback, useLayoutEffect, useEffect } from "react"; import { NodeSelection } from "@tiptap/pm/state"; +// plane utils +import { cn } from "@plane/utils"; // extensions import { CustoBaseImageNodeViewProps, ImageToolbarRoot } from "@/extensions/custom-image"; -// helpers -import { cn } from "@/helpers/common"; const MIN_SIZE = 100; diff --git a/packages/editor/src/core/extensions/custom-image/components/image-uploader.tsx b/packages/editor/src/core/extensions/custom-image/components/image-uploader.tsx index 8ad99bc4439..eaea423878d 100644 --- a/packages/editor/src/core/extensions/custom-image/components/image-uploader.tsx +++ b/packages/editor/src/core/extensions/custom-image/components/image-uploader.tsx @@ -1,7 +1,9 @@ import { ChangeEvent, useCallback, useEffect, useMemo, useRef } from "react"; import { ImageIcon } from "lucide-react"; -// helpers -import { cn } from "@/helpers/common"; +// plane utils +import { cn } from "@plane/utils"; +// constants +import { ACCEPTED_FILE_EXTENSIONS } from "@/constants/config"; // hooks import { useUploader, useDropZone, uploadFirstImageAndInsertRemaining } from "@/hooks/use-file-upload"; // extensions @@ -127,7 +129,7 @@ export const CustomImageUploader = (props: CustomImageUploaderProps) => { return "Uploading..."; } - if (draggedInside) { + if (draggedInside && editor.isEditable) { return "Drop image here"; } @@ -137,14 +139,16 @@ export const CustomImageUploader = (props: CustomImageUploaderProps) => { return (
{ ref={fileInputRef} hidden type="file" - accept=".jpg,.jpeg,.png,.webp" + accept={ACCEPTED_FILE_EXTENSIONS.join(",")} onChange={onFileChange} multiple /> diff --git a/packages/editor/src/core/extensions/custom-image/components/toolbar/full-screen.tsx b/packages/editor/src/core/extensions/custom-image/components/toolbar/full-screen.tsx index 38ea23c9925..92b5904fbf7 100644 --- a/packages/editor/src/core/extensions/custom-image/components/toolbar/full-screen.tsx +++ b/packages/editor/src/core/extensions/custom-image/components/toolbar/full-screen.tsx @@ -1,7 +1,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { ExternalLink, Maximize, Minus, Plus, X } from "lucide-react"; -// helpers -import { cn } from "@/helpers/common"; +// plane utils +import { cn } from "@plane/utils"; type Props = { image: { diff --git a/packages/editor/src/core/extensions/custom-image/components/toolbar/root.tsx b/packages/editor/src/core/extensions/custom-image/components/toolbar/root.tsx index d42d875cc93..3179db0d4cd 100644 --- a/packages/editor/src/core/extensions/custom-image/components/toolbar/root.tsx +++ b/packages/editor/src/core/extensions/custom-image/components/toolbar/root.tsx @@ -1,6 +1,6 @@ import { useState } from "react"; -// helpers -import { cn } from "@/helpers/common"; +// plane utils +import { cn } from "@plane/utils"; // components import { ImageFullScreenAction } from "./full-screen"; diff --git a/packages/editor/src/core/extensions/drop.tsx b/packages/editor/src/core/extensions/drop.tsx index 2044f03bf5d..0d578770aeb 100644 --- a/packages/editor/src/core/extensions/drop.tsx +++ b/packages/editor/src/core/extensions/drop.tsx @@ -2,58 +2,67 @@ import { Extension, Editor } from "@tiptap/core"; import { Plugin, PluginKey } from "@tiptap/pm/state"; import { EditorView } from "@tiptap/pm/view"; -export const DropHandlerExtension = () => - Extension.create({ - name: "dropHandler", - priority: 1000, +export const DropHandlerExtension = Extension.create({ + name: "dropHandler", + priority: 1000, - addProseMirrorPlugins() { - const editor = this.editor; - return [ - new Plugin({ - key: new PluginKey("drop-handler-plugin"), - props: { - handlePaste: (view: EditorView, event: ClipboardEvent) => { - if (event.clipboardData && event.clipboardData.files && event.clipboardData.files.length > 0) { - event.preventDefault(); - const files = Array.from(event.clipboardData.files); - const imageFiles = files.filter((file) => file.type.startsWith("image")); + addProseMirrorPlugins() { + const editor = this.editor; + return [ + new Plugin({ + key: new PluginKey("drop-handler-plugin"), + props: { + handlePaste: (view: EditorView, event: ClipboardEvent) => { + if ( + editor.isEditable && + event.clipboardData && + event.clipboardData.files && + event.clipboardData.files.length > 0 + ) { + event.preventDefault(); + const files = Array.from(event.clipboardData.files); + const imageFiles = files.filter((file) => file.type.startsWith("image")); - if (imageFiles.length > 0) { - const pos = view.state.selection.from; - insertImagesSafely({ editor, files: imageFiles, initialPos: pos, event: "drop" }); - } - return true; + if (imageFiles.length > 0) { + const pos = view.state.selection.from; + insertImagesSafely({ editor, files: imageFiles, initialPos: pos, event: "drop" }); } - return false; - }, - handleDrop: (view: EditorView, event: DragEvent, _slice: any, moved: boolean) => { - if (!moved && event.dataTransfer && event.dataTransfer.files && event.dataTransfer.files.length > 0) { - event.preventDefault(); - const files = Array.from(event.dataTransfer.files); - const imageFiles = files.filter((file) => file.type.startsWith("image")); + return true; + } + return false; + }, + handleDrop: (view: EditorView, event: DragEvent, _slice: any, moved: boolean) => { + if ( + editor.isEditable && + !moved && + event.dataTransfer && + event.dataTransfer.files && + event.dataTransfer.files.length > 0 + ) { + event.preventDefault(); + const files = Array.from(event.dataTransfer.files); + const imageFiles = files.filter((file) => file.type.startsWith("image")); - if (imageFiles.length > 0) { - const coordinates = view.posAtCoords({ - left: event.clientX, - top: event.clientY, - }); + if (imageFiles.length > 0) { + const coordinates = view.posAtCoords({ + left: event.clientX, + top: event.clientY, + }); - if (coordinates) { - const pos = coordinates.pos; - insertImagesSafely({ editor, files: imageFiles, initialPos: pos, event: "drop" }); - } - return true; + if (coordinates) { + const pos = coordinates.pos; + insertImagesSafely({ editor, files: imageFiles, initialPos: pos, event: "drop" }); } + return true; } - return false; - }, + } + return false; }, - }), - ]; - }, - }); - + }, + }), + ]; + }, +}); export const insertImagesSafely = async ({ editor, files, diff --git a/packages/editor/src/core/extensions/extensions.tsx b/packages/editor/src/core/extensions/extensions.tsx index 87262048205..748bd104079 100644 --- a/packages/editor/src/core/extensions/extensions.tsx +++ b/packages/editor/src/core/extensions/extensions.tsx @@ -44,6 +44,7 @@ type TArguments = { mentionHandler: TMentionHandler; placeholder?: string | ((isFocused: boolean, value: string) => string); tabIndex?: number; + editable: boolean; }; export const CoreEditorExtensions = (args: TArguments): Extensions => { @@ -86,7 +87,7 @@ export const CoreEditorExtensions = (args: TArguments): Extensions => { ...(enableHistory ? {} : { history: false }), }), CustomQuoteExtension, - DropHandlerExtension(), + DropHandlerExtension, CustomHorizontalRule.configure({ HTMLAttributes: { class: "py-4 border-custom-border-400", @@ -134,6 +135,7 @@ export const CoreEditorExtensions = (args: TArguments): Extensions => { CustomCodeInlineExtension, Markdown.configure({ html: true, + transformCopiedText: true, transformPastedText: true, breaks: true, }), @@ -144,6 +146,8 @@ export const CoreEditorExtensions = (args: TArguments): Extensions => { CustomMentionExtension(mentionHandler), Placeholder.configure({ placeholder: ({ editor, node }) => { + if (!editor.isEditable) return; + if (node.type.name === "heading") return `Heading ${node.attrs.level}`; if (editor.storage.imageComponent.uploadInProgress) return ""; diff --git a/packages/editor/src/core/extensions/read-only-extensions.tsx b/packages/editor/src/core/extensions/read-only-extensions.tsx index 5db19c813c8..38c7f996632 100644 --- a/packages/editor/src/core/extensions/read-only-extensions.tsx +++ b/packages/editor/src/core/extensions/read-only-extensions.tsx @@ -20,7 +20,6 @@ import { TableRow, Table, CustomMentionExtension, - HeadingListExtension, CustomReadOnlyImageExtension, CustomTextAlignExtension, CustomCalloutReadOnlyExtension, @@ -134,7 +133,6 @@ export const CoreReadOnlyEditorExtensions = (props: Props): Extensions => { CustomMentionExtension(mentionHandler), CharacterCount, CustomColorExtension, - HeadingListExtension, CustomTextAlignExtension, CustomCalloutReadOnlyExtension, ...CoreReadOnlyEditorAdditionalExtensions({ diff --git a/packages/editor/src/core/extensions/slash-commands/command-menu-item.tsx b/packages/editor/src/core/extensions/slash-commands/command-menu-item.tsx index 3a03c3b6a70..bd8ce2aecdb 100644 --- a/packages/editor/src/core/extensions/slash-commands/command-menu-item.tsx +++ b/packages/editor/src/core/extensions/slash-commands/command-menu-item.tsx @@ -1,5 +1,5 @@ -// helpers -import { cn } from "@/helpers/common"; +// plane utils +import { cn } from "@plane/utils"; // types import { ISlashCommandItem } from "@/types"; diff --git a/packages/editor/src/core/helpers/common.ts b/packages/editor/src/core/helpers/common.ts index 0fb32310d6a..8638d2c151d 100644 --- a/packages/editor/src/core/helpers/common.ts +++ b/packages/editor/src/core/helpers/common.ts @@ -1,6 +1,6 @@ import { EditorState, Selection } from "@tiptap/pm/state"; -import { clsx, type ClassValue } from "clsx"; -import { twMerge } from "tailwind-merge"; +// plane utils +import { cn } from "@plane/utils"; interface EditorClassNames { noBorder?: boolean; @@ -18,10 +18,6 @@ export const getEditorClassNames = ({ noBorder, borderOnFocus, containerClassNam containerClassName ); -export function cn(...inputs: ClassValue[]) { - return twMerge(clsx(inputs)); -} - // Helper function to find the parent node of a specific type export function findParentNodeOfType(selection: Selection, typeName: string) { let depth = selection.$anchor.depth; diff --git a/packages/editor/src/core/hooks/use-collaborative-editor.ts b/packages/editor/src/core/hooks/use-collaborative-editor.ts index b3c7d6cfc2e..4abf7d6d1ff 100644 --- a/packages/editor/src/core/hooks/use-collaborative-editor.ts +++ b/packages/editor/src/core/hooks/use-collaborative-editor.ts @@ -15,6 +15,7 @@ export const useCollaborativeEditor = (props: TCollaborativeEditorProps) => { const { onTransaction, disabledExtensions, + editable, editorClassName, editorProps = {}, embedHandler, @@ -75,7 +76,7 @@ export const useCollaborativeEditor = (props: TCollaborativeEditorProps) => { const editor = useEditor({ disabledExtensions, id, - onTransaction, + editable, editorProps, editorClassName, enableHistory: false, @@ -97,9 +98,10 @@ export const useCollaborativeEditor = (props: TCollaborativeEditorProps) => { }), ], fileHandler, - handleEditorReady, forwardedRef, + handleEditorReady, mentionHandler, + onTransaction, placeholder, provider, tabIndex, diff --git a/packages/editor/src/core/hooks/use-editor.ts b/packages/editor/src/core/hooks/use-editor.ts index 6ed1d40b5b5..563d5902d22 100644 --- a/packages/editor/src/core/hooks/use-editor.ts +++ b/packages/editor/src/core/hooks/use-editor.ts @@ -26,6 +26,7 @@ import type { } from "@/types"; export interface CustomEditorProps { + editable: boolean; editorClassName: string; editorProps?: EditorProps; enableHistory: boolean; @@ -51,6 +52,7 @@ export interface CustomEditorProps { export const useEditor = (props: CustomEditorProps) => { const { disabledExtensions, + editable = true, editorClassName, editorProps = {}, enableHistory, @@ -70,39 +72,43 @@ export const useEditor = (props: CustomEditorProps) => { autofocus = false, } = props; // states - const [savedSelection, setSavedSelection] = useState(null); // refs const editorRef: MutableRefObject = useRef(null); const savedSelectionRef = useRef(savedSelection); - const editor = useTiptapEditor({ - autofocus, - editorProps: { - ...CoreEditorProps({ - editorClassName, - }), - ...editorProps, - }, - extensions: [ - ...CoreEditorExtensions({ - disabledExtensions, - enableHistory, - fileHandler, - mentionHandler, - placeholder, - tabIndex, - }), - ...extensions, - ], - content: typeof initialValue === "string" && initialValue.trim() !== "" ? initialValue : "

", - onCreate: () => handleEditorReady?.(true), - onTransaction: ({ editor }) => { - setSavedSelection(editor.state.selection); - onTransaction?.(); + const editor = useTiptapEditor( + { + editable, + autofocus, + editorProps: { + ...CoreEditorProps({ + editorClassName, + }), + ...editorProps, + }, + extensions: [ + ...CoreEditorExtensions({ + editable, + disabledExtensions, + enableHistory, + fileHandler, + mentionHandler, + placeholder, + tabIndex, + }), + ...extensions, + ], + content: typeof initialValue === "string" && initialValue.trim() !== "" ? initialValue : "

", + onCreate: () => handleEditorReady?.(true), + onTransaction: ({ editor }) => { + setSavedSelection(editor.state.selection); + onTransaction?.(); + }, + onUpdate: ({ editor }) => onChange?.(editor.getJSON(), editor.getHTML()), + onDestroy: () => handleEditorReady?.(false), }, - onUpdate: ({ editor }) => onChange?.(editor.getJSON(), editor.getHTML()), - onDestroy: () => handleEditorReady?.(false), - }); + [editable] + ); // Update the ref whenever savedSelection changes useEffect(() => { diff --git a/packages/editor/src/core/hooks/use-file-upload.ts b/packages/editor/src/core/hooks/use-file-upload.ts index f5f930f2900..65daa2f8e49 100644 --- a/packages/editor/src/core/hooks/use-file-upload.ts +++ b/packages/editor/src/core/hooks/use-file-upload.ts @@ -105,7 +105,7 @@ export const useDropZone = (args: TDropzoneArgs) => { async (e: DragEvent) => { e.preventDefault(); setDraggedInside(false); - if (e.dataTransfer.files.length === 0) { + if (e.dataTransfer.files.length === 0 || !editor.isEditable) { return; } const filesList = e.dataTransfer.files; diff --git a/packages/editor/src/core/hooks/use-read-only-collaborative-editor.ts b/packages/editor/src/core/hooks/use-read-only-collaborative-editor.ts deleted file mode 100644 index 01ca19b8148..00000000000 --- a/packages/editor/src/core/hooks/use-read-only-collaborative-editor.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { useEffect, useMemo, useState } from "react"; -import { HocuspocusProvider } from "@hocuspocus/provider"; -import Collaboration from "@tiptap/extension-collaboration"; -import { IndexeddbPersistence } from "y-indexeddb"; -// extensions -import { HeadingListExtension } from "@/extensions"; -// hooks -import { useReadOnlyEditor } from "@/hooks/use-read-only-editor"; -// types -import { TReadOnlyCollaborativeEditorProps } from "@/types"; - -export const useReadOnlyCollaborativeEditor = (props: TReadOnlyCollaborativeEditorProps) => { - const { - disabledExtensions, - editorClassName, - editorProps = {}, - extensions, - fileHandler, - forwardedRef, - handleEditorReady, - id, - mentionHandler, - realtimeConfig, - serverHandler, - user, - } = props; - // states - const [hasServerConnectionFailed, setHasServerConnectionFailed] = useState(false); - const [hasServerSynced, setHasServerSynced] = useState(false); - // initialize Hocuspocus provider - const provider = useMemo( - () => - new HocuspocusProvider({ - name: id, - url: realtimeConfig.url, - token: JSON.stringify(user), - parameters: realtimeConfig.queryParams, - onAuthenticationFailed: () => { - serverHandler?.onServerError?.(); - setHasServerConnectionFailed(true); - }, - onConnect: () => serverHandler?.onConnect?.(), - onClose: (data) => { - if (data.event.code === 1006) { - serverHandler?.onServerError?.(); - setHasServerConnectionFailed(true); - } - }, - onSynced: () => setHasServerSynced(true), - }), - [id, realtimeConfig, serverHandler, user] - ); - - // indexed db integration for offline support - const localProvider = useMemo( - () => (id ? new IndexeddbPersistence(id, provider.document) : undefined), - [id, provider] - ); - - // destroy and disconnect connection on unmount - useEffect( - () => () => { - provider.destroy(); - localProvider?.destroy(); - }, - [provider, localProvider] - ); - - const editor = useReadOnlyEditor({ - disabledExtensions, - editorProps, - editorClassName, - extensions: [ - ...(extensions ?? []), - HeadingListExtension, - Collaboration.configure({ - document: provider.document, - }), - ], - fileHandler, - forwardedRef, - handleEditorReady, - mentionHandler, - provider, - }); - - return { - editor, - hasServerConnectionFailed, - hasServerSynced, - }; -}; diff --git a/packages/editor/src/core/plugins/image/utils/validate-file.ts b/packages/editor/src/core/plugins/image/utils/validate-file.ts index db88f3f73c8..703bb2bf0a9 100644 --- a/packages/editor/src/core/plugins/image/utils/validate-file.ts +++ b/packages/editor/src/core/plugins/image/utils/validate-file.ts @@ -1,3 +1,6 @@ +// constants +import { ACCEPTED_FILE_MIME_TYPES } from "@/constants/config"; + type TArgs = { file: File; maxFileSize: number; @@ -11,9 +14,8 @@ export const isFileValid = (args: TArgs): boolean => { return false; } - const allowedTypes = ["image/jpeg", "image/jpg", "image/png", "image/webp"]; - if (!allowedTypes.includes(file.type)) { - alert("Invalid file type. Please select a JPEG, JPG, PNG, or WEBP image file."); + if (!ACCEPTED_FILE_MIME_TYPES.includes(file.type)) { + alert("Invalid file type. Please select a JPEG, JPG, PNG, WEBP or GIF file."); return false; } diff --git a/packages/editor/src/core/props/props.tsx b/packages/editor/src/core/props/props.tsx index 4bda3e51a2d..ee0b9e50007 100644 --- a/packages/editor/src/core/props/props.tsx +++ b/packages/editor/src/core/props/props.tsx @@ -1,6 +1,6 @@ import { EditorProps } from "@tiptap/pm/view"; -// helpers -import { cn } from "@/helpers/common"; +// plane utils +import { cn } from "@plane/utils"; export type TCoreEditorProps = { editorClassName: string; diff --git a/packages/editor/src/core/props/read-only.tsx b/packages/editor/src/core/props/read-only.tsx index aaa635a508f..ea5bf09f3a7 100644 --- a/packages/editor/src/core/props/read-only.tsx +++ b/packages/editor/src/core/props/read-only.tsx @@ -1,6 +1,6 @@ import { EditorProps } from "@tiptap/pm/view"; -// helpers -import { cn } from "@/helpers/common"; +// plane utils +import { cn } from "@plane/utils"; // props import { TCoreEditorProps } from "@/props"; diff --git a/packages/editor/src/core/types/collaboration.ts b/packages/editor/src/core/types/collaboration.ts index de1e09e9307..c69a003fc9c 100644 --- a/packages/editor/src/core/types/collaboration.ts +++ b/packages/editor/src/core/types/collaboration.ts @@ -21,6 +21,7 @@ export type TServerHandler = { type TCollaborativeEditorHookProps = { disabledExtensions: TExtensions[]; + editable?: boolean; editorClassName: string; editorProps?: EditorProps; extensions?: Extensions; diff --git a/packages/editor/src/core/types/editor.ts b/packages/editor/src/core/types/editor.ts index cec6ff0080c..27a719f0476 100644 --- a/packages/editor/src/core/types/editor.ts +++ b/packages/editor/src/core/types/editor.ts @@ -135,6 +135,7 @@ export interface IRichTextEditor extends IEditorProps { export interface ICollaborativeDocumentEditor extends Omit { + editable: boolean; aiHandler?: TAIHandler; embedHandler: TEmbedConfig; handleEditorReady?: (value: boolean) => void; diff --git a/packages/editor/src/index.ts b/packages/editor/src/index.ts index ed7d9134698..9dd0db267f2 100644 --- a/packages/editor/src/index.ts +++ b/packages/editor/src/index.ts @@ -9,7 +9,6 @@ import "./styles/drag-drop.css"; // editors export { CollaborativeDocumentEditorWithRef, - CollaborativeDocumentReadOnlyEditorWithRef, DocumentReadOnlyEditorWithRef, LiteTextEditorWithRef, LiteTextReadOnlyEditorWithRef, diff --git a/packages/editor/src/styles/editor.css b/packages/editor/src/styles/editor.css index db60c7cf5f5..e234f87cf86 100644 --- a/packages/editor/src/styles/editor.css +++ b/packages/editor/src/styles/editor.css @@ -111,8 +111,12 @@ ul[data-type="taskList"] li > label input[type="checkbox"] { transform: scale(1.05); } -ul[data-type="taskList"] li > label input[type="checkbox"]:hover { - background-color: rgba(var(--color-background-80)) !important; +.ProseMirror[contenteditable="true"] input[type="checkbox"]:hover { + background-color: rgba(var(--color-background-80)); +} + +.ProseMirror[contenteditable="false"] input[type="checkbox"] { + pointer-events: none; } ul[data-type="taskList"] li > label input[type="checkbox"][checked] { @@ -151,10 +155,6 @@ ul[data-type="taskList"] li > label input[type="checkbox"] { margin-right: 0.2rem; margin-top: 0.15rem; - &:hover { - background-color: rgb(var(--color-background-80)); - } - &:active { background-color: rgb(var(--color-background-90)); } diff --git a/packages/types/src/index.d.ts b/packages/types/src/index.d.ts index 6a0dd2f7dc3..fa4bf05a8ab 100644 --- a/packages/types/src/index.d.ts +++ b/packages/types/src/index.d.ts @@ -34,3 +34,4 @@ export * from "./favorite"; export * from "./file"; export * from "./workspace-draft-issues/base"; export * from "./command-palette"; +export * from "./timezone"; diff --git a/packages/types/src/issues.d.ts b/packages/types/src/issues.d.ts index b6d32bdf816..f77408fd6c0 100644 --- a/packages/types/src/issues.d.ts +++ b/packages/types/src/issues.d.ts @@ -10,6 +10,12 @@ import type { Properties, IIssueDisplayFilterOptions, TIssue, + IIssueFilterOptions, + IIssueDisplayProperties, + TIssueGroupByOptions, + TIssueOrderByOptions, + TIssueGroupingFilters, + TIssueExtraOptions } from "@plane/types"; export interface IIssueCycle { @@ -235,3 +241,18 @@ export interface IIssueListRow { icon?: ReactElement | undefined; payload?: Partial; } + +export interface ILayoutDisplayFiltersOptions { + filters: (keyof IIssueFilterOptions)[]; + display_properties: (keyof IIssueDisplayProperties)[]; + display_filters: { + group_by?: TIssueGroupByOptions[]; + sub_group_by?: TIssueGroupByOptions[]; + order_by?: TIssueOrderByOptions[]; + type?: TIssueGroupingFilters[]; + }; + extra_options: { + access: boolean; + values: TIssueExtraOptions[]; + }; +} diff --git a/packages/types/src/timezone.d.ts b/packages/types/src/timezone.d.ts new file mode 100644 index 00000000000..b4df123a306 --- /dev/null +++ b/packages/types/src/timezone.d.ts @@ -0,0 +1,8 @@ +export type TTimezoneObject = { + utc_offset: string; + gmt_offset: string; + label: string; + value: string; +}; + +export type TTimezones = { timezones: TTimezoneObject[] }; diff --git a/packages/types/src/view-props.d.ts b/packages/types/src/view-props.d.ts index aa1c75cdbdc..dca1a652c62 100644 --- a/packages/types/src/view-props.d.ts +++ b/packages/types/src/view-props.d.ts @@ -1,5 +1,3 @@ -import { EIssueLayoutTypes } from "constants/issue"; - export type TIssueLayouts = | "list" | "kanban" @@ -110,7 +108,7 @@ export interface IIssueDisplayFilterOptions { }; group_by?: TIssueGroupByOptions; sub_group_by?: TIssueGroupByOptions; - layout?: EIssueLayoutTypes; + layout?: any; // TODO: Need to fix this and set it to enum EIssueLayoutTypes order_by?: TIssueOrderByOptions; show_empty_groups?: boolean; sub_issue?: boolean; diff --git a/packages/utils/package.json b/packages/utils/package.json index a0e0ecca141..69519e57042 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -15,8 +15,10 @@ "lint:errors": "eslint src --ext .ts,.tsx --quiet" }, "dependencies": { + "clsx": "^2.1.1", "isomorphic-dompurify": "^2.16.0", - "react": "^18.3.1" + "react": "^18.3.1", + "tailwind-merge": "^2.5.5" }, "devDependencies": { "@plane/eslint-config": "*", diff --git a/packages/utils/src/common.ts b/packages/utils/src/common.ts new file mode 100644 index 00000000000..a500a738583 --- /dev/null +++ b/packages/utils/src/common.ts @@ -0,0 +1,4 @@ +import { clsx, type ClassValue } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export const cn = (...inputs: ClassValue[]) => twMerge(clsx(inputs)); diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 7e63eed7925..cf629534521 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -1,3 +1,4 @@ export * from "./color"; +export * from "./common"; export * from "./emoji"; export * from "./string"; diff --git a/space/core/components/issues/issue-layouts/kanban/block-reactions.tsx b/space/core/components/issues/issue-layouts/kanban/block-reactions.tsx index 241a087e781..a7ffd38ae85 100644 --- a/space/core/components/issues/issue-layouts/kanban/block-reactions.tsx +++ b/space/core/components/issues/issue-layouts/kanban/block-reactions.tsx @@ -1,7 +1,7 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; -//plane -import { cn } from "@plane/editor"; +// plane utils +import { cn } from "@plane/utils"; // components import { IssueEmojiReactions, IssueVotes } from "@/components/issues/reactions"; // hooks diff --git a/space/core/components/issues/issue-layouts/kanban/block.tsx b/space/core/components/issues/issue-layouts/kanban/block.tsx index 7c246cc339f..1975963cc1a 100644 --- a/space/core/components/issues/issue-layouts/kanban/block.tsx +++ b/space/core/components/issues/issue-layouts/kanban/block.tsx @@ -4,10 +4,12 @@ import { MutableRefObject } from "react"; import { observer } from "mobx-react"; import Link from "next/link"; import { useParams, useSearchParams } from "next/navigation"; -// plane -import { cn } from "@plane/editor"; +// plane types import { IIssueDisplayProperties } from "@plane/types"; +// plane ui import { Tooltip } from "@plane/ui"; +// plane utils +import { cn } from "@plane/utils"; // components import { WithDisplayPropertiesHOC } from "@/components/issues/issue-layouts/with-display-properties-HOC"; // helpers diff --git a/space/core/components/issues/issue-layouts/list/block.tsx b/space/core/components/issues/issue-layouts/list/block.tsx index 39a298448ac..6d4fb0983f5 100644 --- a/space/core/components/issues/issue-layouts/list/block.tsx +++ b/space/core/components/issues/issue-layouts/list/block.tsx @@ -4,10 +4,12 @@ import { useRef } from "react"; import { observer } from "mobx-react"; import Link from "next/link"; import { useParams, useSearchParams } from "next/navigation"; -// types -import { cn } from "@plane/editor"; +// plane types import { IIssueDisplayProperties } from "@plane/types"; +// plane ui import { Tooltip } from "@plane/ui"; +// plane utils +import { cn } from "@plane/utils"; // helpers import { queryParamGenerator } from "@/helpers/query-param-generator"; // hooks diff --git a/space/core/components/issues/issue-layouts/list/list-group.tsx b/space/core/components/issues/issue-layouts/list/list-group.tsx index 742cfeef156..75d280d0d07 100644 --- a/space/core/components/issues/issue-layouts/list/list-group.tsx +++ b/space/core/components/issues/issue-layouts/list/list-group.tsx @@ -2,9 +2,10 @@ import { Fragment, MutableRefObject, forwardRef, useRef, useState } from "react"; import { observer } from "mobx-react"; -import { cn } from "@plane/editor"; -// plane +// plane types import { IGroupByColumn, TIssueGroupByOptions, IIssueDisplayProperties, TPaginationData, TLoader } from "@plane/types"; +// plane utils +import { cn } from "@plane/utils"; // hooks import { useIntersectionObserver } from "@/hooks/use-intersection-observer"; // diff --git a/space/core/components/issues/issue-layouts/properties/all-properties.tsx b/space/core/components/issues/issue-layouts/properties/all-properties.tsx index 3c596cb53c9..66e9ab2960c 100644 --- a/space/core/components/issues/issue-layouts/properties/all-properties.tsx +++ b/space/core/components/issues/issue-layouts/properties/all-properties.tsx @@ -2,11 +2,12 @@ import { observer } from "mobx-react"; import { Layers, Link, Paperclip } from "lucide-react"; -// types -import { cn } from "@plane/editor"; +// plane types import { IIssueDisplayProperties } from "@plane/types"; +// plane ui import { Tooltip } from "@plane/ui"; -// ui +// plane utils +import { cn } from "@plane/utils"; // components import { IssueBlockDate, diff --git a/space/core/components/issues/issue-layouts/properties/cycle.tsx b/space/core/components/issues/issue-layouts/properties/cycle.tsx index 52c10578978..1774781cd39 100644 --- a/space/core/components/issues/issue-layouts/properties/cycle.tsx +++ b/space/core/components/issues/issue-layouts/properties/cycle.tsx @@ -1,9 +1,10 @@ "use client"; import { observer } from "mobx-react"; -// ui -import { cn } from "@plane/editor"; +// plane ui import { ContrastIcon, Tooltip } from "@plane/ui"; +// plane utils +import { cn } from "@plane/utils"; //hooks import { useCycle } from "@/hooks/store/use-cycle"; diff --git a/space/core/components/issues/issue-layouts/properties/member.tsx b/space/core/components/issues/issue-layouts/properties/member.tsx index bac44d52322..9ae3314f180 100644 --- a/space/core/components/issues/issue-layouts/properties/member.tsx +++ b/space/core/components/issues/issue-layouts/properties/member.tsx @@ -3,9 +3,10 @@ import { observer } from "mobx-react"; // icons import { LucideIcon, Users } from "lucide-react"; -// ui -import { cn } from "@plane/editor"; +// plane ui import { Avatar, AvatarGroup } from "@plane/ui"; +// plane utils +import { cn } from "@plane/utils"; // hooks import { useMember } from "@/hooks/store/use-member"; // diff --git a/space/core/components/issues/issue-layouts/properties/modules.tsx b/space/core/components/issues/issue-layouts/properties/modules.tsx index eaa30d9908b..465f469c0b4 100644 --- a/space/core/components/issues/issue-layouts/properties/modules.tsx +++ b/space/core/components/issues/issue-layouts/properties/modules.tsx @@ -1,9 +1,10 @@ "use client"; import { observer } from "mobx-react"; -// planes -import { cn } from "@plane/editor"; +// plane ui import { DiceIcon, Tooltip } from "@plane/ui"; +// plane utils +import { cn } from "@plane/utils"; // hooks import { useModule } from "@/hooks/store/use-module"; diff --git a/space/core/components/issues/issue-layouts/properties/state.tsx b/space/core/components/issues/issue-layouts/properties/state.tsx index 56a09bcd99f..1d2d1c6fe87 100644 --- a/space/core/components/issues/issue-layouts/properties/state.tsx +++ b/space/core/components/issues/issue-layouts/properties/state.tsx @@ -1,9 +1,10 @@ "use client"; import { observer } from "mobx-react"; -// ui -import { cn } from "@plane/editor"; +// plane ui import { StateGroupIcon, Tooltip } from "@plane/ui"; +// plane utils +import { cn } from "@plane/utils"; //hooks import { useStates } from "@/hooks/store"; diff --git a/web/app/[workspaceSlug]/(projects)/drafts/header.tsx b/web/app/[workspaceSlug]/(projects)/drafts/header.tsx index f77e61c3199..68597b509a0 100644 --- a/web/app/[workspaceSlug]/(projects)/drafts/header.tsx +++ b/web/app/[workspaceSlug]/(projects)/drafts/header.tsx @@ -3,13 +3,13 @@ import { useState } from "react"; import { observer } from "mobx-react"; import { PenSquare } from "lucide-react"; +import { EIssuesStoreType } from "@plane/constants"; // ui import { Breadcrumbs, Button, Header } from "@plane/ui"; // components import { BreadcrumbLink, CountChip } from "@/components/common"; import { CreateUpdateIssueModal } from "@/components/issues"; -// constants -import { EIssuesStoreType } from "@/constants/issue"; + // hooks import { useProject, useUserPermissions, useWorkspaceDraftIssues } from "@/hooks/store"; // plane-web diff --git a/web/app/[workspaceSlug]/(projects)/profile/[userId]/mobile-header.tsx b/web/app/[workspaceSlug]/(projects)/profile/[userId]/mobile-header.tsx index b963ca147c9..21d230347c9 100644 --- a/web/app/[workspaceSlug]/(projects)/profile/[userId]/mobile-header.tsx +++ b/web/app/[workspaceSlug]/(projects)/profile/[userId]/mobile-header.tsx @@ -5,6 +5,8 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // icons import { ChevronDown } from "lucide-react"; +// plane constants +import { EIssueLayoutTypes, EIssueFilterType, EIssuesStoreType } from "@plane/constants"; // types import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions, TIssueLayouts } from "@plane/types"; // ui @@ -12,13 +14,7 @@ import { CustomMenu } from "@plane/ui"; // components import { DisplayFiltersSelection, FilterSelection, FiltersDropdown } from "@/components/issues"; // constants -import { - EIssueFilterType, - EIssueLayoutTypes, - EIssuesStoreType, - ISSUE_DISPLAY_FILTERS_BY_LAYOUT, - ISSUE_LAYOUTS, -} from "@/constants/issue"; +import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT, ISSUE_LAYOUTS } from "@/constants/issue"; // helpers import { isIssueFilterActive } from "@/helpers/filter.helper"; // hooks diff --git a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/archives/header.tsx b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/archives/header.tsx index f95611fbc45..17df19b2201 100644 --- a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/archives/header.tsx +++ b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/archives/header.tsx @@ -3,13 +3,13 @@ import { FC } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; +import { EIssuesStoreType } from "@plane/constants"; // ui import { ArchiveIcon, Breadcrumbs, Tooltip, Header } from "@plane/ui"; // components import { BreadcrumbLink, Logo } from "@/components/common"; // constants import { PROJECT_ARCHIVES_BREADCRUMB_LIST } from "@/constants/archives"; -import { EIssuesStoreType } from "@/constants/issue"; // hooks import { useIssues, useProject } from "@/hooks/store"; import { useAppRouter } from "@/hooks/use-app-router"; diff --git a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(detail)/[cycleId]/page.tsx b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(detail)/[cycleId]/page.tsx index 7a29f055306..37bfae3b1b4 100644 --- a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(detail)/[cycleId]/page.tsx +++ b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(detail)/[cycleId]/page.tsx @@ -8,8 +8,6 @@ import { PageHead } from "@/components/core"; import { CycleDetailsSidebar } from "@/components/cycles"; import useCyclesDetails from "@/components/cycles/active-cycle/use-cycles-details"; import { CycleLayoutRoot } from "@/components/issues/issue-layouts"; -// constants -// import { EIssuesStoreType } from "@/constants/issue"; // helpers import { cn } from "@/helpers/common.helper"; // hooks diff --git a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(detail)/header.tsx b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(detail)/header.tsx index 678c50c2a8f..dc079bc949d 100644 --- a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(detail)/header.tsx +++ b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(detail)/header.tsx @@ -6,6 +6,8 @@ import Link from "next/link"; import { useParams } from "next/navigation"; // icons import { ArrowRight, PanelRight } from "lucide-react"; +// plane constants +import { EIssueLayoutTypes, EIssueFilterType, EIssuesStoreType } from "@plane/constants"; // types import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions } from "@plane/types"; // ui @@ -15,12 +17,7 @@ import { ProjectAnalyticsModal } from "@/components/analytics"; import { BreadcrumbLink, Logo } from "@/components/common"; import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "@/components/issues"; // constants -import { - EIssueFilterType, - EIssueLayoutTypes, - EIssuesStoreType, - ISSUE_DISPLAY_FILTERS_BY_LAYOUT, -} from "@/constants/issue"; +import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "@/constants/issue"; // helpers import { cn } from "@/helpers/common.helper"; import { isIssueFilterActive } from "@/helpers/filter.helper"; diff --git a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(detail)/mobile-header.tsx b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(detail)/mobile-header.tsx index aa81ae5816a..1f85665fa86 100644 --- a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(detail)/mobile-header.tsx +++ b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(detail)/mobile-header.tsx @@ -4,6 +4,8 @@ import { useCallback, useState } from "react"; import { useParams } from "next/navigation"; // icons import { Calendar, ChevronDown, Kanban, List } from "lucide-react"; +// plane constants +import { EIssueLayoutTypes, EIssueFilterType, EIssuesStoreType } from "@plane/constants"; // types import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions } from "@plane/types"; // ui @@ -12,13 +14,7 @@ import { CustomMenu } from "@plane/ui"; import { ProjectAnalyticsModal } from "@/components/analytics"; import { DisplayFiltersSelection, FilterSelection, FiltersDropdown } from "@/components/issues"; // constants -import { - EIssueFilterType, - EIssueLayoutTypes, - EIssuesStoreType, - ISSUE_DISPLAY_FILTERS_BY_LAYOUT, - ISSUE_LAYOUTS, -} from "@/constants/issue"; +import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT, ISSUE_LAYOUTS } from "@/constants/issue"; // helpers import { isIssueFilterActive } from "@/helpers/filter.helper"; // hooks diff --git a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/draft-issues/header.tsx b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/draft-issues/header.tsx index c1e866d0348..59c5e995bf5 100644 --- a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/draft-issues/header.tsx +++ b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/draft-issues/header.tsx @@ -3,6 +3,8 @@ import { FC, useCallback } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; +// plane constants +import { EIssueLayoutTypes, EIssueFilterType, EIssuesStoreType } from "@plane/constants"; // types import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions } from "@plane/types"; // ui @@ -11,12 +13,7 @@ import { Breadcrumbs, LayersIcon, Tooltip } from "@plane/ui"; import { BreadcrumbLink, Logo } from "@/components/common"; import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "@/components/issues"; // constants -import { - EIssueFilterType, - EIssuesStoreType, - EIssueLayoutTypes, - ISSUE_DISPLAY_FILTERS_BY_LAYOUT, -} from "@/constants/issue"; +import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "@/constants/issue"; // helpers import { isIssueFilterActive } from "@/helpers/filter.helper"; // hooks diff --git a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/issues/(list)/mobile-header.tsx b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/issues/(list)/mobile-header.tsx index 025c9fab04f..29f2637b76e 100644 --- a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/issues/(list)/mobile-header.tsx +++ b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/issues/(list)/mobile-header.tsx @@ -5,6 +5,8 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // icons import { Calendar, ChevronDown, Kanban, List } from "lucide-react"; +// plane constants +import { EIssueLayoutTypes, EIssueFilterType, EIssuesStoreType } from "@plane/constants"; // types import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions } from "@plane/types"; // ui @@ -13,13 +15,7 @@ import { CustomMenu } from "@plane/ui"; import { ProjectAnalyticsModal } from "@/components/analytics"; import { DisplayFiltersSelection, FilterSelection, FiltersDropdown } from "@/components/issues/issue-layouts"; // constants -import { - EIssueFilterType, - EIssueLayoutTypes, - EIssuesStoreType, - ISSUE_DISPLAY_FILTERS_BY_LAYOUT, - ISSUE_LAYOUTS, -} from "@/constants/issue"; +import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT, ISSUE_LAYOUTS } from "@/constants/issue"; // helpers import { isIssueFilterActive } from "@/helpers/filter.helper"; // hooks diff --git a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/modules/(detail)/header.tsx b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/modules/(detail)/header.tsx index 38c2f4453fd..e84cef04fdc 100644 --- a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/modules/(detail)/header.tsx +++ b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/modules/(detail)/header.tsx @@ -6,6 +6,8 @@ import Link from "next/link"; import { useParams } from "next/navigation"; // icons import { ArrowRight, PanelRight } from "lucide-react"; +// plane constants +import { EIssueLayoutTypes, EIssuesStoreType, EIssueFilterType } from "@plane/constants"; // types import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions } from "@plane/types"; // ui @@ -15,12 +17,7 @@ import { ProjectAnalyticsModal } from "@/components/analytics"; import { BreadcrumbLink, Logo } from "@/components/common"; import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "@/components/issues"; // constants -import { - EIssuesStoreType, - EIssueFilterType, - EIssueLayoutTypes, - ISSUE_DISPLAY_FILTERS_BY_LAYOUT, -} from "@/constants/issue"; +import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "@/constants/issue"; // helpers import { cn } from "@/helpers/common.helper"; import { isIssueFilterActive } from "@/helpers/filter.helper"; diff --git a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/modules/(detail)/mobile-header.tsx b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/modules/(detail)/mobile-header.tsx index 0edfa2b5a2b..63cf32ef6ef 100644 --- a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/modules/(detail)/mobile-header.tsx +++ b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/modules/(detail)/mobile-header.tsx @@ -5,21 +5,17 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // icons import { Calendar, ChevronDown, Kanban, List } from "lucide-react"; +// plane constants +import { EIssueLayoutTypes, EIssueFilterType, EIssuesStoreType } from "@plane/constants"; // types import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions } from "@plane/types"; // ui import { CustomMenu } from "@plane/ui"; // components import { ProjectAnalyticsModal } from "@/components/analytics"; -import { DisplayFiltersSelection, FilterSelection, FiltersDropdown } from "@/components/issues"; +import { DisplayFiltersSelection, FilterSelection, FiltersDropdown } from "@/components/issues/issue-layouts"; // constants -import { - EIssueFilterType, - EIssueLayoutTypes, - EIssuesStoreType, - ISSUE_DISPLAY_FILTERS_BY_LAYOUT, - ISSUE_LAYOUTS, -} from "@/constants/issue"; +import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT, ISSUE_LAYOUTS } from "@/constants/issue"; // helpers import { isIssueFilterActive } from "@/helpers/filter.helper"; // hooks diff --git a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/views/(detail)/[viewId]/header.tsx b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/views/(detail)/[viewId]/header.tsx index 6fd44adfcd9..aca4b5b4a5e 100644 --- a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/views/(detail)/[viewId]/header.tsx +++ b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/views/(detail)/[viewId]/header.tsx @@ -5,6 +5,8 @@ import { observer } from "mobx-react"; import Link from "next/link"; import { useParams } from "next/navigation"; import { Layers, Lock } from "lucide-react"; +// plane constants +import { EIssueLayoutTypes, EIssueFilterType, EIssuesStoreType } from "@plane/constants"; // types import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions } from "@plane/types"; // ui @@ -13,12 +15,7 @@ import { Breadcrumbs, Button, CustomMenu, Tooltip, Header } from "@plane/ui"; import { BreadcrumbLink, Logo } from "@/components/common"; import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "@/components/issues"; // constants -import { - EIssuesStoreType, - EIssueFilterType, - EIssueLayoutTypes, - ISSUE_DISPLAY_FILTERS_BY_LAYOUT, -} from "@/constants/issue"; +import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "@/constants/issue"; import { EViewAccess } from "@/constants/views"; // helpers import { isIssueFilterActive } from "@/helpers/filter.helper"; diff --git a/web/app/[workspaceSlug]/(projects)/workspace-views/header.tsx b/web/app/[workspaceSlug]/(projects)/workspace-views/header.tsx index 500d23ed701..e1ec683ec3a 100644 --- a/web/app/[workspaceSlug]/(projects)/workspace-views/header.tsx +++ b/web/app/[workspaceSlug]/(projects)/workspace-views/header.tsx @@ -3,8 +3,10 @@ import { useCallback, useState } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; -// types import { Layers } from "lucide-react"; +// plane constants +import { EIssueFilterType, EIssuesStoreType } from "@plane/constants"; +// types import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions } from "@plane/types"; // ui import { Breadcrumbs, Button, Header } from "@plane/ui"; @@ -13,7 +15,7 @@ import { BreadcrumbLink } from "@/components/common"; import { DisplayFiltersSelection, FiltersDropdown, FilterSelection } from "@/components/issues"; import { CreateUpdateWorkspaceViewModal } from "@/components/workspace"; // constants -import { EIssueFilterType, EIssuesStoreType, ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "@/constants/issue"; +import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "@/constants/issue"; // helpers import { isIssueFilterActive } from "@/helpers/filter.helper"; // hooks diff --git a/web/app/profile/page.tsx b/web/app/profile/page.tsx index 1dd9702a36b..d451042d9d6 100644 --- a/web/app/profile/page.tsx +++ b/web/app/profile/page.tsx @@ -20,9 +20,9 @@ import { import { DeactivateAccountModal } from "@/components/account"; import { LogoSpinner } from "@/components/common"; import { ImagePickerPopover, UserImageUploadModal, PageHead } from "@/components/core"; +import { TimezoneSelect } from "@/components/global"; import { ProfileSettingContentWrapper } from "@/components/profile"; // constants -import { TIME_ZONES, TTimezone } from "@/constants/timezones"; import { USER_ROLES } from "@/constants/workspace"; // helpers import { getFileURL } from "@/helpers/file.helper"; @@ -120,22 +120,6 @@ const ProfileSettingsPage = observer(() => { }); }; - const getTimeZoneLabel = (timezone: TTimezone | undefined) => { - if (!timezone) return undefined; - return ( -
- {timezone.gmtOffset} - {timezone.name} -
- ); - }; - - const timeZoneOptions = TIME_ZONES.map((timeZone) => ({ - value: timeZone.value, - query: timeZone.name + " " + timeZone.gmtOffset + " " + timeZone.value, - content: getTimeZoneLabel(timeZone), - })); - if (!currentUser) return (
@@ -379,19 +363,12 @@ const ProfileSettingsPage = observer(() => { control={control} rules={{ required: "Please select a timezone" }} render={({ field: { value, onChange } }) => ( - t.value === value)) ?? value) - : "Select a timezone" - } - options={timeZoneOptions} - onChange={onChange} - buttonClassName={errors.user_timezone ? "border-red-500" : ""} - className="rounded-md border-[0.5px] !border-custom-border-200" - optionsClassName="w-72" - input + onChange={(value: string) => { + onChange(value); + }} + error={Boolean(errors.user_timezone)} /> )} /> diff --git a/web/ce/components/issues/header.tsx b/web/ce/components/issues/header.tsx index a4c750061de..51dbc3b4174 100644 --- a/web/ce/components/issues/header.tsx +++ b/web/ce/components/issues/header.tsx @@ -4,13 +4,14 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // icons import { Briefcase, Circle, ExternalLink } from "lucide-react"; +// plane constants +import { EIssuesStoreType } from "@plane/constants"; // ui import { Breadcrumbs, Button, LayersIcon, Tooltip, Header } from "@plane/ui"; // components import { BreadcrumbLink, CountChip, Logo } from "@/components/common"; // constants import HeaderFilters from "@/components/issues/filters"; -import { EIssuesStoreType } from "@/constants/issue"; // helpers import { SPACE_BASE_PATH, SPACE_BASE_URL } from "@/helpers/common.helper"; // hooks diff --git a/web/ce/components/issues/quick-add/root.tsx b/web/ce/components/issues/quick-add/root.tsx index 382f790a0cf..c0bd3914edf 100644 --- a/web/ce/components/issues/quick-add/root.tsx +++ b/web/ce/components/issues/quick-add/root.tsx @@ -1,6 +1,8 @@ import { FC, useEffect, useRef } from "react"; import { observer } from "mobx-react"; import { UseFormRegister, UseFormSetFocus } from "react-hook-form"; +// plane constants +import { EIssueLayoutTypes } from "@plane/constants"; // plane helpers import { useOutsideClickDetector } from "@plane/hooks"; // types @@ -14,8 +16,6 @@ import { SpreadsheetQuickAddIssueForm, TQuickAddIssueForm, } from "@/components/issues/issue-layouts"; -// constants -import { EIssueLayoutTypes } from "@/constants/issue"; // hooks import { useProject } from "@/hooks/store"; import useKeypress from "@/hooks/use-keypress"; diff --git a/web/ce/components/workflow/add-state-transition.tsx b/web/ce/components/workflow/add-state-transition.tsx index 48ba6c02ab9..a22769ba254 100644 --- a/web/ce/components/workflow/add-state-transition.tsx +++ b/web/ce/components/workflow/add-state-transition.tsx @@ -1,6 +1,6 @@ import { Plus } from "lucide-react"; -// Plane -import { cn } from "@plane/editor"; +// plane utils +import { cn } from "@plane/utils"; type Props = { workspaceSlug: string; diff --git a/web/ce/constants/issues.ts b/web/ce/constants/issues.ts index 99b8ef90de1..70a34577f73 100644 --- a/web/ce/constants/issues.ts +++ b/web/ce/constants/issues.ts @@ -1,6 +1,4 @@ -import { TIssueActivityComment } from "@plane/types"; -// constants -import { ILayoutDisplayFiltersOptions } from "@/constants/issue"; +import { ILayoutDisplayFiltersOptions, TIssueActivityComment } from "@plane/types"; export enum EActivityFilterType { ACTIVITY = "ACTIVITY", diff --git a/web/ce/types/projects/index.ts b/web/ce/types/projects/index.ts index 244d8c4df33..9fb35777a3a 100644 --- a/web/ce/types/projects/index.ts +++ b/web/ce/types/projects/index.ts @@ -1 +1,2 @@ export * from "./projects"; +export * from "./project-activity"; diff --git a/web/ce/types/projects/project-activity.ts b/web/ce/types/projects/project-activity.ts new file mode 100644 index 00000000000..ed75a6b9c81 --- /dev/null +++ b/web/ce/types/projects/project-activity.ts @@ -0,0 +1,25 @@ +export interface TProjectActivity { + id: string; + content: string; + createdAt: string; + updatedAt: string; + userId: string; + projectId: string; + created_at: string; + field: string; + verb: string; + actor_detail: { + display_name: string; + id: string; + }; + workspace_detail: { + slug: string; + }; + project_detail: { + name: string; + }; + new_value: string; + old_value: string; + project: string; + new_identifier?: string; +} diff --git a/web/core/components/command-palette/actions/issue-actions/actions-list.tsx b/web/core/components/command-palette/actions/issue-actions/actions-list.tsx index 6c1c01acad2..c15a935b5e7 100644 --- a/web/core/components/command-palette/actions/issue-actions/actions-list.tsx +++ b/web/core/components/command-palette/actions/issue-actions/actions-list.tsx @@ -4,11 +4,10 @@ import { Command } from "cmdk"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; import { LinkIcon, Signal, Trash2, UserMinus2, UserPlus2, Users } from "lucide-react"; +import { EIssuesStoreType } from "@plane/constants"; import { TIssue } from "@plane/types"; // hooks import { DoubleCircleIcon, TOAST_TYPE, setToast } from "@plane/ui"; -// constants -import { EIssuesStoreType } from "@/constants/issue"; // helpers import { copyTextToClipboard } from "@/helpers/string.helper"; // hooks diff --git a/web/core/components/command-palette/actions/issue-actions/change-assignee.tsx b/web/core/components/command-palette/actions/issue-actions/change-assignee.tsx index 319adf8f238..84ac73b7550 100644 --- a/web/core/components/command-palette/actions/issue-actions/change-assignee.tsx +++ b/web/core/components/command-palette/actions/issue-actions/change-assignee.tsx @@ -4,12 +4,12 @@ import { Command } from "cmdk"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; import { Check } from "lucide-react"; +// plane constants +import { EIssuesStoreType } from "@plane/constants"; // plane types import { TIssue } from "@plane/types"; // plane ui import { Avatar } from "@plane/ui"; -// constants -import { EIssuesStoreType } from "@/constants/issue"; // helpers import { getFileURL } from "@/helpers/file.helper"; // hooks diff --git a/web/core/components/command-palette/actions/issue-actions/change-priority.tsx b/web/core/components/command-palette/actions/issue-actions/change-priority.tsx index 5bd8ce850e1..2f004e8eae0 100644 --- a/web/core/components/command-palette/actions/issue-actions/change-priority.tsx +++ b/web/core/components/command-palette/actions/issue-actions/change-priority.tsx @@ -1,13 +1,16 @@ -"use client"; `` +"use client"; import { Command } from "cmdk"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; import { Check } from "lucide-react"; +// plane constants +import { EIssuesStoreType } from "@plane/constants"; +// plane types import { TIssue, TIssuePriorities } from "@plane/types"; // mobx store import { PriorityIcon } from "@plane/ui"; -import { EIssuesStoreType, ISSUE_PRIORITIES } from "@/constants/issue"; +import { ISSUE_PRIORITIES } from "@/constants/issue"; import { useIssues } from "@/hooks/store"; // ui // types diff --git a/web/core/components/command-palette/actions/issue-actions/change-state.tsx b/web/core/components/command-palette/actions/issue-actions/change-state.tsx index 5d512f4acaf..f60ee7dcaa1 100644 --- a/web/core/components/command-palette/actions/issue-actions/change-state.tsx +++ b/web/core/components/command-palette/actions/issue-actions/change-state.tsx @@ -5,9 +5,9 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // hooks import { Check } from "lucide-react"; +import { EIssuesStoreType } from "@plane/constants"; import { TIssue } from "@plane/types"; import { Spinner, StateGroupIcon } from "@plane/ui"; -import { EIssuesStoreType } from "@/constants/issue"; import { useProjectState, useIssues } from "@/hooks/store"; // ui // icons diff --git a/web/core/components/common/access-field.tsx b/web/core/components/common/access-field.tsx index dd7606a3aee..b619dde44fb 100644 --- a/web/core/components/common/access-field.tsx +++ b/web/core/components/common/access-field.tsx @@ -1,6 +1,8 @@ import { LucideIcon } from "lucide-react"; -import { cn } from "@plane/editor"; +// plane ui import { Tooltip } from "@plane/ui"; +// plane utils +import { cn } from "@plane/utils"; type Props = { onChange: (value: number) => void; diff --git a/web/core/components/core/modals/bulk-delete-issues-modal.tsx b/web/core/components/core/modals/bulk-delete-issues-modal.tsx index 1d397a315e0..aec70262ab1 100644 --- a/web/core/components/core/modals/bulk-delete-issues-modal.tsx +++ b/web/core/components/core/modals/bulk-delete-issues-modal.tsx @@ -6,6 +6,7 @@ import { useParams } from "next/navigation"; import { SubmitHandler, useForm } from "react-hook-form"; import { Search } from "lucide-react"; import { Combobox, Dialog, Transition } from "@headlessui/react"; +import { EIssuesStoreType } from "@plane/constants"; // types import { ISearchIssueResponse, IUser } from "@plane/types"; // ui @@ -14,7 +15,6 @@ import { Button, Loader, TOAST_TYPE, setToast } from "@plane/ui"; import { EmptyState } from "@/components/empty-state"; // constants import { EmptyStateType } from "@/constants/empty-state"; -import { EIssuesStoreType } from "@/constants/issue"; // hooks import { useIssues } from "@/hooks/store"; import useDebounce from "@/hooks/use-debounce"; diff --git a/web/core/components/cycles/active-cycle/cycle-stats.tsx b/web/core/components/cycles/active-cycle/cycle-stats.tsx index 6fcdaebd539..44d7b595f48 100644 --- a/web/core/components/cycles/active-cycle/cycle-stats.tsx +++ b/web/core/components/cycles/active-cycle/cycle-stats.tsx @@ -7,6 +7,7 @@ import { CalendarCheck } from "lucide-react"; // headless ui import { Tab } from "@headlessui/react"; // types +import { EIssuesStoreType } from "@plane/constants"; import { ICycle, IIssueFilterOptions } from "@plane/types"; // ui import { Tooltip, Loader, PriorityIcon, Avatar } from "@plane/ui"; @@ -16,7 +17,6 @@ import { StateDropdown } from "@/components/dropdowns"; import { EmptyState } from "@/components/empty-state"; // constants import { EmptyStateType } from "@/constants/empty-state"; -import { EIssuesStoreType } from "@/constants/issue"; // helpers import { cn } from "@/helpers/common.helper"; import { renderFormattedDate, renderFormattedDateWithoutYear } from "@/helpers/date-time.helper"; diff --git a/web/core/components/cycles/active-cycle/use-cycles-details.ts b/web/core/components/cycles/active-cycle/use-cycles-details.ts index cd148705b48..4412319ba37 100644 --- a/web/core/components/cycles/active-cycle/use-cycles-details.ts +++ b/web/core/components/cycles/active-cycle/use-cycles-details.ts @@ -2,9 +2,9 @@ import { useCallback } from "react"; import isEqual from "lodash/isEqual"; import { useRouter } from "next/navigation"; import useSWR from "swr"; +import { EIssueFilterType, EIssuesStoreType } from "@plane/constants"; import { IIssueFilterOptions } from "@plane/types"; import { CYCLE_ISSUES_WITH_PARAMS } from "@/constants/fetch-keys"; -import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; import { useCycle, useIssues } from "@/hooks/store"; interface IActiveCycleDetails { diff --git a/web/core/components/cycles/analytics-sidebar/issue-progress.tsx b/web/core/components/cycles/analytics-sidebar/issue-progress.tsx index d9725d1d66d..0efdaded511 100644 --- a/web/core/components/cycles/analytics-sidebar/issue-progress.tsx +++ b/web/core/components/cycles/analytics-sidebar/issue-progress.tsx @@ -7,11 +7,11 @@ import { observer } from "mobx-react"; import { useSearchParams } from "next/navigation"; import { ChevronUp, ChevronDown } from "lucide-react"; import { Disclosure, Transition } from "@headlessui/react"; +import { EIssueFilterType, EIssuesStoreType } from "@plane/constants"; import { ICycle, IIssueFilterOptions, TCyclePlotType, TProgressSnapshot } from "@plane/types"; // components import { CycleProgressStats } from "@/components/cycles"; // constants -import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; // helpers import { getDate } from "@/helpers/date-time.helper"; // hooks diff --git a/web/core/components/cycles/transfer-issues-modal.tsx b/web/core/components/cycles/transfer-issues-modal.tsx index ae9cf3dac08..1d065bf85bb 100644 --- a/web/core/components/cycles/transfer-issues-modal.tsx +++ b/web/core/components/cycles/transfer-issues-modal.tsx @@ -8,8 +8,8 @@ import { Dialog, Transition } from "@headlessui/react"; // hooks // ui //icons +import { EIssuesStoreType } from "@plane/constants"; import { ContrastIcon, TransferIcon, TOAST_TYPE, setToast } from "@plane/ui"; -import { EIssuesStoreType } from "@/constants/issue"; import { useCycle, useIssues } from "@/hooks/store"; //icons // constants diff --git a/web/core/components/dropdowns/layout.tsx b/web/core/components/dropdowns/layout.tsx index 7864d1849df..9907ab1406f 100644 --- a/web/core/components/dropdowns/layout.tsx +++ b/web/core/components/dropdowns/layout.tsx @@ -1,11 +1,14 @@ import { useCallback, useMemo } from "react"; import { observer } from "mobx-react"; import { Check } from "lucide-react"; -// plane packages -import { cn } from "@plane/editor"; +// plane constants +import { EIssueLayoutTypes } from "@plane/constants"; +// plane ui import { Dropdown } from "@plane/ui"; +// plane utils +import { cn } from "@plane/utils"; // constants -import { EIssueLayoutTypes, ISSUE_LAYOUT_MAP } from "@/constants/issue"; +import { ISSUE_LAYOUT_MAP } from "@/constants/issue"; type TLayoutDropDown = { onChange: (value: EIssueLayoutTypes) => void; diff --git a/web/core/components/dropdowns/member/avatar.tsx b/web/core/components/dropdowns/member/avatar.tsx index 9907de3599e..0b2189f6510 100644 --- a/web/core/components/dropdowns/member/avatar.tsx +++ b/web/core/components/dropdowns/member/avatar.tsx @@ -3,8 +3,9 @@ import { observer } from "mobx-react"; import { LucideIcon, Users } from "lucide-react"; // plane ui -import { cn } from "@plane/editor"; import { Avatar, AvatarGroup } from "@plane/ui"; +// plane utils +import { cn } from "@plane/utils"; // helpers import { getFileURL } from "@/helpers/file.helper"; // hooks diff --git a/web/core/components/editor/lite-text-editor/lite-text-editor.tsx b/web/core/components/editor/lite-text-editor/lite-text-editor.tsx index 57bcbbd2ee3..d1a7b06405d 100644 --- a/web/core/components/editor/lite-text-editor/lite-text-editor.tsx +++ b/web/core/components/editor/lite-text-editor/lite-text-editor.tsx @@ -1,10 +1,10 @@ import React, { useState } from "react"; -// editor +// plane constants +import { EIssueCommentAccessSpecifier } from "@plane/constants"; +// plane editor import { EditorRefApi, ILiteTextEditor, LiteTextEditorWithRef } from "@plane/editor"; // components import { EditorMentionsRoot, IssueCommentToolbar } from "@/components/editor"; -// constants -import { EIssueCommentAccessSpecifier } from "@/constants/issue"; // helpers import { cn } from "@/helpers/common.helper"; import { getEditorFileHandlers } from "@/helpers/editor.helper"; diff --git a/web/core/components/editor/lite-text-editor/toolbar.tsx b/web/core/components/editor/lite-text-editor/toolbar.tsx index 1951a3170e4..643095f1feb 100644 --- a/web/core/components/editor/lite-text-editor/toolbar.tsx +++ b/web/core/components/editor/lite-text-editor/toolbar.tsx @@ -2,13 +2,13 @@ import React, { useEffect, useState, useCallback } from "react"; import { Globe2, Lock, LucideIcon } from "lucide-react"; +import { EIssueCommentAccessSpecifier } from "@plane/constants"; // editor import { EditorRefApi } from "@plane/editor"; // ui import { Button, Tooltip } from "@plane/ui"; // constants import { TOOLBAR_ITEMS, ToolbarMenuItem } from "@/constants/editor"; -import { EIssueCommentAccessSpecifier } from "@/constants/issue"; // helpers import { cn } from "@/helpers/common.helper"; diff --git a/web/core/components/gantt-chart/chart/views/quarter.tsx b/web/core/components/gantt-chart/chart/views/quarter.tsx index 421d0bdfec6..ee1a11c5733 100644 --- a/web/core/components/gantt-chart/chart/views/quarter.tsx +++ b/web/core/components/gantt-chart/chart/views/quarter.tsx @@ -1,7 +1,7 @@ import { FC } from "react"; import { observer } from "mobx-react"; -// Plane -import { cn } from "@plane/editor"; +// plane utils +import { cn } from "@plane/utils"; // hooks import { useTimeLineChartStore } from "@/hooks/use-timeline-chart"; // diff --git a/web/core/components/gantt-chart/chart/views/week.tsx b/web/core/components/gantt-chart/chart/views/week.tsx index 2096acbc2bc..7c38d97ee86 100644 --- a/web/core/components/gantt-chart/chart/views/week.tsx +++ b/web/core/components/gantt-chart/chart/views/week.tsx @@ -1,7 +1,7 @@ import { FC } from "react"; import { observer } from "mobx-react"; -// Plane -import { cn } from "@plane/editor"; +// plane utils +import { cn } from "@plane/utils"; // hooks import { useTimeLineChartStore } from "@/hooks/use-timeline-chart"; // diff --git a/web/core/components/gantt-chart/helpers/blockResizables/left-resizable.tsx b/web/core/components/gantt-chart/helpers/blockResizables/left-resizable.tsx index b5f0de5c157..99b96e786dc 100644 --- a/web/core/components/gantt-chart/helpers/blockResizables/left-resizable.tsx +++ b/web/core/components/gantt-chart/helpers/blockResizables/left-resizable.tsx @@ -1,7 +1,7 @@ import { useState } from "react"; import { observer } from "mobx-react"; -// Plane -import { cn } from "@plane/editor"; +// plane utils +import { cn } from "@plane/utils"; //helpers import { renderFormattedDate } from "@/helpers/date-time.helper"; //hooks diff --git a/web/core/components/gantt-chart/helpers/blockResizables/right-resizable.tsx b/web/core/components/gantt-chart/helpers/blockResizables/right-resizable.tsx index bb262875b59..8370a7630ae 100644 --- a/web/core/components/gantt-chart/helpers/blockResizables/right-resizable.tsx +++ b/web/core/components/gantt-chart/helpers/blockResizables/right-resizable.tsx @@ -1,7 +1,7 @@ import { useState } from "react"; import { observer } from "mobx-react"; -// Plane -import { cn } from "@plane/editor"; +// plane utils +import { cn } from "@plane/utils"; //helpers import { renderFormattedDate } from "@/helpers/date-time.helper"; //hooks diff --git a/web/core/components/global/index.ts b/web/core/components/global/index.ts index 1230b8384fc..bb0ffcec8a1 100644 --- a/web/core/components/global/index.ts +++ b/web/core/components/global/index.ts @@ -1 +1,3 @@ export * from "./product-updates"; + +export * from "./timezone-select"; diff --git a/web/core/components/global/timezone-select.tsx b/web/core/components/global/timezone-select.tsx new file mode 100644 index 00000000000..55b9f5cf186 --- /dev/null +++ b/web/core/components/global/timezone-select.tsx @@ -0,0 +1,53 @@ +"use client"; + +import { FC } from "react"; +import { observer } from "mobx-react"; +import { CustomSearchSelect } from "@plane/ui"; +import { cn } from "@plane/utils"; +// hooks +import useTimezone from "@/hooks/use-timezone"; + +type TTimezoneSelect = { + value: string | undefined; + onChange: (value: string) => void; + error?: boolean; + label?: string; + buttonClassName?: string; + className?: string; + optionsClassName?: string; + disabled?: boolean; +}; + +export const TimezoneSelect: FC = observer((props) => { + // props + const { + value, + onChange, + error = false, + label = "Select a timezone", + buttonClassName = "", + className = "", + optionsClassName = "", + disabled = false, + } = props; + // hooks + const { disabled: isDisabled, timezones, selectedValue } = useTimezone(); + + return ( +
+ +
+ ); +}); diff --git a/web/core/components/inbox/inbox-filter/root.tsx b/web/core/components/inbox/inbox-filter/root.tsx index 04761033106..df4fcf69fb5 100644 --- a/web/core/components/inbox/inbox-filter/root.tsx +++ b/web/core/components/inbox/inbox-filter/root.tsx @@ -1,8 +1,10 @@ import { FC } from "react"; import { ChevronDown, ListFilter } from "lucide-react"; -// components -import { cn } from "@plane/editor"; +// plane ui import { getButtonStyling } from "@plane/ui"; +// plane utils +import { cn } from "@plane/utils"; +// components import { InboxIssueFilterSelection, InboxIssueOrderByDropdown } from "@/components/inbox/inbox-filter"; import { FiltersDropdown } from "@/components/issues"; import useSize from "@/hooks/use-window-size"; diff --git a/web/core/components/issues/archived-issues-header.tsx b/web/core/components/issues/archived-issues-header.tsx index 3926f08720b..e64c651b744 100644 --- a/web/core/components/issues/archived-issues-header.tsx +++ b/web/core/components/issues/archived-issues-header.tsx @@ -1,13 +1,15 @@ import { FC } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; +// plane constants +import { EIssueFilterType, EIssuesStoreType } from "@plane/constants"; // types import type { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions } from "@plane/types"; // components import { ArchiveTabsList } from "@/components/archives"; import { DisplayFiltersSelection, FilterSelection, FiltersDropdown } from "@/components/issues"; // constants -import { EIssueFilterType, EIssuesStoreType, ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "@/constants/issue"; +import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "@/constants/issue"; // helpers import { isIssueFilterActive } from "@/helpers/filter.helper"; // hooks diff --git a/web/core/components/issues/filters.tsx b/web/core/components/issues/filters.tsx index 54b6f501572..f96c582c9a2 100644 --- a/web/core/components/issues/filters.tsx +++ b/web/core/components/issues/filters.tsx @@ -2,13 +2,15 @@ import { useCallback, useState } from "react"; import { observer } from "mobx-react"; +// plane constants +import { EIssueLayoutTypes, EIssueFilterType, EIssuesStoreType } from "@plane/constants"; // types import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions } from "@plane/types"; import { Button } from "@plane/ui"; // components import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "@/components/issues"; // constants -import { EIssueFilterType, EIssueLayoutTypes, EIssuesStoreType, ISSUE_STORE_TO_FILTERS_MAP } from "@/constants/issue"; +import { ISSUE_STORE_TO_FILTERS_MAP } from "@/constants/issue"; // helpers import { isIssueFilterActive } from "@/helpers/filter.helper"; // hooks diff --git a/web/core/components/issues/issue-detail/issue-activity/comments/comment-card.tsx b/web/core/components/issues/issue-detail/issue-activity/comments/comment-card.tsx index 53998f01ba4..b3921d7fa70 100644 --- a/web/core/components/issues/issue-detail/issue-activity/comments/comment-card.tsx +++ b/web/core/components/issues/issue-detail/issue-activity/comments/comment-card.tsx @@ -4,14 +4,13 @@ import { FC, useEffect, useRef, useState } from "react"; import { observer } from "mobx-react"; import { useForm } from "react-hook-form"; import { Check, Globe2, Lock, Pencil, Trash2, X } from "lucide-react"; +import { EIssueCommentAccessSpecifier } from "@plane/constants"; import { EditorReadOnlyRefApi, EditorRefApi } from "@plane/editor"; import { TIssueComment } from "@plane/types"; // ui import { CustomMenu } from "@plane/ui"; // components import { LiteTextEditor, LiteTextReadOnlyEditor } from "@/components/editor"; -// constants -import { EIssueCommentAccessSpecifier } from "@/constants/issue"; // helpers import { isCommentEmpty } from "@/helpers/string.helper"; // hooks diff --git a/web/core/components/issues/issue-detail/issue-activity/comments/comment-create.tsx b/web/core/components/issues/issue-detail/issue-activity/comments/comment-create.tsx index ccaf972566d..7dec4ecadb6 100644 --- a/web/core/components/issues/issue-detail/issue-activity/comments/comment-create.tsx +++ b/web/core/components/issues/issue-detail/issue-activity/comments/comment-create.tsx @@ -1,13 +1,12 @@ import { FC, useRef, useState } from "react"; import { useForm, Controller } from "react-hook-form"; +import { EIssueCommentAccessSpecifier } from "@plane/constants"; // plane editor import { EditorRefApi } from "@plane/editor"; // types import { TIssueComment } from "@plane/types"; // components import { LiteTextEditor } from "@/components/editor"; -// constants -import { EIssueCommentAccessSpecifier } from "@/constants/issue"; // helpers import { cn } from "@/helpers/common.helper"; import { isCommentEmpty } from "@/helpers/string.helper"; diff --git a/web/core/components/issues/issue-detail/issue-detail-quick-actions.tsx b/web/core/components/issues/issue-detail/issue-detail-quick-actions.tsx index e0dedfaa5c1..31858bff15f 100644 --- a/web/core/components/issues/issue-detail/issue-detail-quick-actions.tsx +++ b/web/core/components/issues/issue-detail/issue-detail-quick-actions.tsx @@ -4,12 +4,12 @@ import React, { FC, useState } from "react"; import { observer } from "mobx-react"; import { usePathname } from "next/navigation"; import { ArchiveIcon, ArchiveRestoreIcon, LinkIcon, Trash2 } from "lucide-react"; +import { EIssuesStoreType } from "@plane/constants"; import { TOAST_TYPE, Tooltip, setToast } from "@plane/ui"; // components import { ArchiveIssueModal, DeleteIssueModal, IssueSubscription } from "@/components/issues"; // constants import { ISSUE_ARCHIVED, ISSUE_DELETED } from "@/constants/event-tracker"; -import { EIssuesStoreType } from "@/constants/issue"; import { ARCHIVABLE_STATE_GROUPS } from "@/constants/state"; // helpers import { cn } from "@/helpers/common.helper"; diff --git a/web/core/components/issues/issue-detail/label/select/label-select.tsx b/web/core/components/issues/issue-detail/label/select/label-select.tsx index 39c76180937..0c61feee8ca 100644 --- a/web/core/components/issues/issue-detail/label/select/label-select.tsx +++ b/web/core/components/issues/issue-detail/label/select/label-select.tsx @@ -185,11 +185,18 @@ export const IssueLabelSelect: React.FC = observer((props) => ) : canCreateLabel ? (

{ + if(!query.length) return handleAddLabel(query); }} - className="text-left text-custom-text-200 cursor-pointer" + className={`text-left text-custom-text-200 ${query.length ? "cursor-pointer" : "cursor-default"}`} > - + Add "{query}" to labels + {query.length ? ( + <> + + Add "{query}" to labels + + ) : ( + "Type to add a new label" + )}

) : (

No matching results.

diff --git a/web/core/components/issues/issue-detail/root.tsx b/web/core/components/issues/issue-detail/root.tsx index 24e24792c8e..136edab8e20 100644 --- a/web/core/components/issues/issue-detail/root.tsx +++ b/web/core/components/issues/issue-detail/root.tsx @@ -4,6 +4,7 @@ import { FC, useMemo } from "react"; import { observer } from "mobx-react"; import { usePathname } from "next/navigation"; // types +import { EIssuesStoreType } from "@plane/constants"; import { TIssue } from "@plane/types"; // ui import { TOAST_TYPE, setPromiseToast, setToast } from "@plane/ui"; @@ -12,7 +13,6 @@ import { EmptyState } from "@/components/common"; import { IssueDetailsSidebar, IssuePeekOverview } from "@/components/issues"; // constants import { ISSUE_UPDATED, ISSUE_DELETED, ISSUE_ARCHIVED } from "@/constants/event-tracker"; -import { EIssuesStoreType } from "@/constants/issue"; // hooks import { useAppTheme, useEventTracker, useIssueDetail, useIssues, useUserPermissions } from "@/hooks/store"; import { useAppRouter } from "@/hooks/use-app-router"; diff --git a/web/core/components/issues/issue-layouts/calendar/base-calendar-root.tsx b/web/core/components/issues/issue-layouts/calendar/base-calendar-root.tsx index 0fbcfbfe709..07e124bf0bf 100644 --- a/web/core/components/issues/issue-layouts/calendar/base-calendar-root.tsx +++ b/web/core/components/issues/issue-layouts/calendar/base-calendar-root.tsx @@ -3,13 +3,12 @@ import { FC, useCallback, useEffect } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; -import { EIssueGroupByToServerOptions } from "@plane/constants"; +import { EIssueGroupByToServerOptions, EIssuesStoreType } from "@plane/constants"; import { TGroupedIssues } from "@plane/types"; // components import { TOAST_TYPE, setToast } from "@plane/ui"; import { CalendarChart } from "@/components/issues"; //constants -import { EIssuesStoreType } from "@/constants/issue"; // hooks import { useIssues, useCalendarView, useUserPermissions } from "@/hooks/store"; import { useIssueStoreType } from "@/hooks/use-issue-layout-store"; @@ -38,7 +37,14 @@ interface IBaseCalendarRoot { } export const BaseCalendarRoot = observer((props: IBaseCalendarRoot) => { - const { QuickActions, addIssuesToView, isCompletedCycle = false, viewId, isEpic = false, canEditPropertiesBasedOnProject } = props; + const { + QuickActions, + addIssuesToView, + isCompletedCycle = false, + viewId, + isEpic = false, + canEditPropertiesBasedOnProject, + } = props; // router const { workspaceSlug } = useParams(); diff --git a/web/core/components/issues/issue-layouts/calendar/calendar.tsx b/web/core/components/issues/issue-layouts/calendar/calendar.tsx index 0377f19c463..9a0284f47bc 100644 --- a/web/core/components/issues/issue-layouts/calendar/calendar.tsx +++ b/web/core/components/issues/issue-layouts/calendar/calendar.tsx @@ -4,6 +4,8 @@ import { useEffect, useRef, useState } from "react"; import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine"; import { autoScrollForElements } from "@atlaskit/pragmatic-drag-and-drop-auto-scroll/element"; import { observer } from "mobx-react"; +// plane constants +import { EIssueLayoutTypes, EIssueFilterType, EIssuesStoreType } from "@plane/constants"; // types import type { IIssueDisplayFilterOptions, @@ -21,7 +23,6 @@ import { Spinner } from "@plane/ui"; import { CalendarHeader, CalendarIssueBlocks, CalendarWeekDays, CalendarWeekHeader } from "@/components/issues"; // constants import { MONTHS_LIST } from "@/constants/calendar"; -import { EIssueFilterType, EIssueLayoutTypes, EIssuesStoreType } from "@/constants/issue"; // helpers import { cn } from "@/helpers/common.helper"; import { renderFormattedPayloadDate } from "@/helpers/date-time.helper"; diff --git a/web/core/components/issues/issue-layouts/calendar/dropdowns/options-dropdown.tsx b/web/core/components/issues/issue-layouts/calendar/dropdowns/options-dropdown.tsx index b28959c5b22..9b5b13ce462 100644 --- a/web/core/components/issues/issue-layouts/calendar/dropdowns/options-dropdown.tsx +++ b/web/core/components/issues/issue-layouts/calendar/dropdowns/options-dropdown.tsx @@ -9,6 +9,7 @@ import { Popover, Transition } from "@headlessui/react"; // hooks // ui // icons +import { EIssueFilterType } from "@plane/constants"; import { IIssueDisplayFilterOptions, IIssueDisplayProperties, @@ -20,7 +21,6 @@ import { ToggleSwitch } from "@plane/ui"; // types // constants import { CALENDAR_LAYOUTS } from "@/constants/calendar"; -import { EIssueFilterType } from "@/constants/issue"; import { useCalendarView } from "@/hooks/store"; import useSize from "@/hooks/use-window-size"; import { IProjectEpicsFilter } from "@/plane-web/store/issue/epic"; diff --git a/web/core/components/issues/issue-layouts/calendar/header.tsx b/web/core/components/issues/issue-layouts/calendar/header.tsx index 3c55acf8e4e..a441ff8c165 100644 --- a/web/core/components/issues/issue-layouts/calendar/header.tsx +++ b/web/core/components/issues/issue-layouts/calendar/header.tsx @@ -2,6 +2,7 @@ import { observer } from "mobx-react"; // components import { ChevronLeft, ChevronRight } from "lucide-react"; +import { EIssueFilterType } from "@plane/constants"; import { IIssueDisplayFilterOptions, IIssueDisplayProperties, @@ -11,7 +12,6 @@ import { import { Row } from "@plane/ui"; import { CalendarMonthsDropdown, CalendarOptionsDropdown } from "@/components/issues"; // icons -import { EIssueFilterType } from "@/constants/issue"; import { useCalendarView } from "@/hooks/store/use-calendar-view"; import { IProjectEpicsFilter } from "@/plane-web/store/issue/epic"; import { ICycleIssuesFilter } from "@/store/issue/cycle"; diff --git a/web/core/components/issues/issue-layouts/calendar/quick-add-issue-actions.tsx b/web/core/components/issues/issue-layouts/calendar/quick-add-issue-actions.tsx index 5a1becee227..285285f7aaf 100644 --- a/web/core/components/issues/issue-layouts/calendar/quick-add-issue-actions.tsx +++ b/web/core/components/issues/issue-layouts/calendar/quick-add-issue-actions.tsx @@ -5,6 +5,8 @@ import { differenceInCalendarDays } from "date-fns"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; import { PlusIcon } from "lucide-react"; +// plane constants +import { EIssueLayoutTypes } from "@plane/constants"; // types import { ISearchIssueResponse, TIssue } from "@plane/types"; // ui @@ -13,7 +15,6 @@ import { CustomMenu, setPromiseToast } from "@plane/ui"; import { ExistingIssuesListModal } from "@/components/core"; import { QuickAddIssueRoot } from "@/components/issues"; // helpers -import { EIssueLayoutTypes } from "@/constants/issue"; import { cn } from "@/helpers/common.helper"; // hooks import { useIssueDetail } from "@/hooks/store"; diff --git a/web/core/components/issues/issue-layouts/calendar/roots/cycle-root.tsx b/web/core/components/issues/issue-layouts/calendar/roots/cycle-root.tsx index 8543e85de87..ba85fb80fbf 100644 --- a/web/core/components/issues/issue-layouts/calendar/roots/cycle-root.tsx +++ b/web/core/components/issues/issue-layouts/calendar/roots/cycle-root.tsx @@ -2,8 +2,8 @@ import { useCallback } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; //hooks +import { EIssuesStoreType } from "@plane/constants"; import { CycleIssueQuickActions } from "@/components/issues"; -import { EIssuesStoreType } from "@/constants/issue"; import { useCycle, useIssues } from "@/hooks/store"; // components import { BaseCalendarRoot } from "../base-calendar-root"; diff --git a/web/core/components/issues/issue-layouts/calendar/roots/module-root.tsx b/web/core/components/issues/issue-layouts/calendar/roots/module-root.tsx index aaf746b34f8..296b4c5a3b5 100644 --- a/web/core/components/issues/issue-layouts/calendar/roots/module-root.tsx +++ b/web/core/components/issues/issue-layouts/calendar/roots/module-root.tsx @@ -3,10 +3,10 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // hooks // components +import { EIssuesStoreType } from "@plane/constants"; import { ModuleIssueQuickActions } from "@/components/issues"; // types // constants -import { EIssuesStoreType } from "@/constants/issue"; import { useIssues } from "@/hooks/store"; import { BaseCalendarRoot } from "../base-calendar-root"; diff --git a/web/core/components/issues/issue-layouts/empty-states/archived-issues.tsx b/web/core/components/issues/issue-layouts/empty-states/archived-issues.tsx index 020062e4e35..833a2d6054e 100644 --- a/web/core/components/issues/issue-layouts/empty-states/archived-issues.tsx +++ b/web/core/components/issues/issue-layouts/empty-states/archived-issues.tsx @@ -1,13 +1,13 @@ import size from "lodash/size"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; +import { EIssueFilterType, EIssuesStoreType } from "@plane/constants"; import { IIssueFilterOptions } from "@plane/types"; // hooks // components import { EmptyState } from "@/components/empty-state"; // constants import { EmptyStateType } from "@/constants/empty-state"; -import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; import { useIssues } from "@/hooks/store"; // types diff --git a/web/core/components/issues/issue-layouts/empty-states/cycle.tsx b/web/core/components/issues/issue-layouts/empty-states/cycle.tsx index 1650bfc9892..274aa85883b 100644 --- a/web/core/components/issues/issue-layouts/empty-states/cycle.tsx +++ b/web/core/components/issues/issue-layouts/empty-states/cycle.tsx @@ -6,6 +6,7 @@ import size from "lodash/size"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // types +import { EIssueFilterType, EIssuesStoreType } from "@plane/constants"; import { IIssueFilterOptions, ISearchIssueResponse } from "@plane/types"; // ui import { TOAST_TYPE, setToast } from "@plane/ui"; @@ -14,7 +15,6 @@ import { ExistingIssuesListModal } from "@/components/core"; import { EmptyState } from "@/components/empty-state"; // constants import { EmptyStateType } from "@/constants/empty-state"; -import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; import { useCommandPalette, useCycle, useEventTracker, useIssues } from "@/hooks/store"; export const CycleEmptyState: React.FC = observer(() => { diff --git a/web/core/components/issues/issue-layouts/empty-states/draft-issues.tsx b/web/core/components/issues/issue-layouts/empty-states/draft-issues.tsx index 88eed515c4f..1af3ca5a5c4 100644 --- a/web/core/components/issues/issue-layouts/empty-states/draft-issues.tsx +++ b/web/core/components/issues/issue-layouts/empty-states/draft-issues.tsx @@ -1,13 +1,13 @@ import size from "lodash/size"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; +import { EIssueFilterType, EIssuesStoreType } from "@plane/constants"; import { IIssueFilterOptions } from "@plane/types"; // hooks // components import { EmptyState } from "@/components/empty-state"; // constants import { EmptyStateType } from "@/constants/empty-state"; -import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; import { useIssues } from "@/hooks/store"; // types diff --git a/web/core/components/issues/issue-layouts/empty-states/global-view.tsx b/web/core/components/issues/issue-layouts/empty-states/global-view.tsx index 107770f83c0..8850fe22677 100644 --- a/web/core/components/issues/issue-layouts/empty-states/global-view.tsx +++ b/web/core/components/issues/issue-layouts/empty-states/global-view.tsx @@ -1,10 +1,10 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // components +import { EIssuesStoreType } from "@plane/constants"; import { EmptyState } from "@/components/empty-state"; // constants import { EMPTY_STATE_DETAILS, EmptyStateType } from "@/constants/empty-state"; -import { EIssuesStoreType } from "@/constants/issue"; // hooks import { useCommandPalette, useEventTracker, useProject } from "@/hooks/store"; // assets diff --git a/web/core/components/issues/issue-layouts/empty-states/index.tsx b/web/core/components/issues/issue-layouts/empty-states/index.tsx index e776d29bad2..f2d42152680 100644 --- a/web/core/components/issues/issue-layouts/empty-states/index.tsx +++ b/web/core/components/issues/issue-layouts/empty-states/index.tsx @@ -1,4 +1,4 @@ -import { EIssuesStoreType } from "@/constants/issue"; +import { EIssuesStoreType } from "@plane/constants"; // components import { ProjectArchivedEmptyState } from "./archived-issues"; import { CycleEmptyState } from "./cycle"; diff --git a/web/core/components/issues/issue-layouts/empty-states/module.tsx b/web/core/components/issues/issue-layouts/empty-states/module.tsx index 35ed83e0051..9e8a26955e6 100644 --- a/web/core/components/issues/issue-layouts/empty-states/module.tsx +++ b/web/core/components/issues/issue-layouts/empty-states/module.tsx @@ -5,6 +5,7 @@ import size from "lodash/size"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // types +import { EIssueFilterType, EIssuesStoreType } from "@plane/constants"; import { IIssueFilterOptions, ISearchIssueResponse } from "@plane/types"; // ui import { TOAST_TYPE, setToast } from "@plane/ui"; @@ -13,7 +14,6 @@ import { ExistingIssuesListModal } from "@/components/core"; import { EmptyState } from "@/components/empty-state"; // constants import { EmptyStateType } from "@/constants/empty-state"; -import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; // hooks import { useCommandPalette, useEventTracker, useIssues } from "@/hooks/store"; diff --git a/web/core/components/issues/issue-layouts/empty-states/project-issues.tsx b/web/core/components/issues/issue-layouts/empty-states/project-issues.tsx index 5ec86340d79..5e437357a89 100644 --- a/web/core/components/issues/issue-layouts/empty-states/project-issues.tsx +++ b/web/core/components/issues/issue-layouts/empty-states/project-issues.tsx @@ -2,12 +2,12 @@ import size from "lodash/size"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // types +import { EIssueFilterType, EIssuesStoreType } from "@plane/constants"; import { IIssueFilterOptions } from "@plane/types"; // components import { EmptyState } from "@/components/empty-state"; // constants import { EmptyStateType } from "@/constants/empty-state"; -import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; // hooks import { useCommandPalette, useEventTracker, useIssues } from "@/hooks/store"; diff --git a/web/core/components/issues/issue-layouts/empty-states/project-view.tsx b/web/core/components/issues/issue-layouts/empty-states/project-view.tsx index 160834ea71c..0749d810f27 100644 --- a/web/core/components/issues/issue-layouts/empty-states/project-view.tsx +++ b/web/core/components/issues/issue-layouts/empty-states/project-view.tsx @@ -1,9 +1,9 @@ import { observer } from "mobx-react"; import { PlusIcon } from "lucide-react"; // components +import { EIssuesStoreType } from "@plane/constants"; import { EmptyState } from "@/components/common"; // constants -import { EIssuesStoreType } from "@/constants/issue"; // hooks import { useCommandPalette, useEventTracker, useUserPermissions } from "@/hooks/store"; import { EUserPermissions, EUserPermissionsLevel } from "@/plane-web/constants/user-permissions"; diff --git a/web/core/components/issues/issue-layouts/filters/applied-filters/roots/archived-issue.tsx b/web/core/components/issues/issue-layouts/filters/applied-filters/roots/archived-issue.tsx index 92a9d8db378..91d7207764b 100644 --- a/web/core/components/issues/issue-layouts/filters/applied-filters/roots/archived-issue.tsx +++ b/web/core/components/issues/issue-layouts/filters/applied-filters/roots/archived-issue.tsx @@ -1,9 +1,9 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; +import { EIssueFilterType, EIssuesStoreType } from "@plane/constants"; import { IIssueFilterOptions } from "@plane/types"; // hooks import { AppliedFiltersList } from "@/components/issues"; -import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; import { useIssues, useLabel, useProjectState } from "@/hooks/store"; // components // types diff --git a/web/core/components/issues/issue-layouts/filters/applied-filters/roots/cycle-root.tsx b/web/core/components/issues/issue-layouts/filters/applied-filters/roots/cycle-root.tsx index e9f6302dc15..2628fe41daa 100644 --- a/web/core/components/issues/issue-layouts/filters/applied-filters/roots/cycle-root.tsx +++ b/web/core/components/issues/issue-layouts/filters/applied-filters/roots/cycle-root.tsx @@ -1,10 +1,10 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; +import { EIssueFilterType, EIssuesStoreType } from "@plane/constants"; import { IIssueFilterOptions } from "@plane/types"; // hooks import { Header, EHeaderVariant } from "@plane/ui"; import { AppliedFiltersList, SaveFilterView } from "@/components/issues"; -import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; import { useIssues, useLabel, useProjectState } from "@/hooks/store"; // components // types diff --git a/web/core/components/issues/issue-layouts/filters/applied-filters/roots/draft-issue.tsx b/web/core/components/issues/issue-layouts/filters/applied-filters/roots/draft-issue.tsx index ba0777eea60..a596b4248c0 100644 --- a/web/core/components/issues/issue-layouts/filters/applied-filters/roots/draft-issue.tsx +++ b/web/core/components/issues/issue-layouts/filters/applied-filters/roots/draft-issue.tsx @@ -1,9 +1,9 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; +import { EIssueFilterType, EIssuesStoreType } from "@plane/constants"; import { IIssueFilterOptions } from "@plane/types"; // hooks import { AppliedFiltersList } from "@/components/issues"; -import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; import { useIssues, useLabel, useProjectState } from "@/hooks/store"; // components // types diff --git a/web/core/components/issues/issue-layouts/filters/applied-filters/roots/global-view-root.tsx b/web/core/components/issues/issue-layouts/filters/applied-filters/roots/global-view-root.tsx index 0b1003260fc..c0a5cc1d39e 100644 --- a/web/core/components/issues/issue-layouts/filters/applied-filters/roots/global-view-root.tsx +++ b/web/core/components/issues/issue-layouts/filters/applied-filters/roots/global-view-root.tsx @@ -6,6 +6,7 @@ import isEmpty from "lodash/isEmpty"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // types +import { EIssueFilterType, EIssuesStoreType } from "@plane/constants"; import { IIssueFilterOptions, TStaticViewTypes } from "@plane/types"; //ui // components @@ -15,7 +16,6 @@ import { UpdateViewComponent } from "@/components/views/update-view-component"; import { CreateUpdateWorkspaceViewModal } from "@/components/workspace"; // constants import { GLOBAL_VIEW_UPDATED } from "@/constants/event-tracker"; -import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; import { EViewAccess } from "@/constants/views"; import { DEFAULT_GLOBAL_VIEWS_LIST } from "@/constants/workspace"; // helpers diff --git a/web/core/components/issues/issue-layouts/filters/applied-filters/roots/module-root.tsx b/web/core/components/issues/issue-layouts/filters/applied-filters/roots/module-root.tsx index 13f0fad8ad7..10820d35416 100644 --- a/web/core/components/issues/issue-layouts/filters/applied-filters/roots/module-root.tsx +++ b/web/core/components/issues/issue-layouts/filters/applied-filters/roots/module-root.tsx @@ -1,10 +1,10 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; +import { EIssueFilterType, EIssuesStoreType } from "@plane/constants"; import { IIssueFilterOptions } from "@plane/types"; // hooks import { Header, EHeaderVariant } from "@plane/ui"; import { AppliedFiltersList, SaveFilterView } from "@/components/issues"; -import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; import { useIssues, useLabel, useProjectState } from "@/hooks/store"; // components // types diff --git a/web/core/components/issues/issue-layouts/filters/applied-filters/roots/profile-issues-root.tsx b/web/core/components/issues/issue-layouts/filters/applied-filters/roots/profile-issues-root.tsx index fe1af5fb20d..eebf4fd9d1e 100644 --- a/web/core/components/issues/issue-layouts/filters/applied-filters/roots/profile-issues-root.tsx +++ b/web/core/components/issues/issue-layouts/filters/applied-filters/roots/profile-issues-root.tsx @@ -1,11 +1,11 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; +import { EIssueFilterType, EIssuesStoreType } from "@plane/constants"; import { IIssueFilterOptions } from "@plane/types"; // hooks // components import { AppliedFiltersList } from "@/components/issues"; // types -import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; import { useIssues, useLabel } from "@/hooks/store"; import { useWorkspaceIssueProperties } from "@/hooks/use-workspace-issue-properties"; diff --git a/web/core/components/issues/issue-layouts/filters/applied-filters/roots/project-root.tsx b/web/core/components/issues/issue-layouts/filters/applied-filters/roots/project-root.tsx index 721bad76969..37616a2736d 100644 --- a/web/core/components/issues/issue-layouts/filters/applied-filters/roots/project-root.tsx +++ b/web/core/components/issues/issue-layouts/filters/applied-filters/roots/project-root.tsx @@ -1,13 +1,13 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // types +import { EIssueFilterType, EIssuesStoreType } from "@plane/constants"; import { IIssueFilterOptions } from "@plane/types"; // ui import { Header, EHeaderVariant } from "@plane/ui"; // components import { AppliedFiltersList, SaveFilterView } from "@/components/issues"; // constants -import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; // hooks import { useLabel, useProjectState, useUserPermissions } from "@/hooks/store"; import { useIssues } from "@/hooks/store/use-issues"; diff --git a/web/core/components/issues/issue-layouts/filters/applied-filters/roots/project-view-root.tsx b/web/core/components/issues/issue-layouts/filters/applied-filters/roots/project-view-root.tsx index 395d6044a6f..152ebcc2d3f 100644 --- a/web/core/components/issues/issue-layouts/filters/applied-filters/roots/project-view-root.tsx +++ b/web/core/components/issues/issue-layouts/filters/applied-filters/roots/project-view-root.tsx @@ -6,6 +6,7 @@ import isEmpty from "lodash/isEmpty"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // types +import { EIssueFilterType, EIssuesStoreType } from "@plane/constants"; import { IIssueFilterOptions } from "@plane/types"; // components import { Header, EHeaderVariant } from "@plane/ui"; @@ -13,7 +14,6 @@ import { AppliedFiltersList } from "@/components/issues"; import { CreateUpdateProjectViewModal } from "@/components/views"; import { UpdateViewComponent } from "@/components/views/update-view-component"; // constants -import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; import { EViewAccess } from "@/constants/views"; // hooks import { useIssues, useLabel, useProjectState, useProjectView, useUser, useUserPermissions } from "@/hooks/store"; diff --git a/web/core/components/issues/issue-layouts/filters/header/display-filters/display-filters-selection.tsx b/web/core/components/issues/issue-layouts/filters/header/display-filters/display-filters-selection.tsx index 604b12581f0..cd33525c8e7 100644 --- a/web/core/components/issues/issue-layouts/filters/header/display-filters/display-filters-selection.tsx +++ b/web/core/components/issues/issue-layouts/filters/header/display-filters/display-filters-selection.tsx @@ -1,7 +1,12 @@ import React from "react"; import isEmpty from "lodash/isEmpty"; import { observer } from "mobx-react"; -import { IIssueDisplayFilterOptions, IIssueDisplayProperties, TIssueGroupByOptions } from "@plane/types"; +import { + IIssueDisplayFilterOptions, + IIssueDisplayProperties, + ILayoutDisplayFiltersOptions, + TIssueGroupByOptions, +} from "@plane/types"; // components import { FilterDisplayProperties, @@ -10,8 +15,6 @@ import { FilterOrderBy, FilterSubGroupBy, } from "@/components/issues"; -// types -import { ILayoutDisplayFiltersOptions } from "@/constants/issue"; type Props = { displayFilters: IIssueDisplayFilterOptions | undefined; diff --git a/web/core/components/issues/issue-layouts/filters/header/filters/filters-selection.tsx b/web/core/components/issues/issue-layouts/filters/header/filters/filters-selection.tsx index fb05e7421b7..c45db7f4907 100644 --- a/web/core/components/issues/issue-layouts/filters/header/filters/filters-selection.tsx +++ b/web/core/components/issues/issue-layouts/filters/header/filters/filters-selection.tsx @@ -3,7 +3,13 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; import { Search, X } from "lucide-react"; // types -import { IIssueDisplayFilterOptions, IIssueFilterOptions, IIssueLabel, IState } from "@plane/types"; +import { + IIssueDisplayFilterOptions, + IIssueFilterOptions, + IIssueLabel, + ILayoutDisplayFiltersOptions, + IState, +} from "@plane/types"; // components import { FilterAssignees, @@ -20,8 +26,6 @@ import { FilterModule, FilterIssueGrouping, } from "@/components/issues"; -// constants -import { ILayoutDisplayFiltersOptions } from "@/constants/issue"; // hooks import { usePlatformOS } from "@/hooks/use-platform-os"; // plane web components diff --git a/web/core/components/issues/issue-layouts/filters/header/layout-selection.tsx b/web/core/components/issues/issue-layouts/filters/header/layout-selection.tsx index 6eb8a0c6ad0..9439eea5dcf 100644 --- a/web/core/components/issues/issue-layouts/filters/header/layout-selection.tsx +++ b/web/core/components/issues/issue-layouts/filters/header/layout-selection.tsx @@ -1,12 +1,13 @@ "use client"; import React from "react"; - +// plane constants +import { EIssueLayoutTypes } from "@plane/constants"; // ui import { Tooltip } from "@plane/ui"; // types // constants -import { EIssueLayoutTypes, ISSUE_LAYOUTS } from "@/constants/issue"; +import { ISSUE_LAYOUTS } from "@/constants/issue"; import { usePlatformOS } from "@/hooks/use-platform-os"; // hooks diff --git a/web/core/components/issues/issue-layouts/gantt/base-gantt-root.tsx b/web/core/components/issues/issue-layouts/gantt/base-gantt-root.tsx index 5e5ec1db8e2..c0c97a22ac0 100644 --- a/web/core/components/issues/issue-layouts/gantt/base-gantt-root.tsx +++ b/web/core/components/issues/issue-layouts/gantt/base-gantt-root.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useEffect } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // plane constants -import { ALL_ISSUES } from "@plane/constants"; +import { ALL_ISSUES, EIssueLayoutTypes, EIssuesStoreType } from "@plane/constants"; import { TIssue } from "@plane/types"; import { setToast, TOAST_TYPE } from "@plane/ui"; // hooks @@ -10,7 +10,6 @@ import { GanttChartRoot, IBlockUpdateData, IssueGanttSidebar } from "@/component import { ETimeLineTypeType, TimeLineTypeContext } from "@/components/gantt-chart/contexts"; import { QuickAddIssueRoot, IssueGanttBlock, GanttQuickAddIssueButton } from "@/components/issues"; //constants -import { EIssueLayoutTypes, EIssuesStoreType } from "@/constants/issue"; // helpers import { renderFormattedPayloadDate } from "@/helpers/date-time.helper"; //hooks diff --git a/web/core/components/issues/issue-layouts/issue-layout-HOC.tsx b/web/core/components/issues/issue-layouts/issue-layout-HOC.tsx index be911f75743..24cf204f992 100644 --- a/web/core/components/issues/issue-layouts/issue-layout-HOC.tsx +++ b/web/core/components/issues/issue-layouts/issue-layout-HOC.tsx @@ -1,4 +1,6 @@ import { observer } from "mobx-react"; +// plane constants +import { EIssueLayoutTypes } from "@plane/constants"; import { CalendarLayoutLoader, GanttLayoutLoader, @@ -6,7 +8,6 @@ import { ListLayoutLoader, SpreadsheetLayoutLoader, } from "@/components/ui"; -import { EIssueLayoutTypes } from "@/constants/issue"; import { useIssues } from "@/hooks/store"; import { useIssueStoreType } from "@/hooks/use-issue-layout-store"; import { IssueLayoutEmptyState } from "./empty-states"; diff --git a/web/core/components/issues/issue-layouts/kanban/base-kanban-root.tsx b/web/core/components/issues/issue-layouts/kanban/base-kanban-root.tsx index 396b1df0d51..2fc8e1c2394 100644 --- a/web/core/components/issues/issue-layouts/kanban/base-kanban-root.tsx +++ b/web/core/components/issues/issue-layouts/kanban/base-kanban-root.tsx @@ -6,11 +6,10 @@ import { dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element import { autoScrollForElements } from "@atlaskit/pragmatic-drag-and-drop-auto-scroll/element"; import { observer } from "mobx-react"; import { useParams, usePathname } from "next/navigation"; -import { EIssueServiceType } from "@plane/constants"; +import { EIssueLayoutTypes, EIssueServiceType, EIssueFilterType, EIssuesStoreType } from "@plane/constants"; import { DeleteIssueModal } from "@/components/issues"; //constants import { ISSUE_DELETED } from "@/constants/event-tracker"; -import { EIssueFilterType, EIssueLayoutTypes, EIssuesStoreType } from "@/constants/issue"; //hooks import { useEventTracker, useIssueDetail, useIssues, useKanbanView, useUserPermissions } from "@/hooks/store"; import { useGroupIssuesDragNDrop } from "@/hooks/use-group-dragndrop"; diff --git a/web/core/components/issues/issue-layouts/kanban/kanban-group.tsx b/web/core/components/issues/issue-layouts/kanban/kanban-group.tsx index 0bee738b6f2..7e1a2f02875 100644 --- a/web/core/components/issues/issue-layouts/kanban/kanban-group.tsx +++ b/web/core/components/issues/issue-layouts/kanban/kanban-group.tsx @@ -5,6 +5,8 @@ import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine"; import { dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter"; import { autoScrollForElements } from "@atlaskit/pragmatic-drag-and-drop-auto-scroll/element"; import { observer } from "mobx-react"; +// plane constants +import { EIssueLayoutTypes } from "@plane/constants"; //types import { TGroupedIssues, @@ -20,7 +22,7 @@ import { KanbanQuickAddIssueButton, QuickAddIssueRoot } from "@/components/issue import { highlightIssueOnDrop } from "@/components/issues/issue-layouts/utils"; import { KanbanIssueBlockLoader } from "@/components/ui"; // helpers -import { DRAG_ALLOWED_GROUPS, EIssueLayoutTypes } from "@/constants/issue"; +import { DRAG_ALLOWED_GROUPS } from "@/constants/issue"; import { cn } from "@/helpers/common.helper"; // hooks import { useProjectState } from "@/hooks/store"; diff --git a/web/core/components/issues/issue-layouts/kanban/roots/cycle-root.tsx b/web/core/components/issues/issue-layouts/kanban/roots/cycle-root.tsx index 591947978c4..c16e3ec2f3a 100644 --- a/web/core/components/issues/issue-layouts/kanban/roots/cycle-root.tsx +++ b/web/core/components/issues/issue-layouts/kanban/roots/cycle-root.tsx @@ -2,9 +2,9 @@ import React, { useCallback } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // components +import { EIssuesStoreType } from "@plane/constants"; import { CycleIssueQuickActions } from "@/components/issues"; // constants -import { EIssuesStoreType } from "@/constants/issue"; // hooks import { useCycle, useIssues, useUserPermissions } from "@/hooks/store"; import { EUserPermissions, EUserPermissionsLevel } from "@/plane-web/constants/user-permissions"; diff --git a/web/core/components/issues/issue-layouts/kanban/roots/module-root.tsx b/web/core/components/issues/issue-layouts/kanban/roots/module-root.tsx index fb1e360d8ae..0e46fc50567 100644 --- a/web/core/components/issues/issue-layouts/kanban/roots/module-root.tsx +++ b/web/core/components/issues/issue-layouts/kanban/roots/module-root.tsx @@ -2,8 +2,8 @@ import React from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // hook +import { EIssuesStoreType } from "@plane/constants"; import { ModuleIssueQuickActions } from "@/components/issues"; -import { EIssuesStoreType } from "@/constants/issue"; import { useIssues } from "@/hooks/store"; // components // types diff --git a/web/core/components/issues/issue-layouts/list/base-list-root.tsx b/web/core/components/issues/issue-layouts/list/base-list-root.tsx index ff49ec668ee..68f7d98595f 100644 --- a/web/core/components/issues/issue-layouts/list/base-list-root.tsx +++ b/web/core/components/issues/issue-layouts/list/base-list-root.tsx @@ -1,10 +1,11 @@ import { FC, useCallback, useEffect } from "react"; import { observer } from "mobx-react"; -// types import { useParams } from "next/navigation"; +// plane constants +import { EIssueLayoutTypes, EIssueFilterType, EIssuesStoreType } from "@plane/constants"; +// types import { GroupByColumnTypes, TGroupedIssues, TIssueKanbanFilters } from "@plane/types"; // constants -import { EIssueFilterType, EIssueLayoutTypes, EIssuesStoreType } from "@/constants/issue"; // hooks import { useIssues, useUserPermissions } from "@/hooks/store"; // hooks diff --git a/web/core/components/issues/issue-layouts/list/list-group.tsx b/web/core/components/issues/issue-layouts/list/list-group.tsx index 7e8f3d29128..1e3413662bb 100644 --- a/web/core/components/issues/issue-layouts/list/list-group.tsx +++ b/web/core/components/issues/issue-layouts/list/list-group.tsx @@ -4,8 +4,9 @@ import { MutableRefObject, useEffect, useRef, useState } from "react"; import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine"; import { dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter"; import { observer } from "mobx-react"; -import { cn } from "@plane/editor"; -// plane packages +// plane constants +import { EIssueLayoutTypes } from "@plane/constants"; +// plane ui import { IGroupByColumn, TIssueMap, @@ -16,10 +17,12 @@ import { TIssueKanbanFilters, } from "@plane/types"; import { Row, setToast, TOAST_TYPE } from "@plane/ui"; +// plane utils +import { cn } from "@plane/utils"; // components import { ListLoaderItemRow } from "@/components/ui"; // constants -import { DRAG_ALLOWED_GROUPS, EIssueLayoutTypes } from "@/constants/issue"; +import { DRAG_ALLOWED_GROUPS } from "@/constants/issue"; // hooks import { useProjectState } from "@/hooks/store"; import { useIntersectionObserver } from "@/hooks/use-intersection-observer"; diff --git a/web/core/components/issues/issue-layouts/list/roots/cycle-root.tsx b/web/core/components/issues/issue-layouts/list/roots/cycle-root.tsx index 12c604ee607..21ab26e7887 100644 --- a/web/core/components/issues/issue-layouts/list/roots/cycle-root.tsx +++ b/web/core/components/issues/issue-layouts/list/roots/cycle-root.tsx @@ -2,9 +2,9 @@ import React, { useCallback } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // components +import { EIssuesStoreType } from "@plane/constants"; import { CycleIssueQuickActions } from "@/components/issues"; // constants -import { EIssuesStoreType } from "@/constants/issue"; // hooks import { useCycle, useIssues, useUserPermissions } from "@/hooks/store"; import { EUserPermissions, EUserPermissionsLevel } from "@/plane-web/constants/user-permissions"; diff --git a/web/core/components/issues/issue-layouts/list/roots/module-root.tsx b/web/core/components/issues/issue-layouts/list/roots/module-root.tsx index 66c5109d1dc..257a6be977f 100644 --- a/web/core/components/issues/issue-layouts/list/roots/module-root.tsx +++ b/web/core/components/issues/issue-layouts/list/roots/module-root.tsx @@ -2,8 +2,8 @@ import React from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // mobx store +import { EIssuesStoreType } from "@plane/constants"; import { ModuleIssueQuickActions } from "@/components/issues"; -import { EIssuesStoreType } from "@/constants/issue"; import { useIssues } from "@/hooks/store"; // components // types diff --git a/web/core/components/issues/issue-layouts/properties/labels.tsx b/web/core/components/issues/issue-layouts/properties/labels.tsx index 56f9b651bef..697bf376b71 100644 --- a/web/core/components/issues/issue-layouts/properties/labels.tsx +++ b/web/core/components/issues/issue-layouts/properties/labels.tsx @@ -341,11 +341,18 @@ export const IssuePropertyLabels: React.FC = observer((pro ) : canCreateLabel ? (

{ + if (!query.length) return; handleAddLabel(query); }} - className="text-left text-custom-text-200 cursor-pointer" + className={`text-left text-custom-text-200 ${query.length ? "cursor-pointer" : "cursor-default"}`} > - + Add "{query}" to labels + {query.length ? ( + <> + + Add "{query}" to labels + + ) : ( + "Type to add a new label" + )}

) : (

No matching results.

diff --git a/web/core/components/issues/issue-layouts/quick-action-dropdowns/all-issue.tsx b/web/core/components/issues/issue-layouts/quick-action-dropdowns/all-issue.tsx index 9ecbe44d0f0..f7bce8e7219 100644 --- a/web/core/components/issues/issue-layouts/quick-action-dropdowns/all-issue.tsx +++ b/web/core/components/issues/issue-layouts/quick-action-dropdowns/all-issue.tsx @@ -6,13 +6,13 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; import { Copy, ExternalLink, Link, Pencil, Trash2 } from "lucide-react"; // types +import { EIssuesStoreType } from "@plane/constants"; import { TIssue } from "@plane/types"; // ui import { ArchiveIcon, ContextMenu, CustomMenu, TContextMenuItem, TOAST_TYPE, setToast } from "@plane/ui"; // components import { ArchiveIssueModal, CreateUpdateIssueModal, DeleteIssueModal } from "@/components/issues"; // constants -import { EIssuesStoreType } from "@/constants/issue"; import { ARCHIVABLE_STATE_GROUPS } from "@/constants/state"; // helpers import { cn } from "@/helpers/common.helper"; diff --git a/web/core/components/issues/issue-layouts/quick-action-dropdowns/archived-issue.tsx b/web/core/components/issues/issue-layouts/quick-action-dropdowns/archived-issue.tsx index e6349fac818..1428a3f0e52 100644 --- a/web/core/components/issues/issue-layouts/quick-action-dropdowns/archived-issue.tsx +++ b/web/core/components/issues/issue-layouts/quick-action-dropdowns/archived-issue.tsx @@ -6,11 +6,11 @@ import { useParams } from "next/navigation"; // icons import { ArchiveRestoreIcon, ExternalLink, Link, Trash2 } from "lucide-react"; // ui +import { EIssuesStoreType } from "@plane/constants"; import { ContextMenu, CustomMenu, TContextMenuItem, TOAST_TYPE, setToast } from "@plane/ui"; // components import { DeleteIssueModal } from "@/components/issues"; // constants -import { EIssuesStoreType } from "@/constants/issue"; // helpers import { cn } from "@/helpers/common.helper"; import { copyUrlToClipboard } from "@/helpers/string.helper"; diff --git a/web/core/components/issues/issue-layouts/quick-action-dropdowns/cycle-issue.tsx b/web/core/components/issues/issue-layouts/quick-action-dropdowns/cycle-issue.tsx index 3f455f990ba..dff81f55f2e 100644 --- a/web/core/components/issues/issue-layouts/quick-action-dropdowns/cycle-issue.tsx +++ b/web/core/components/issues/issue-layouts/quick-action-dropdowns/cycle-issue.tsx @@ -6,13 +6,13 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; import { Copy, ExternalLink, Link, Pencil, Trash2, XCircle } from "lucide-react"; // types +import { EIssuesStoreType } from "@plane/constants"; import { TIssue } from "@plane/types"; // ui import { ArchiveIcon, ContextMenu, CustomMenu, TContextMenuItem, TOAST_TYPE, setToast } from "@plane/ui"; // components import { ArchiveIssueModal, CreateUpdateIssueModal, DeleteIssueModal } from "@/components/issues"; // constants -import { EIssuesStoreType } from "@/constants/issue"; import { ARCHIVABLE_STATE_GROUPS } from "@/constants/state"; // helpers import { cn } from "@/helpers/common.helper"; diff --git a/web/core/components/issues/issue-layouts/quick-action-dropdowns/draft-issue.tsx b/web/core/components/issues/issue-layouts/quick-action-dropdowns/draft-issue.tsx index d9bc00c5fce..f9fd1ab1c52 100644 --- a/web/core/components/issues/issue-layouts/quick-action-dropdowns/draft-issue.tsx +++ b/web/core/components/issues/issue-layouts/quick-action-dropdowns/draft-issue.tsx @@ -6,13 +6,13 @@ import { observer } from "mobx-react"; // icons import { Pencil, Trash2 } from "lucide-react"; // types +import { EIssuesStoreType } from "@plane/constants"; import { TIssue } from "@plane/types"; // ui import { ContextMenu, CustomMenu, TContextMenuItem } from "@plane/ui"; // components import { CreateUpdateIssueModal, DeleteIssueModal } from "@/components/issues"; // constant -import { EIssuesStoreType } from "@/constants/issue"; // helpers import { cn } from "@/helpers/common.helper"; // hooks diff --git a/web/core/components/issues/issue-layouts/quick-action-dropdowns/module-issue.tsx b/web/core/components/issues/issue-layouts/quick-action-dropdowns/module-issue.tsx index c4ce4ce526d..c6c8e691eca 100644 --- a/web/core/components/issues/issue-layouts/quick-action-dropdowns/module-issue.tsx +++ b/web/core/components/issues/issue-layouts/quick-action-dropdowns/module-issue.tsx @@ -6,13 +6,13 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; import { Copy, ExternalLink, Link, Pencil, Trash2, XCircle } from "lucide-react"; // types +import { EIssuesStoreType } from "@plane/constants"; import { TIssue } from "@plane/types"; // ui import { ArchiveIcon, ContextMenu, CustomMenu, TContextMenuItem, TOAST_TYPE, setToast } from "@plane/ui"; // components import { ArchiveIssueModal, CreateUpdateIssueModal, DeleteIssueModal } from "@/components/issues"; // constants -import { EIssuesStoreType } from "@/constants/issue"; import { ARCHIVABLE_STATE_GROUPS } from "@/constants/state"; // helpers import { cn } from "@/helpers/common.helper"; diff --git a/web/core/components/issues/issue-layouts/quick-action-dropdowns/project-issue.tsx b/web/core/components/issues/issue-layouts/quick-action-dropdowns/project-issue.tsx index 378585e4bfc..f9f5c88d7a5 100644 --- a/web/core/components/issues/issue-layouts/quick-action-dropdowns/project-issue.tsx +++ b/web/core/components/issues/issue-layouts/quick-action-dropdowns/project-issue.tsx @@ -6,13 +6,13 @@ import { observer } from "mobx-react"; import { useParams, usePathname } from "next/navigation"; import { Copy, ExternalLink, Link, Pencil, Trash2 } from "lucide-react"; // types +import { EIssuesStoreType } from "@plane/constants"; import { TIssue } from "@plane/types"; // ui import { ArchiveIcon, ContextMenu, CustomMenu, TContextMenuItem, TOAST_TYPE, setToast } from "@plane/ui"; // components import { ArchiveIssueModal, CreateUpdateIssueModal, DeleteIssueModal } from "@/components/issues"; // constants -import { EIssuesStoreType } from "@/constants/issue"; import { ARCHIVABLE_STATE_GROUPS } from "@/constants/state"; // helpers import { cn } from "@/helpers/common.helper"; diff --git a/web/core/components/issues/issue-layouts/quick-add/root.tsx b/web/core/components/issues/issue-layouts/quick-add/root.tsx index 4cdf2e8c092..61575fb23b3 100644 --- a/web/core/components/issues/issue-layouts/quick-add/root.tsx +++ b/web/core/components/issues/issue-layouts/quick-add/root.tsx @@ -5,6 +5,8 @@ import { observer } from "mobx-react"; import { useParams, usePathname } from "next/navigation"; import { useForm, UseFormRegister } from "react-hook-form"; import { PlusIcon } from "lucide-react"; +// plane constants +import { EIssueLayoutTypes } from "@plane/constants"; // types import { IProject, TIssue } from "@plane/types"; // ui @@ -13,7 +15,6 @@ import { setPromiseToast } from "@plane/ui"; import { CreateIssueToastActionItems } from "@/components/issues"; // constants import { ISSUE_CREATED } from "@/constants/event-tracker"; -import { EIssueLayoutTypes } from "@/constants/issue"; // helpers import { cn } from "@/helpers/common.helper"; import { createIssuePayload } from "@/helpers/issue.helper"; diff --git a/web/core/components/issues/issue-layouts/roots/all-issue-layout-root.tsx b/web/core/components/issues/issue-layouts/roots/all-issue-layout-root.tsx index d9d6e45f9f6..25d529e93e6 100644 --- a/web/core/components/issues/issue-layouts/roots/all-issue-layout-root.tsx +++ b/web/core/components/issues/issue-layouts/roots/all-issue-layout-root.tsx @@ -4,7 +4,7 @@ import { observer } from "mobx-react"; import { useParams, useSearchParams } from "next/navigation"; import useSWR from "swr"; // plane constants -import { ALL_ISSUES } from "@plane/constants"; +import { ALL_ISSUES, EIssueLayoutTypes, EIssueFilterType, EIssuesStoreType } from "@plane/constants"; import { IIssueDisplayFilterOptions } from "@plane/types"; // hooks // components @@ -13,12 +13,7 @@ import { SpreadsheetView } from "@/components/issues/issue-layouts"; import { AllIssueQuickActions } from "@/components/issues/issue-layouts/quick-action-dropdowns"; import { SpreadsheetLayoutLoader } from "@/components/ui"; // constants -import { - EIssueFilterType, - EIssueLayoutTypes, - EIssuesStoreType, - ISSUE_DISPLAY_FILTERS_BY_LAYOUT, -} from "@/constants/issue"; +import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "@/constants/issue"; // hooks import { useGlobalView, useIssues, useUserPermissions } from "@/hooks/store"; import { useAppRouter } from "@/hooks/use-app-router"; diff --git a/web/core/components/issues/issue-layouts/roots/archived-issue-layout-root.tsx b/web/core/components/issues/issue-layouts/roots/archived-issue-layout-root.tsx index 7e94dbfbe99..86f299ef280 100644 --- a/web/core/components/issues/issue-layouts/roots/archived-issue-layout-root.tsx +++ b/web/core/components/issues/issue-layouts/roots/archived-issue-layout-root.tsx @@ -4,9 +4,9 @@ import { useParams } from "next/navigation"; import useSWR from "swr"; // mobx store // components +import { EIssuesStoreType } from "@plane/constants"; import { LogoSpinner } from "@/components/common"; import { ArchivedIssueListLayout, ArchivedIssueAppliedFiltersRoot, IssuePeekOverview } from "@/components/issues"; -import { EIssuesStoreType } from "@/constants/issue"; // ui import { useIssues } from "@/hooks/store"; import { IssuesStoreContext } from "@/hooks/use-issue-layout-store"; diff --git a/web/core/components/issues/issue-layouts/roots/cycle-layout-root.tsx b/web/core/components/issues/issue-layouts/roots/cycle-layout-root.tsx index 1b69156ba11..8d35494e4a1 100644 --- a/web/core/components/issues/issue-layouts/roots/cycle-layout-root.tsx +++ b/web/core/components/issues/issue-layouts/roots/cycle-layout-root.tsx @@ -3,7 +3,8 @@ import isEmpty from "lodash/isEmpty"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; import useSWR from "swr"; -// hooks +// plane constants +import { EIssueLayoutTypes, EIssuesStoreType } from "@plane/constants"; // components import { LogoSpinner } from "@/components/common"; import { TransferIssues, TransferIssuesModal } from "@/components/cycles"; @@ -17,7 +18,6 @@ import { IssuePeekOverview, } from "@/components/issues"; // constants -import { EIssueLayoutTypes, EIssuesStoreType } from "@/constants/issue"; // hooks import { useCycle, useIssues } from "@/hooks/store"; import { IssuesStoreContext } from "@/hooks/use-issue-layout-store"; diff --git a/web/core/components/issues/issue-layouts/roots/draft-issue-layout-root.tsx b/web/core/components/issues/issue-layouts/roots/draft-issue-layout-root.tsx index c13ff104e16..13597c5789b 100644 --- a/web/core/components/issues/issue-layouts/roots/draft-issue-layout-root.tsx +++ b/web/core/components/issues/issue-layouts/roots/draft-issue-layout-root.tsx @@ -2,9 +2,11 @@ import React from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; import useSWR from "swr"; +// plane constants +import { EIssueLayoutTypes, EIssuesStoreType } from "@plane/constants"; +// components import { LogoSpinner } from "@/components/common"; import { IssuePeekOverview } from "@/components/issues/peek-overview"; -import { EIssueLayoutTypes, EIssuesStoreType } from "@/constants/issue"; // hooks import { useIssues } from "@/hooks/store"; import { IssuesStoreContext } from "@/hooks/use-issue-layout-store"; diff --git a/web/core/components/issues/issue-layouts/roots/module-layout-root.tsx b/web/core/components/issues/issue-layouts/roots/module-layout-root.tsx index b4eb7c464cd..f64f28cc755 100644 --- a/web/core/components/issues/issue-layouts/roots/module-layout-root.tsx +++ b/web/core/components/issues/issue-layouts/roots/module-layout-root.tsx @@ -2,7 +2,8 @@ import React from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; import useSWR from "swr"; -// mobx store +// plane constants +import { EIssueLayoutTypes, EIssuesStoreType } from "@plane/constants"; // components import { Row, ERowVariant } from "@plane/ui"; import { LogoSpinner } from "@/components/common"; @@ -16,7 +17,6 @@ import { ModuleSpreadsheetLayout, } from "@/components/issues"; // constants -import { EIssueLayoutTypes, EIssuesStoreType } from "@/constants/issue"; import { useIssues } from "@/hooks/store"; import { IssuesStoreContext } from "@/hooks/use-issue-layout-store"; // types diff --git a/web/core/components/issues/issue-layouts/roots/project-layout-root.tsx b/web/core/components/issues/issue-layouts/roots/project-layout-root.tsx index 853f13dd4f2..4007468dc20 100644 --- a/web/core/components/issues/issue-layouts/roots/project-layout-root.tsx +++ b/web/core/components/issues/issue-layouts/roots/project-layout-root.tsx @@ -4,6 +4,8 @@ import { FC, Fragment } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; import useSWR from "swr"; +// plane constants +import { EIssueLayoutTypes, EIssuesStoreType } from "@plane/constants"; // components import { Spinner } from "@plane/ui"; import { LogoSpinner } from "@/components/common"; @@ -16,8 +18,6 @@ import { ProjectSpreadsheetLayout, IssuePeekOverview, } from "@/components/issues"; -// constants -import { EIssueLayoutTypes, EIssuesStoreType } from "@/constants/issue"; // hooks import { useIssues } from "@/hooks/store"; import { IssuesStoreContext } from "@/hooks/use-issue-layout-store"; diff --git a/web/core/components/issues/issue-layouts/roots/project-view-layout-root.tsx b/web/core/components/issues/issue-layouts/roots/project-view-layout-root.tsx index 8c84417578d..fd0a54a3191 100644 --- a/web/core/components/issues/issue-layouts/roots/project-view-layout-root.tsx +++ b/web/core/components/issues/issue-layouts/roots/project-view-layout-root.tsx @@ -2,7 +2,8 @@ import React from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; import useSWR from "swr"; -// mobx store +// plane constants +import { EIssueLayoutTypes, EIssuesStoreType } from "@plane/constants"; // components import { LogoSpinner } from "@/components/common"; import { @@ -14,8 +15,6 @@ import { ProjectViewListLayout, ProjectViewSpreadsheetLayout, } from "@/components/issues"; -// constants -import { EIssueLayoutTypes, EIssuesStoreType } from "@/constants/issue"; import { useIssues } from "@/hooks/store"; import { IssuesStoreContext } from "@/hooks/use-issue-layout-store"; // types diff --git a/web/core/components/issues/issue-layouts/spreadsheet/base-spreadsheet-root.tsx b/web/core/components/issues/issue-layouts/spreadsheet/base-spreadsheet-root.tsx index b7bd6d9f134..5a681fd8330 100644 --- a/web/core/components/issues/issue-layouts/spreadsheet/base-spreadsheet-root.tsx +++ b/web/core/components/issues/issue-layouts/spreadsheet/base-spreadsheet-root.tsx @@ -2,11 +2,9 @@ import { FC, useCallback, useEffect } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // plane constants -import { ALL_ISSUES } from "@plane/constants"; +import { ALL_ISSUES, EIssueLayoutTypes, EIssuesStoreType, EIssueFilterType } from "@plane/constants"; import { IIssueDisplayFilterOptions } from "@plane/types"; // hooks -import { EIssueFilterType, EIssueLayoutTypes, EIssuesStoreType } from "@/constants/issue"; -// hooks import { useIssues, useUserPermissions } from "@/hooks/store"; import { useIssueStoreType } from "@/hooks/use-issue-layout-store"; import { useIssuesActions } from "@/hooks/use-issues-actions"; diff --git a/web/core/components/issues/issue-layouts/spreadsheet/spreadsheet-view.tsx b/web/core/components/issues/issue-layouts/spreadsheet/spreadsheet-view.tsx index 26c7881112d..6d70b923f27 100644 --- a/web/core/components/issues/issue-layouts/spreadsheet/spreadsheet-view.tsx +++ b/web/core/components/issues/issue-layouts/spreadsheet/spreadsheet-view.tsx @@ -1,13 +1,13 @@ import React, { useRef } from "react"; import { observer } from "mobx-react"; +// plane constants +import { EIssueLayoutTypes } from "@plane/constants"; // types import { TIssue, IIssueDisplayFilterOptions, IIssueDisplayProperties } from "@plane/types"; // components import { LogoSpinner } from "@/components/common"; import { MultipleSelectGroup } from "@/components/core"; import { QuickAddIssueRoot, SpreadsheetAddIssueButton } from "@/components/issues"; -// constants -import { EIssueLayoutTypes } from "@/constants/issue"; import { SPREADSHEET_PROPERTY_LIST, SPREADSHEET_SELECT_GROUP } from "@/constants/spreadsheet"; // hooks import { useProject } from "@/hooks/store"; diff --git a/web/core/components/issues/issue-layouts/utils.tsx b/web/core/components/issues/issue-layouts/utils.tsx index 2cb20814cee..3e7d72b1bd0 100644 --- a/web/core/components/issues/issue-layouts/utils.tsx +++ b/web/core/components/issues/issue-layouts/utils.tsx @@ -11,6 +11,7 @@ import uniq from "lodash/uniq"; import scrollIntoView from "smooth-scroll-into-view-if-needed"; import { ContrastIcon } from "lucide-react"; // plane types +import { EIssuesStoreType } from "@plane/constants"; import { GroupByColumnTypes, IGroupByColumn, @@ -30,7 +31,7 @@ import { Avatar, CycleGroupIcon, DiceIcon, PriorityIcon, StateGroupIcon } from " // components import { Logo } from "@/components/common"; // constants -import { ISSUE_PRIORITIES, EIssuesStoreType } from "@/constants/issue"; +import { ISSUE_PRIORITIES } from "@/constants/issue"; import { STATE_GROUPS } from "@/constants/state"; // helpers import { renderFormattedDate } from "@/helpers/date-time.helper"; diff --git a/web/core/components/issues/issue-modal/base.tsx b/web/core/components/issues/issue-modal/base.tsx index 2a9d4abe1ce..116b22e77b5 100644 --- a/web/core/components/issues/issue-modal/base.tsx +++ b/web/core/components/issues/issue-modal/base.tsx @@ -4,13 +4,13 @@ import React, { useEffect, useRef, useState } from "react"; import { observer } from "mobx-react"; import { useParams, usePathname } from "next/navigation"; // types +import { EIssuesStoreType } from "@plane/constants"; import type { TBaseIssue, TIssue } from "@plane/types"; // ui import { EModalPosition, EModalWidth, ModalCore, TOAST_TYPE, setToast } from "@plane/ui"; import { CreateIssueToastActionItems, IssuesModalProps } from "@/components/issues"; // constants import { ISSUE_CREATED, ISSUE_UPDATED } from "@/constants/event-tracker"; -import { EIssuesStoreType } from "@/constants/issue"; // hooks import { useIssueModal } from "@/hooks/context/use-issue-modal"; import { useEventTracker, useCycle, useIssues, useModule, useIssueDetail, useUser } from "@/hooks/store"; @@ -187,19 +187,21 @@ export const CreateUpdateIssueModalBase: React.FC = observer(( if (!response) throw new Error(); // check if we should add issue to cycle/module - if ( - payload.cycle_id && - payload.cycle_id !== "" && - (payload.cycle_id !== cycleId || storeType !== EIssuesStoreType.CYCLE) - ) { - await addIssueToCycle(response, payload.cycle_id); - } - if ( - payload.module_ids && - payload.module_ids.length > 0 && - (!payload.module_ids.includes(moduleId?.toString()) || storeType !== EIssuesStoreType.MODULE) - ) { - await addIssueToModule(response, payload.module_ids); + if (!is_draft_issue) { + if ( + payload.cycle_id && + payload.cycle_id !== "" && + (payload.cycle_id !== cycleId || storeType !== EIssuesStoreType.CYCLE) + ) { + await addIssueToCycle(response, payload.cycle_id); + } + if ( + payload.module_ids && + payload.module_ids.length > 0 && + (!payload.module_ids.includes(moduleId?.toString()) || storeType !== EIssuesStoreType.MODULE) + ) { + await addIssueToModule(response, payload.module_ids); + } } // add other property values diff --git a/web/core/components/issues/issue-modal/form.tsx b/web/core/components/issues/issue-modal/form.tsx index 48e12a377be..86d260c3e92 100644 --- a/web/core/components/issues/issue-modal/form.tsx +++ b/web/core/components/issues/issue-modal/form.tsx @@ -5,6 +5,7 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; import { useForm } from "react-hook-form"; // editor +import { EIssuesStoreType } from "@plane/constants"; import { EditorRefApi } from "@plane/editor"; // types import type { TIssue, ISearchIssueResponse, TWorkspaceDraftIssue } from "@plane/types"; @@ -19,7 +20,6 @@ import { IssueTitleInput, } from "@/components/issues/issue-modal/components"; import { CreateLabelModal } from "@/components/labels"; -import { EIssuesStoreType } from "@/constants/issue"; import { ETabIndices } from "@/constants/tab-indices"; // helpers import { cn } from "@/helpers/common.helper"; diff --git a/web/core/components/issues/issue-modal/modal.tsx b/web/core/components/issues/issue-modal/modal.tsx index 3c8a639ee50..56569bef8cf 100644 --- a/web/core/components/issues/issue-modal/modal.tsx +++ b/web/core/components/issues/issue-modal/modal.tsx @@ -3,11 +3,11 @@ import React from "react"; import { observer } from "mobx-react"; // types +import { EIssuesStoreType } from "@plane/constants"; import type { TIssue } from "@plane/types"; // components import { CreateUpdateIssueModalBase } from "@/components/issues"; // constants -import { EIssuesStoreType } from "@/constants/issue"; // plane web providers import { IssueModalProvider } from "@/plane-web/components/issues"; diff --git a/web/core/components/issues/parent-issues-list-modal.tsx b/web/core/components/issues/parent-issues-list-modal.tsx index 5042902221b..193b2327e2e 100644 --- a/web/core/components/issues/parent-issues-list-modal.tsx +++ b/web/core/components/issues/parent-issues-list-modal.tsx @@ -9,7 +9,7 @@ import { Combobox, Dialog, Transition } from "@headlessui/react"; // types import { ISearchIssueResponse } from "@plane/types"; // ui -import { Loader, ToggleSwitch, Tooltip } from "@plane/ui"; +import { Loader } from "@plane/ui"; // components import { IssueSearchModalEmptyState } from "@/components/core"; // helpers @@ -48,7 +48,6 @@ export const ParentIssuesListModal: React.FC = ({ const [searchTerm, setSearchTerm] = useState(""); const [issues, setIssues] = useState([]); const [isSearching, setIsSearching] = useState(false); - const [isWorkspaceLevel, setIsWorkspaceLevel] = useState(false); const { isMobile } = usePlatformOS(); const debouncedSearchTerm: string = useDebounce(searchTerm, 500); @@ -59,7 +58,6 @@ export const ParentIssuesListModal: React.FC = ({ const handleClose = () => { onClose(); setSearchTerm(""); - setIsWorkspaceLevel(false); }; useEffect(() => { @@ -73,7 +71,7 @@ export const ParentIssuesListModal: React.FC = ({ search: debouncedSearchTerm, parent: true, issue_id: issueId, - workspace_search: isWorkspaceLevel, + workspace_search: false, epic: searchEpic ? true : undefined, }) .then((res) => setIssues(res)) @@ -81,7 +79,7 @@ export const ParentIssuesListModal: React.FC = ({ setIsSearching(false); setIsLoading(false); }); - }, [debouncedSearchTerm, isOpen, issueId, isWorkspaceLevel, projectId, workspaceSlug]); + }, [debouncedSearchTerm, isOpen, issueId, projectId, workspaceSlug]); return ( <> @@ -131,28 +129,6 @@ export const ParentIssuesListModal: React.FC = ({ tabIndex={baseTabIndex} />
-
- -
- setIsWorkspaceLevel((prevData) => !prevData)} - label="Workspace level" - /> - -
-
-
{ // state diff --git a/web/core/components/modules/analytics-sidebar/issue-progress.tsx b/web/core/components/modules/analytics-sidebar/issue-progress.tsx index e51e46ed4cc..29bac20c29b 100644 --- a/web/core/components/modules/analytics-sidebar/issue-progress.tsx +++ b/web/core/components/modules/analytics-sidebar/issue-progress.tsx @@ -6,13 +6,13 @@ import { observer } from "mobx-react"; import { useSearchParams } from "next/navigation"; import { AlertCircle, ChevronUp, ChevronDown } from "lucide-react"; import { Disclosure, Transition } from "@headlessui/react"; +import { EIssueFilterType, EIssuesStoreType } from "@plane/constants"; import { IIssueFilterOptions, TModulePlotType } from "@plane/types"; import { CustomSelect, Spinner } from "@plane/ui"; // components import ProgressChart from "@/components/core/sidebar/progress-chart"; import { ModuleProgressStats } from "@/components/modules"; // constants -import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; // helpers import { getDate } from "@/helpers/date-time.helper"; // hooks diff --git a/web/core/components/modules/module-view-header.tsx b/web/core/components/modules/module-view-header.tsx index 592c1e80d7e..6afcf2cc092 100644 --- a/web/core/components/modules/module-view-header.tsx +++ b/web/core/components/modules/module-view-header.tsx @@ -3,16 +3,15 @@ import React, { FC, useCallback, useEffect, useRef, useState } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; -// icons import { ListFilter, Search, X } from "lucide-react"; -// editor -import { cn } from "@plane/editor"; // plane helpers import { useOutsideClickDetector } from "@plane/hooks"; // types import { TModuleFilters } from "@plane/types"; // ui import { Tooltip } from "@plane/ui"; +// plane utils +import { cn } from "@plane/utils"; // components import { FiltersDropdown } from "@/components/issues"; import { ModuleFiltersSelection, ModuleOrderByDropdown } from "@/components/modules/dropdowns"; diff --git a/web/core/components/pages/editor/editor-body.tsx b/web/core/components/pages/editor/editor-body.tsx index c36b70f7415..7e4155ba25e 100644 --- a/web/core/components/pages/editor/editor-body.tsx +++ b/web/core/components/pages/editor/editor-body.tsx @@ -1,11 +1,9 @@ -import { useCallback, useMemo } from "react"; +import { Dispatch, SetStateAction, useCallback, useMemo } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // document-editor import { CollaborativeDocumentEditorWithRef, - CollaborativeDocumentReadOnlyEditorWithRef, - EditorReadOnlyRefApi, EditorRefApi, TAIMenuProps, TDisplayConfig, @@ -20,7 +18,7 @@ import { EditorMentionsRoot } from "@/components/editor"; import { PageContentBrowser, PageContentLoader, PageEditorTitle } from "@/components/pages"; // helpers import { cn, LIVE_BASE_PATH, LIVE_BASE_URL } from "@/helpers/common.helper"; -import { getEditorFileHandlers, getReadOnlyEditorFileHandlers } from "@/helpers/editor.helper"; +import { getEditorFileHandlers } from "@/helpers/editor.helper"; import { generateRandomColor } from "@/helpers/string.helper"; // hooks import { useUser, useWorkspace } from "@/hooks/store"; @@ -44,24 +42,14 @@ const projectService = new ProjectService(); type Props = { editorRef: React.RefObject; editorReady: boolean; - handleConnectionStatus: (status: boolean) => void; - handleEditorReady: (value: boolean) => void; - handleReadOnlyEditorReady: (value: boolean) => void; + handleConnectionStatus: Dispatch>; + handleEditorReady: Dispatch>; page: IPage; - readOnlyEditorRef: React.RefObject; sidePeekVisible: boolean; }; export const PageEditorBody: React.FC = observer((props) => { - const { - editorRef, - handleConnectionStatus, - handleEditorReady, - handleReadOnlyEditorReady, - page, - readOnlyEditorRef, - sidePeekVisible, - } = props; + const { editorRef, handleConnectionStatus, handleEditorReady, page, sidePeekVisible } = props; // router const { workspaceSlug, projectId } = useParams(); // store hooks @@ -106,11 +94,11 @@ export const PageEditorBody: React.FC = observer((props) => { const handleServerConnect = useCallback(() => { handleConnectionStatus(false); - }, []); + }, [handleConnectionStatus]); const handleServerError = useCallback(() => { handleConnectionStatus(true); - }, []); + }, [handleConnectionStatus]); const serverHandler: TServerHandler = useMemo( () => ({ @@ -163,18 +151,16 @@ export const PageEditorBody: React.FC = observer((props) => { "w-[5%]": isFullWidth, })} > - {!isFullWidth && ( - - )} + {!isFullWidth && }
-
-
+
+
= observer((props) => { readOnly={!isContentEditable} />
- {isContentEditable ? ( - { - const { asset_id } = await fileService.uploadProjectAsset( - workspaceSlug?.toString() ?? "", - projectId?.toString() ?? "", - { - entity_identifier: pageId, - entity_type: EFileAssetType.PAGE_DESCRIPTION, - }, - file - ); - return asset_id; - }, - workspaceId, - workspaceSlug: workspaceSlug?.toString() ?? "", - })} - handleEditorReady={handleEditorReady} - ref={editorRef} - containerClassName="h-full p-0 pb-64" - displayConfig={displayConfig} - editorClassName="pl-10" - mentionHandler={{ - searchCallback: async (query) => { - const res = await fetchMentions(query); - if (!res) throw new Error("Failed in fetching mentions"); - return res; - }, - renderComponent: (props) => , - }} - embedHandler={{ - issue: issueEmbedProps, - }} - realtimeConfig={realtimeConfig} - serverHandler={serverHandler} - user={userConfig} - disabledExtensions={disabledExtensions} - aiHandler={{ - menu: getAIMenu, - }} - /> - ) : ( - , - }} - embedHandler={{ - issue: { - widgetCallback: issueEmbedProps.widgetCallback, - }, - }} - realtimeConfig={realtimeConfig} - user={userConfig} - /> - )} + { + const { asset_id } = await fileService.uploadProjectAsset( + workspaceSlug?.toString() ?? "", + projectId?.toString() ?? "", + { + entity_identifier: pageId, + entity_type: EFileAssetType.PAGE_DESCRIPTION, + }, + file + ); + return asset_id; + }, + workspaceId, + workspaceSlug: workspaceSlug?.toString() ?? "", + })} + handleEditorReady={handleEditorReady} + ref={editorRef} + containerClassName="h-full p-0 pb-64" + displayConfig={displayConfig} + editorClassName="pl-10" + mentionHandler={{ + searchCallback: async (query) => { + const res = await fetchMentions(query); + if (!res) throw new Error("Failed in fetching mentions"); + return res; + }, + renderComponent: (props) => , + }} + embedHandler={{ + issue: issueEmbedProps, + }} + realtimeConfig={realtimeConfig} + serverHandler={serverHandler} + user={userConfig} + disabledExtensions={disabledExtensions} + aiHandler={{ + menu: getAIMenu, + }} + />
; handleDuplicatePage: () => void; page: IPage; - readOnlyEditorRef: React.RefObject; }; export const PageExtraOptions: React.FC = observer((props) => { - const { editorRef, handleDuplicatePage, page, readOnlyEditorRef } = props; + const { editorRef, handleDuplicatePage, page } = props; // derived values const { archived_at, @@ -85,12 +84,8 @@ export const PageExtraOptions: React.FC = observer((props) => { iconClassName="text-custom-text-100" /> )} - - + +
); }); diff --git a/web/core/components/pages/editor/header/info-popover.tsx b/web/core/components/pages/editor/header/info-popover.tsx index e295d8ea278..13a1b17666a 100644 --- a/web/core/components/pages/editor/header/info-popover.tsx +++ b/web/core/components/pages/editor/header/info-popover.tsx @@ -2,12 +2,12 @@ import { useState } from "react"; import { usePopper } from "react-popper"; import { Info } from "lucide-react"; // plane editor -import { EditorReadOnlyRefApi, EditorRefApi } from "@plane/editor"; +import { EditorRefApi } from "@plane/editor"; // helpers import { getReadTimeFromWordsCount } from "@/helpers/date-time.helper"; type Props = { - editorRef: EditorRefApi | EditorReadOnlyRefApi | null; + editorRef: EditorRefApi | null; }; export const PageInfoPopover: React.FC = (props) => { diff --git a/web/core/components/pages/editor/header/mobile-root.tsx b/web/core/components/pages/editor/header/mobile-root.tsx index ac831796cbe..df93a70e922 100644 --- a/web/core/components/pages/editor/header/mobile-root.tsx +++ b/web/core/components/pages/editor/header/mobile-root.tsx @@ -13,52 +13,34 @@ type Props = { editorRef: React.RefObject; handleDuplicatePage: () => void; page: IPage; - readOnlyEditorReady: boolean; - readOnlyEditorRef: React.RefObject; setSidePeekVisible: (sidePeekState: boolean) => void; sidePeekVisible: boolean; }; export const PageEditorMobileHeaderRoot: React.FC = observer((props) => { - const { - editorReady, - editorRef, - handleDuplicatePage, - page, - readOnlyEditorReady, - readOnlyEditorRef, - setSidePeekVisible, - sidePeekVisible, - } = props; + const { editorReady, editorRef, handleDuplicatePage, page, setSidePeekVisible, sidePeekVisible } = props; // derived values const { isContentEditable } = page; // page filters const { isFullWidth } = usePageFilters(); - if (!editorRef.current && !readOnlyEditorRef.current) return null; + if (!editorRef.current) return null; return ( <>
- +
- {(editorReady || readOnlyEditorReady) && isContentEditable && editorRef.current && ( - - )} + {editorReady && isContentEditable && editorRef.current && }
); diff --git a/web/core/components/pages/editor/header/options-dropdown.tsx b/web/core/components/pages/editor/header/options-dropdown.tsx index 1881cc47ff6..928b84bf984 100644 --- a/web/core/components/pages/editor/header/options-dropdown.tsx +++ b/web/core/components/pages/editor/header/options-dropdown.tsx @@ -15,7 +15,7 @@ import { LucideIcon, } from "lucide-react"; // document editor -import { EditorReadOnlyRefApi, EditorRefApi } from "@plane/editor"; +import { EditorRefApi } from "@plane/editor"; // ui import { ArchiveIcon, CustomMenu, type ISvgIcons, TOAST_TYPE, ToggleSwitch, setToast } from "@plane/ui"; // components @@ -31,7 +31,7 @@ import { useQueryParams } from "@/hooks/use-query-params"; import { IPage } from "@/store/pages/page"; type Props = { - editorRef: EditorRefApi | EditorReadOnlyRefApi | null; + editorRef: EditorRefApi | null; handleDuplicatePage: () => void; page: IPage; }; diff --git a/web/core/components/pages/editor/header/root.tsx b/web/core/components/pages/editor/header/root.tsx index 9640f4e43b6..41933feb725 100644 --- a/web/core/components/pages/editor/header/root.tsx +++ b/web/core/components/pages/editor/header/root.tsx @@ -1,5 +1,5 @@ import { observer } from "mobx-react"; -import { EditorReadOnlyRefApi, EditorRefApi } from "@plane/editor"; +import { EditorRefApi } from "@plane/editor"; // components import { Header, EHeaderVariant } from "@plane/ui"; import { PageEditorMobileHeaderRoot, PageExtraOptions, PageSummaryPopover, PageToolbar } from "@/components/pages"; @@ -15,35 +15,24 @@ type Props = { editorRef: React.RefObject; handleDuplicatePage: () => void; page: IPage; - readOnlyEditorReady: boolean; - readOnlyEditorRef: React.RefObject; setSidePeekVisible: (sidePeekState: boolean) => void; sidePeekVisible: boolean; }; export const PageEditorHeaderRoot: React.FC = observer((props) => { - const { - editorReady, - editorRef, - handleDuplicatePage, - page, - readOnlyEditorReady, - readOnlyEditorRef, - setSidePeekVisible, - sidePeekVisible, - } = props; + const { editorReady, editorRef, setSidePeekVisible, sidePeekVisible, handleDuplicatePage, page } = props; // derived values const { isContentEditable } = page; // page filters const { isFullWidth } = usePageFilters(); - if (!editorRef.current && !readOnlyEditorRef.current) return null; + if (!editorRef.current) return null; return ( <>
- {(editorReady || readOnlyEditorReady) && ( + {editorReady && (
= observer((props) => { })} >
)} - {(editorReady || readOnlyEditorReady) && isContentEditable && editorRef.current && ( - - )} + {editorReady && isContentEditable && editorRef.current && }
- +
{ // states const [editorReady, setEditorReady] = useState(false); const [hasConnectionFailed, setHasConnectionFailed] = useState(false); - const [readOnlyEditorReady, setReadOnlyEditorReady] = useState(false); const [sidePeekVisible, setSidePeekVisible] = useState(window.innerWidth >= 768); const [isVersionsOverlayOpen, setIsVersionsOverlayOpen] = useState(false); // refs const editorRef = useRef(null); - const readOnlyEditorRef = useRef(null); // router const router = useAppRouter(); // search params @@ -99,9 +97,7 @@ export const PageRoot = observer((props: TPageRootProps) => { editorRef.current?.clearEditor(); editorRef.current?.setEditorValue(descriptionHTML); }; - const currentVersionDescription = isContentEditable - ? editorRef.current?.getDocument().html - : readOnlyEditorRef.current?.getDocument().html; + const currentVersionDescription = editorRef.current?.getDocument().html; return ( <> @@ -137,19 +133,15 @@ export const PageRoot = observer((props: TPageRootProps) => { editorRef={editorRef} handleDuplicatePage={handleDuplicatePage} page={page} - readOnlyEditorReady={readOnlyEditorReady} - readOnlyEditorRef={readOnlyEditorRef} setSidePeekVisible={(state) => setSidePeekVisible(state)} sidePeekVisible={sidePeekVisible} /> setHasConnectionFailed(status)} - handleEditorReady={(val) => setEditorReady(val)} - handleReadOnlyEditorReady={() => setReadOnlyEditorReady(true)} + handleConnectionStatus={setHasConnectionFailed} + handleEditorReady={setEditorReady} page={page} - readOnlyEditorRef={readOnlyEditorRef} sidePeekVisible={sidePeekVisible} /> diff --git a/web/core/components/pages/editor/summary/content-browser.tsx b/web/core/components/pages/editor/summary/content-browser.tsx index 669d2e978c8..16d818aaeb7 100644 --- a/web/core/components/pages/editor/summary/content-browser.tsx +++ b/web/core/components/pages/editor/summary/content-browser.tsx @@ -1,11 +1,11 @@ import { useState, useEffect } from "react"; // plane editor -import { EditorReadOnlyRefApi, EditorRefApi, IMarking } from "@plane/editor"; +import { EditorRefApi, IMarking } from "@plane/editor"; // components import { OutlineHeading1, OutlineHeading2, OutlineHeading3 } from "./heading-components"; type Props = { - editorRef: EditorRefApi | EditorReadOnlyRefApi | null; + editorRef: EditorRefApi | null; setSidePeekVisible?: (sidePeekState: boolean) => void; }; diff --git a/web/core/components/pages/editor/summary/popover.tsx b/web/core/components/pages/editor/summary/popover.tsx index 5d14234f037..9acc4a7cc0c 100644 --- a/web/core/components/pages/editor/summary/popover.tsx +++ b/web/core/components/pages/editor/summary/popover.tsx @@ -2,14 +2,14 @@ import { useState } from "react"; import { usePopper } from "react-popper"; import { List } from "lucide-react"; // document editor -import { EditorReadOnlyRefApi, EditorRefApi } from "@plane/editor"; +import { EditorRefApi } from "@plane/editor"; // helpers import { cn } from "@/helpers/common.helper"; // components import { PageContentBrowser } from "./content-browser"; type Props = { - editorRef: EditorRefApi | EditorReadOnlyRefApi | null; + editorRef: EditorRefApi | null; isFullWidth: boolean; sidePeekVisible: boolean; setSidePeekVisible: (sidePeekState: boolean) => void; diff --git a/web/core/components/pages/modals/export-page-modal.tsx b/web/core/components/pages/modals/export-page-modal.tsx index 475b1b1bb71..67e2f629d86 100644 --- a/web/core/components/pages/modals/export-page-modal.tsx +++ b/web/core/components/pages/modals/export-page-modal.tsx @@ -4,7 +4,7 @@ import { useState } from "react"; import { PageProps, pdf } from "@react-pdf/renderer"; import { Controller, useForm } from "react-hook-form"; // plane editor -import { EditorReadOnlyRefApi, EditorRefApi } from "@plane/editor"; +import { EditorRefApi } from "@plane/editor"; // plane ui import { Button, CustomSelect, EModalPosition, EModalWidth, ModalCore, setToast, TOAST_TYPE } from "@plane/ui"; // components @@ -13,7 +13,7 @@ import { PDFDocument } from "@/components/editor"; import { useParseEditorContent } from "@/hooks/use-parse-editor-content"; type Props = { - editorRef: EditorRefApi | EditorReadOnlyRefApi | null; + editorRef: EditorRefApi | null; isOpen: boolean; onClose: () => void; pageTitle: string; diff --git a/web/core/components/profile/profile-issues-filter.tsx b/web/core/components/profile/profile-issues-filter.tsx index aaaa153613a..4b20324ea2f 100644 --- a/web/core/components/profile/profile-issues-filter.tsx +++ b/web/core/components/profile/profile-issues-filter.tsx @@ -1,17 +1,14 @@ import { useCallback } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; +// plane constants +import { EIssueLayoutTypes, EIssuesStoreType, EIssueFilterType } from "@plane/constants"; // types import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions } from "@plane/types"; // components import { DisplayFiltersSelection, FilterSelection, FiltersDropdown, LayoutSelection } from "@/components/issues"; // constants -import { - EIssuesStoreType, - EIssueFilterType, - ISSUE_DISPLAY_FILTERS_BY_LAYOUT, - EIssueLayoutTypes, -} from "@/constants/issue"; +import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "@/constants/issue"; // helpers import { isIssueFilterActive } from "@/helpers/filter.helper"; // hooks diff --git a/web/core/components/profile/profile-issues.tsx b/web/core/components/profile/profile-issues.tsx index e4adaf9993d..428ccf8f98c 100644 --- a/web/core/components/profile/profile-issues.tsx +++ b/web/core/components/profile/profile-issues.tsx @@ -3,11 +3,11 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; import useSWR from "swr"; // components +import { EIssuesStoreType } from "@plane/constants"; import { IssuePeekOverview, ProfileIssuesAppliedFiltersRoot } from "@/components/issues"; import { ProfileIssuesKanBanLayout } from "@/components/issues/issue-layouts/kanban/roots/profile-issues-root"; import { ProfileIssuesListLayout } from "@/components/issues/issue-layouts/list/roots/profile-issues-root"; // hooks -import { EIssuesStoreType } from "@/constants/issue"; import { useIssues } from "@/hooks/store"; import { IssuesStoreContext } from "../../hooks/use-issue-layout-store"; // constants diff --git a/web/core/components/project/create/common-attributes.tsx b/web/core/components/project/create/common-attributes.tsx index f753d0ae758..53da57d28d9 100644 --- a/web/core/components/project/create/common-attributes.tsx +++ b/web/core/components/project/create/common-attributes.tsx @@ -1,9 +1,10 @@ import { ChangeEvent } from "react"; import { Controller, useFormContext, UseFormSetValue } from "react-hook-form"; import { Info } from "lucide-react"; -import { cn } from "@plane/editor"; -// ui +// plane ui import { Input, TextArea, Tooltip } from "@plane/ui"; +// plane utils +import { cn } from "@plane/utils"; // constants import { ETabIndices } from "@/constants/tab-indices"; // helpers diff --git a/web/core/components/project/filters.tsx b/web/core/components/project/filters.tsx index 9434f79951f..2465bbc3693 100644 --- a/web/core/components/project/filters.tsx +++ b/web/core/components/project/filters.tsx @@ -2,9 +2,10 @@ import { useCallback } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; import { ListFilter } from "lucide-react"; -// types -import { cn } from "@plane/editor"; +// plane types import { TProjectFilters } from "@plane/types"; +// plane utils +import { cn } from "@plane/utils"; // components import { FiltersDropdown } from "@/components/issues"; import { ProjectFiltersSelection, ProjectOrderByDropdown } from "@/components/project"; diff --git a/web/core/components/project/form.tsx b/web/core/components/project/form.tsx index 855c52aaf7f..8ce776eb666 100644 --- a/web/core/components/project/form.tsx +++ b/web/core/components/project/form.tsx @@ -16,16 +16,15 @@ import { CustomEmojiIconPicker, EmojiIconPickerTypes, Tooltip, - CustomSearchSelect, } from "@plane/ui"; // components import { Logo } from "@/components/common"; import { ImagePickerPopover } from "@/components/core"; +import { TimezoneSelect } from "@/components/global"; // constants import { PROJECT_UPDATED } from "@/constants/event-tracker"; import { NETWORK_CHOICES } from "@/constants/project"; // helpers -import { TTimezone, TIME_ZONES } from "@/constants/timezones"; import { renderFormattedDate } from "@/helpers/date-time.helper"; import { convertHexEmojiToDecimal } from "@/helpers/emoji.helper"; import { getFileURL } from "@/helpers/file.helper"; @@ -34,6 +33,7 @@ import { useEventTracker, useProject } from "@/hooks/store"; import { usePlatformOS } from "@/hooks/use-platform-os"; // services import { ProjectService } from "@/services/project"; + export interface IProjectDetailsForm { project: IProject; workspaceSlug: string; @@ -68,20 +68,6 @@ export const ProjectDetailsForm: FC = (props) => { }); // derived values const currentNetwork = NETWORK_CHOICES.find((n) => n.key === project?.network); - const getTimeZoneLabel = (timezone: TTimezone | undefined) => { - if (!timezone) return undefined; - return ( -
- {timezone.gmtOffset} - {timezone.name} -
- ); - }; - const timeZoneOptions = TIME_ZONES.map((timeZone) => ({ - value: timeZone.value, - query: timeZone.name + " " + timeZone.gmtOffset + " " + timeZone.value, - content: getTimeZoneLabel(timeZone), - })); const coverImage = watch("cover_image_url"); useEffect(() => { @@ -393,20 +379,16 @@ export const ProjectDetailsForm: FC = (props) => { control={control} rules={{ required: "Please select a timezone" }} render={({ field: { value, onChange } }) => ( - t.value === value)) ?? value) - : "Select a timezone" - } - options={timeZoneOptions} - onChange={onChange} - buttonClassName={errors.timezone ? "border-red-500" : "border-none"} - className="rounded-md border-[0.5px] !border-custom-border-200" - optionsClassName="w-72" - input - /> + <> + { + onChange(value); + }} + error={Boolean(errors.timezone)} + buttonClassName="border-none" + /> + )} /> {errors.timezone && {errors.timezone.message}} diff --git a/web/core/components/ui/loader/layouts/kanban-layout-loader.tsx b/web/core/components/ui/loader/layouts/kanban-layout-loader.tsx index ebf92445e88..9cf250a1890 100644 --- a/web/core/components/ui/loader/layouts/kanban-layout-loader.tsx +++ b/web/core/components/ui/loader/layouts/kanban-layout-loader.tsx @@ -1,7 +1,9 @@ import { forwardRef } from "react"; import range from "lodash/range"; -import { cn } from "@plane/editor"; +// plane ui import { ContentWrapper } from "@plane/ui"; +// plane utils +import { cn } from "@plane/utils"; export const KanbanIssueBlockLoader = forwardRef( ({ cardHeight = 100, shouldAnimate = true }, ref) => ( diff --git a/web/core/components/ui/loader/layouts/list-layout-loader.tsx b/web/core/components/ui/loader/layouts/list-layout-loader.tsx index 65d4d1565a2..fdcaf88984f 100644 --- a/web/core/components/ui/loader/layouts/list-layout-loader.tsx +++ b/web/core/components/ui/loader/layouts/list-layout-loader.tsx @@ -1,7 +1,9 @@ import { Fragment, forwardRef } from "react"; import range from "lodash/range"; -import { cn } from "@plane/editor"; +// plane ui import { Row } from "@plane/ui"; +// plane utils +import { cn } from "@plane/utils"; import { getRandomInt, getRandomLength } from "../utils"; export const ListLoaderItemRow = forwardRef< diff --git a/web/core/components/views/form.tsx b/web/core/components/views/form.tsx index ede1fa10b6e..a39f98fc4e8 100644 --- a/web/core/components/views/form.tsx +++ b/web/core/components/views/form.tsx @@ -4,6 +4,8 @@ import { useEffect, useState } from "react"; import { observer } from "mobx-react"; import { Controller, useForm } from "react-hook-form"; import { Layers } from "lucide-react"; +// plane constants +import { EIssueLayoutTypes } from "@plane/constants"; // types import { IProjectView, IIssueFilterOptions, IIssueDisplayProperties, IIssueDisplayFilterOptions } from "@plane/types"; // ui @@ -12,7 +14,7 @@ import { Button, EmojiIconPicker, EmojiIconPickerTypes, Input, TextArea } from " import { Logo } from "@/components/common"; import { AppliedFiltersList, DisplayFiltersSelection, FilterSelection, FiltersDropdown } from "@/components/issues"; // constants -import { EIssueLayoutTypes, ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "@/constants/issue"; +import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "@/constants/issue"; import { ETabIndices } from "@/constants/tab-indices"; import { EViewAccess } from "@/constants/views"; // helpers diff --git a/web/core/components/workspace/logo.tsx b/web/core/components/workspace/logo.tsx index 4407205e07f..460e076c5fc 100644 --- a/web/core/components/workspace/logo.tsx +++ b/web/core/components/workspace/logo.tsx @@ -1,5 +1,6 @@ +// plane utils +import { cn } from "@plane/utils"; // helpers -import { cn } from "@plane/editor"; import { getFileURL } from "@/helpers/file.helper"; type Props = { diff --git a/web/core/constants/issue.ts b/web/core/constants/issue.ts index c568284393d..5ef54075a5b 100644 --- a/web/core/constants/issue.ts +++ b/web/core/constants/issue.ts @@ -1,14 +1,16 @@ // icons import { Calendar, GanttChartSquare, Kanban, List, Sheet } from "lucide-react"; +// plane constants +import { EIssueLayoutTypes, EIssuesStoreType } from "@plane/constants"; // types import { - IIssueFilterOptions, IIssueDisplayProperties, TIssueExtraOptions, TIssueGroupByOptions, TIssueOrderByOptions, TIssuePriorities, TIssueGroupingFilters, + ILayoutDisplayFiltersOptions, } from "@plane/types"; import { ADDITIONAL_ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "@/plane-web/constants"; @@ -21,30 +23,6 @@ export const DRAG_ALLOWED_GROUPS: TIssueGroupByOptions[] = [ "cycle", ]; -export enum EIssuesStoreType { - GLOBAL = "GLOBAL", - PROFILE = "PROFILE", - TEAM = "TEAM", - PROJECT = "PROJECT", - CYCLE = "CYCLE", - MODULE = "MODULE", - TEAM_VIEW = "TEAM_VIEW", - PROJECT_VIEW = "PROJECT_VIEW", - ARCHIVED = "ARCHIVED", - DRAFT = "DRAFT", - DEFAULT = "DEFAULT", - WORKSPACE_DRAFT = "WORKSPACE_DRAFT", - EPIC = "EPIC", -} - -export enum EIssueLayoutTypes { - LIST = "list", - KANBAN = "kanban", - CALENDAR = "calendar", - GANTT = "gantt_chart", - SPREADSHEET = "spreadsheet", -} - export type TCreateModalStoreTypes = | EIssuesStoreType.TEAM | EIssuesStoreType.PROJECT @@ -55,18 +33,6 @@ export type TCreateModalStoreTypes = | EIssuesStoreType.MODULE | EIssuesStoreType.EPIC; -export enum EIssueFilterType { - FILTERS = "filters", - DISPLAY_FILTERS = "display_filters", - DISPLAY_PROPERTIES = "display_properties", - KANBAN_FILTERS = "kanban_filters", -} - -export enum EIssueCommentAccessSpecifier { - EXTERNAL = "EXTERNAL", - INTERNAL = "INTERNAL", -} - export const ISSUE_PRIORITIES: { key: TIssuePriorities; title: string; @@ -197,21 +163,6 @@ export const ISSUE_LAYOUTS: { icon: any; }[] = Object.values(ISSUE_LAYOUT_MAP); -export interface ILayoutDisplayFiltersOptions { - filters: (keyof IIssueFilterOptions)[]; - display_properties: (keyof IIssueDisplayProperties)[]; - display_filters: { - group_by?: TIssueGroupByOptions[]; - sub_group_by?: TIssueGroupByOptions[]; - order_by?: TIssueOrderByOptions[]; - type?: TIssueGroupingFilters[]; - }; - extra_options: { - access: boolean; - values: TIssueExtraOptions[]; - }; -} - export type TFiltersByLayout = { [layoutType: string]: ILayoutDisplayFiltersOptions; }; @@ -553,13 +504,6 @@ export const ISSUE_STORE_TO_FILTERS_MAP: Partial { - if (currentActionBeingProcessed) { - const serverEventName = getServerEventName(currentActionBeingProcessed); - if (serverEventName) { - editorRef?.emitRealTimeUpdate(serverEventName); - } - } - }, [currentActionBeingProcessed, editorRef]); - useEffect(() => { const realTimeStatelessMessageListener = editorRef?.listenToRealTimeUpdate(); @@ -95,6 +90,5 @@ export const useCollaborativePageActions = (editorRef: EditorRefApi | EditorRead return { executeCollaborativeAction, - EVENT_ACTION_DETAILS_MAP: actionHandlerMap, }; }; diff --git a/web/core/hooks/use-group-dragndrop.ts b/web/core/hooks/use-group-dragndrop.ts index 3e5bff3e364..3bbcee82278 100644 --- a/web/core/hooks/use-group-dragndrop.ts +++ b/web/core/hooks/use-group-dragndrop.ts @@ -1,10 +1,10 @@ "use client"; import { useParams } from "next/navigation"; +import { EIssuesStoreType } from "@plane/constants"; import { TIssue, TIssueGroupByOptions, TIssueOrderByOptions } from "@plane/types"; import { TOAST_TYPE, setToast } from "@plane/ui"; import { GroupDropLocation, handleGroupDragDrop } from "@/components/issues/issue-layouts/utils"; -import { EIssuesStoreType } from "@/constants/issue"; import { ISSUE_FILTER_DEFAULT_DATA } from "@/store/issue/helpers/base-issues.store"; import { useIssueDetail, useIssues } from "./store"; import { useIssuesActions } from "./use-issues-actions"; diff --git a/web/core/hooks/use-issue-layout-store.ts b/web/core/hooks/use-issue-layout-store.ts index aab69402f0e..cb5af2d2874 100644 --- a/web/core/hooks/use-issue-layout-store.ts +++ b/web/core/hooks/use-issue-layout-store.ts @@ -1,6 +1,6 @@ import { createContext, useContext } from "react"; import { useParams } from "next/navigation"; -import { EIssuesStoreType } from "@/constants/issue"; +import { EIssuesStoreType } from "@plane/constants"; import { useIssues } from "./store"; export const IssuesStoreContext = createContext(undefined); diff --git a/web/core/hooks/use-issues-actions.tsx b/web/core/hooks/use-issues-actions.tsx index 2315b43850b..eeebb6746b6 100644 --- a/web/core/hooks/use-issues-actions.tsx +++ b/web/core/hooks/use-issues-actions.tsx @@ -1,6 +1,7 @@ import { useCallback, useMemo } from "react"; // types import { useParams } from "next/navigation"; +import { EIssueFilterType, EIssuesStoreType } from "@plane/constants"; import { IIssueDisplayFilterOptions, IIssueDisplayProperties, @@ -12,7 +13,6 @@ import { TLoader, TProfileViews, } from "@plane/types"; -import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; import { EDraftIssuePaginationType } from "@/constants/workspace-drafts"; import { useTeamIssueActions, useTeamViewIssueActions } from "@/plane-web/helpers/issue-action-helper"; import { useIssues } from "./store"; diff --git a/web/core/hooks/use-timezone.tsx b/web/core/hooks/use-timezone.tsx new file mode 100644 index 00000000000..983f99beb43 --- /dev/null +++ b/web/core/hooks/use-timezone.tsx @@ -0,0 +1,80 @@ +import useSWR from "swr"; +import { TTimezoneObject } from "@plane/types"; +// services +import timezoneService from "@/services/timezone.service"; + +// group timezones by value +const groupTimezones = (timezones: TTimezoneObject[]): TTimezoneObject[] => { + const groupedMap = timezones.reduce((acc, timezone: TTimezoneObject) => { + const key = timezone.value; + + if (!acc.has(key)) { + acc.set(key, { + utc_offset: timezone.utc_offset, + gmt_offset: timezone.gmt_offset, + value: timezone.value, + label: timezone.label, + }); + } else { + const existing = acc.get(key); + existing.label = `${existing.label}, ${timezone.label}`; + } + + return acc; + }, new Map()); + + return Array.from(groupedMap.values()); +}; + +const useTimezone = () => { + // fetching the timezone from the server + const { + data: timezones, + isLoading: timezoneIsLoading, + error: timezonesError, + } = useSWR("TIMEZONES_LIST", () => timezoneService.fetch(), { + refreshInterval: 0, + }); + + // derived values + const isDisabled = timezoneIsLoading || timezonesError || !timezones; + + const getTimeZoneLabel = (timezone: TTimezoneObject | undefined) => { + if (!timezone) return undefined; + return ( +
+ {timezone.utc_offset} + {timezone.label} +
+ ); + }; + const options = [ + ...groupTimezones(timezones?.timezones || [])?.map((timezone) => ({ + value: timezone.value, + query: `${timezone.value} ${timezone.label}, ${timezone.gmt_offset}, ${timezone.utc_offset}`, + content: getTimeZoneLabel(timezone), + })), + { + value: "UTC", + query: "utc, coordinated universal time", + content: "UTC", + }, + { + value: "Universal", + query: "universal, coordinated universal time", + content: "Universal", + }, + ]; + + const selectedTimezone = (value: string | undefined) => options.find((option) => option.value === value)?.content; + + return { + timezones: options, + isLoading: timezoneIsLoading, + error: timezonesError, + disabled: isDisabled, + selectedValue: selectedTimezone, + }; +}; + +export default useTimezone; diff --git a/web/core/local-db/utils/utils.ts b/web/core/local-db/utils/utils.ts index 6cd5f3033c5..b0330e057aa 100644 --- a/web/core/local-db/utils/utils.ts +++ b/web/core/local-db/utils/utils.ts @@ -174,7 +174,7 @@ export const clearOPFS = async (force = false) => { return; } // ts-ignore - for await (const entry of root.values()) { + for await (const entry of (root as any)?.values()) { if (entry.kind === "directory" && entry.name.startsWith(".ahp-")) { // A lock with the same name as the directory protects it from // being deleted. diff --git a/web/core/services/timezone.service.ts b/web/core/services/timezone.service.ts new file mode 100644 index 00000000000..d19e7e96495 --- /dev/null +++ b/web/core/services/timezone.service.ts @@ -0,0 +1,23 @@ +import { TTimezones } from "@plane/types"; +// helpers +import { API_BASE_URL } from "@/helpers/common.helper"; +// api services +import { APIService } from "@/services/api.service"; + +export class TimezoneService extends APIService { + constructor() { + super(API_BASE_URL); + } + + async fetch(): Promise { + return this.get(`/api/timezones/`) + .then((response) => response?.data) + .catch((error) => { + throw error?.response?.data; + }); + } +} + +const timezoneService = new TimezoneService(); + +export default timezoneService; diff --git a/web/core/store/base-command-palette.store.ts b/web/core/store/base-command-palette.store.ts index 436129dd0d4..5281082d14a 100644 --- a/web/core/store/base-command-palette.store.ts +++ b/web/core/store/base-command-palette.store.ts @@ -1,6 +1,7 @@ import { observable, action, makeObservable } from "mobx"; +import { EIssuesStoreType } from "@plane/constants"; // services -import { EIssuesStoreType, TCreateModalStoreTypes } from "@/constants/issue"; +import { TCreateModalStoreTypes } from "@/constants/issue"; // types / constants import { DEFAULT_CREATE_PAGE_MODAL_DATA, EPageAccess, TCreatePageModal } from "@/constants/page"; diff --git a/web/core/store/global-view.store.ts b/web/core/store/global-view.store.ts index e0d0d7a7b92..ff40a8fd33a 100644 --- a/web/core/store/global-view.store.ts +++ b/web/core/store/global-view.store.ts @@ -4,9 +4,9 @@ import isEqual from "lodash/isEqual"; import set from "lodash/set"; import { observable, action, makeObservable, runInAction, computed } from "mobx"; import { computedFn } from "mobx-utils"; +import { EIssueFilterType } from "@plane/constants"; import { IIssueFilterOptions, IWorkspaceView } from "@plane/types"; // constants -import { EIssueFilterType } from "@/constants/issue"; import { EViewAccess } from "@/constants/views"; // services import { WorkspaceService } from "@/plane-web/services"; diff --git a/web/core/store/issue/archived/filter.store.ts b/web/core/store/issue/archived/filter.store.ts index ad673c8cf41..d9cbb9ab172 100644 --- a/web/core/store/issue/archived/filter.store.ts +++ b/web/core/store/issue/archived/filter.store.ts @@ -5,6 +5,7 @@ import set from "lodash/set"; import { action, computed, makeObservable, observable, runInAction } from "mobx"; // base class import { computedFn } from "mobx-utils"; +import { EIssuesStoreType, EIssueFilterType } from "@plane/constants"; import { IIssueFilterOptions, IIssueDisplayFilterOptions, @@ -14,7 +15,6 @@ import { TIssueParams, IssuePaginationOptions, } from "@plane/types"; -import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; import { handleIssueQueryParamsByLayout } from "@/helpers/issue.helper"; import { IssueFiltersService } from "@/services/issue_filter.service"; import { IBaseIssueFilterStore, IssueFilterHelperStore } from "../helpers/issue-filter-helper.store"; diff --git a/web/core/store/issue/cycle/filter.store.ts b/web/core/store/issue/cycle/filter.store.ts index 5e62061f055..c8a0bc0fb4a 100644 --- a/web/core/store/issue/cycle/filter.store.ts +++ b/web/core/store/issue/cycle/filter.store.ts @@ -3,6 +3,7 @@ import set from "lodash/set"; import { action, computed, makeObservable, observable, runInAction } from "mobx"; // base class import { computedFn } from "mobx-utils"; +import { EIssueFilterType, EIssuesStoreType } from "@plane/constants"; import { IIssueFilterOptions, IIssueDisplayFilterOptions, @@ -12,7 +13,6 @@ import { TIssueParams, IssuePaginationOptions, } from "@plane/types"; -import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; import { handleIssueQueryParamsByLayout } from "@/helpers/issue.helper"; import { IssueFiltersService } from "@/services/issue_filter.service"; import { IBaseIssueFilterStore, IssueFilterHelperStore } from "../helpers/issue-filter-helper.store"; diff --git a/web/core/store/issue/draft/filter.store.ts b/web/core/store/issue/draft/filter.store.ts index bbada1199bf..7b06262c92f 100644 --- a/web/core/store/issue/draft/filter.store.ts +++ b/web/core/store/issue/draft/filter.store.ts @@ -5,6 +5,7 @@ import set from "lodash/set"; import { action, computed, makeObservable, observable, runInAction } from "mobx"; // base class import { computedFn } from "mobx-utils"; +import { EIssueFilterType, EIssuesStoreType } from "@plane/constants"; import { IIssueFilterOptions, IIssueDisplayFilterOptions, @@ -14,7 +15,6 @@ import { TIssueParams, IssuePaginationOptions, } from "@plane/types"; -import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; import { handleIssueQueryParamsByLayout } from "@/helpers/issue.helper"; import { IssueFiltersService } from "@/services/issue_filter.service"; import { IBaseIssueFilterStore, IssueFilterHelperStore } from "../helpers/issue-filter-helper.store"; diff --git a/web/core/store/issue/helpers/base-issues.store.ts b/web/core/store/issue/helpers/base-issues.store.ts index 17e264d4240..3b115bb06ba 100644 --- a/web/core/store/issue/helpers/base-issues.store.ts +++ b/web/core/store/issue/helpers/base-issues.store.ts @@ -12,8 +12,9 @@ import uniq from "lodash/uniq"; import update from "lodash/update"; import { action, computed, makeObservable, observable, runInAction } from "mobx"; import { computedFn } from "mobx-utils"; +// plane constants +import { EIssueLayoutTypes, ALL_ISSUES } from "@plane/constants"; // types -import { ALL_ISSUES } from "@plane/constants"; import { TIssue, TIssueGroupByOptions, @@ -32,7 +33,7 @@ import { // components import { IBlockUpdateDependencyData } from "@/components/gantt-chart"; // constants -import { EIssueLayoutTypes, ISSUE_PRIORITIES } from "@/constants/issue"; +import { ISSUE_PRIORITIES } from "@/constants/issue"; // helpers import { convertToISODateString } from "@/helpers/date-time.helper"; // local-db diff --git a/web/core/store/issue/helpers/issue-filter-helper.store.ts b/web/core/store/issue/helpers/issue-filter-helper.store.ts index 37d0e3d8658..118c73c3b50 100644 --- a/web/core/store/issue/helpers/issue-filter-helper.store.ts +++ b/web/core/store/issue/helpers/issue-filter-helper.store.ts @@ -1,6 +1,12 @@ import isEmpty from "lodash/isEmpty"; -import { EIssueGroupByToServerOptions, EServerGroupByToFilterOptions } from "@plane/constants"; -// types +// plane constants +import { + EIssueGroupByToServerOptions, + EServerGroupByToFilterOptions, + EIssueLayoutTypes, + EIssuesStoreType, + EIssueFilterType, +} from "@plane/constants"; import { IIssueDisplayFilterOptions, IIssueDisplayProperties, @@ -12,8 +18,6 @@ import { TIssueParams, TStaticViewTypes, } from "@plane/types"; -// constants -import { EIssueFilterType, EIssueLayoutTypes, EIssuesStoreType } from "@/constants/issue"; // helpers import { getComputedDisplayFilters, getComputedDisplayProperties } from "@/helpers/issue.helper"; // lib diff --git a/web/core/store/issue/module/filter.store.ts b/web/core/store/issue/module/filter.store.ts index 9c22963b91e..e1bd1b07005 100644 --- a/web/core/store/issue/module/filter.store.ts +++ b/web/core/store/issue/module/filter.store.ts @@ -3,6 +3,7 @@ import set from "lodash/set"; import { action, computed, makeObservable, observable, runInAction } from "mobx"; // base class import { computedFn } from "mobx-utils"; +import { EIssueFilterType, EIssuesStoreType } from "@plane/constants"; import { IIssueFilterOptions, IIssueDisplayFilterOptions, @@ -12,7 +13,6 @@ import { TIssueParams, IssuePaginationOptions, } from "@plane/types"; -import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; import { handleIssueQueryParamsByLayout } from "@/helpers/issue.helper"; import { IssueFiltersService } from "@/services/issue_filter.service"; import { IBaseIssueFilterStore, IssueFilterHelperStore } from "../helpers/issue-filter-helper.store"; diff --git a/web/core/store/issue/profile/filter.store.ts b/web/core/store/issue/profile/filter.store.ts index edd5073d3fc..5ba8083289f 100644 --- a/web/core/store/issue/profile/filter.store.ts +++ b/web/core/store/issue/profile/filter.store.ts @@ -3,6 +3,7 @@ import set from "lodash/set"; import { action, computed, makeObservable, observable, runInAction } from "mobx"; // base class import { computedFn } from "mobx-utils"; +import { EIssueFilterType, EIssuesStoreType } from "@plane/constants"; import { IIssueFilterOptions, IIssueDisplayFilterOptions, @@ -12,7 +13,6 @@ import { TIssueParams, IssuePaginationOptions, } from "@plane/types"; -import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; import { handleIssueQueryParamsByLayout } from "@/helpers/issue.helper"; import { IssueFiltersService } from "@/services/issue_filter.service"; import { IBaseIssueFilterStore, IssueFilterHelperStore } from "../helpers/issue-filter-helper.store"; diff --git a/web/core/store/issue/project-views/filter.store.ts b/web/core/store/issue/project-views/filter.store.ts index b49633c367c..a25a53cff30 100644 --- a/web/core/store/issue/project-views/filter.store.ts +++ b/web/core/store/issue/project-views/filter.store.ts @@ -3,6 +3,7 @@ import set from "lodash/set"; import { action, computed, makeObservable, observable, runInAction } from "mobx"; // base class import { computedFn } from "mobx-utils"; +import { EIssueFilterType, EIssuesStoreType } from "@plane/constants"; import { IIssueFilterOptions, IIssueDisplayFilterOptions, @@ -12,7 +13,6 @@ import { TIssueParams, IssuePaginationOptions, } from "@plane/types"; -import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; import { handleIssueQueryParamsByLayout } from "@/helpers/issue.helper"; // services import { ViewService } from "@/plane-web/services"; diff --git a/web/core/store/issue/project/filter.store.ts b/web/core/store/issue/project/filter.store.ts index 069f2ed8932..4d194e2f12e 100644 --- a/web/core/store/issue/project/filter.store.ts +++ b/web/core/store/issue/project/filter.store.ts @@ -3,6 +3,7 @@ import set from "lodash/set"; import { action, computed, makeObservable, observable, runInAction } from "mobx"; // base class import { computedFn } from "mobx-utils"; +import { EIssueFilterType, EIssuesStoreType } from "@plane/constants"; import { IIssueFilterOptions, IIssueDisplayFilterOptions, @@ -12,7 +13,6 @@ import { TIssueParams, IssuePaginationOptions, } from "@plane/types"; -import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; import { handleIssueQueryParamsByLayout } from "@/helpers/issue.helper"; import { IssueFiltersService } from "@/services/issue_filter.service"; import { IBaseIssueFilterStore, IssueFilterHelperStore } from "../helpers/issue-filter-helper.store"; diff --git a/web/core/store/issue/workspace-draft/filter.store.ts b/web/core/store/issue/workspace-draft/filter.store.ts index f43d0a068e9..7d504596f2f 100644 --- a/web/core/store/issue/workspace-draft/filter.store.ts +++ b/web/core/store/issue/workspace-draft/filter.store.ts @@ -1,8 +1,10 @@ -import isEmpty from "lodash/isEmpty"; +import +isEmpty from "lodash/isEmpty"; import set from "lodash/set"; import { action, computed, makeObservable, observable, runInAction } from "mobx"; // base class import { computedFn } from "mobx-utils"; +import { EIssuesStoreType, EIssueFilterType } from "@plane/constants"; import { IIssueFilterOptions, IIssueDisplayFilterOptions, @@ -12,7 +14,6 @@ import { TIssueParams, IssuePaginationOptions, } from "@plane/types"; -import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; import { handleIssueQueryParamsByLayout } from "@/helpers/issue.helper"; import { IssueFiltersService } from "@/services/issue_filter.service"; import { IBaseIssueFilterStore, IssueFilterHelperStore } from "../helpers/issue-filter-helper.store"; diff --git a/web/core/store/issue/workspace/filter.store.ts b/web/core/store/issue/workspace/filter.store.ts index e062147c610..ffc36e65087 100644 --- a/web/core/store/issue/workspace/filter.store.ts +++ b/web/core/store/issue/workspace/filter.store.ts @@ -3,8 +3,10 @@ import isEmpty from "lodash/isEmpty"; import pickBy from "lodash/pickBy"; import set from "lodash/set"; import { action, computed, makeObservable, observable, runInAction } from "mobx"; -// base class +// plane constants import { computedFn } from "mobx-utils"; +import { EIssueLayoutTypes, EIssueFilterType, EIssuesStoreType } from "@plane/constants"; +// base class import { IIssueFilterOptions, IIssueDisplayFilterOptions, @@ -15,7 +17,6 @@ import { TStaticViewTypes, IssuePaginationOptions, } from "@plane/types"; -import { EIssueFilterType, EIssueLayoutTypes, EIssuesStoreType } from "@/constants/issue"; // services import { handleIssueQueryParamsByLayout } from "@/helpers/issue.helper"; import { WorkspaceService } from "@/plane-web/services"; diff --git a/web/helpers/issue.helper.ts b/web/helpers/issue.helper.ts index 171c469b0d7..5b9c2161855 100644 --- a/web/helpers/issue.helper.ts +++ b/web/helpers/issue.helper.ts @@ -2,6 +2,8 @@ import differenceInCalendarDays from "date-fns/differenceInCalendarDays"; import isEmpty from "lodash/isEmpty"; import set from "lodash/set"; import { v4 as uuidv4 } from "uuid"; +// plane constants +import { EIssueLayoutTypes } from "@plane/constants"; // types import { IIssueDisplayFilterOptions, @@ -17,7 +19,7 @@ import { } from "@plane/types"; import { IGanttBlock } from "@/components/gantt-chart"; // constants -import { EIssueLayoutTypes, ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "@/constants/issue"; +import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "@/constants/issue"; import { STATE_GROUPS } from "@/constants/state"; // helpers import { orderArrayBy } from "@/helpers/array.helper"; diff --git a/yarn.lock b/yarn.lock index 26849e4e990..ca19c7554ad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5400,11 +5400,6 @@ clone@^2.1.2: resolved "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz" integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== -clsx@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz" - integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== - clsx@^2.0.0, clsx@^2.1.0, clsx@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz" @@ -11271,16 +11266,7 @@ streamx@^2.15.0, streamx@^2.20.0: optionalDependencies: bare-events "^2.2.0" -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -11368,14 +11354,7 @@ string_decoder@^1.1.1, string_decoder@^1.3.0: dependencies: safe-buffer "~5.2.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -11516,12 +11495,7 @@ tabbable@^6.0.0: resolved "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz" integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew== -tailwind-merge@^1.14.0: - version "1.14.0" - resolved "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-1.14.0.tgz" - integrity sha512-3mFKyCo/MBcgyOTlrY8T7odzZFx+w+qKSMAmdFzRvqBfLlSigU6TZnlFHK0lkMwj9Bj8OYU+9yW9lmGuS0QEnQ== - -tailwind-merge@^2.0.0: +tailwind-merge@^2.0.0, tailwind-merge@^2.5.5: version "2.5.5" resolved "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.5.tgz" integrity sha512-0LXunzzAZzo0tEPxV3I297ffKZPlKDrjj7NXphC8V5ak9yHC5zRmxnOe2m/Rd/7ivsOMJe3JZ2JVocoDdQTRBA== @@ -12631,16 +12605,7 @@ word-wrap@^1.2.5: resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz" integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==