From a90724516b33811483672c848af49e7b0290de5f Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Thu, 11 Jul 2024 13:18:06 +0530 Subject: [PATCH 1/8] chore: auth screen layout padding (#5087) --- space/core/components/views/auth.tsx | 2 +- web/app/accounts/forgot-password/page.tsx | 2 +- web/app/accounts/reset-password/page.tsx | 2 +- web/app/accounts/set-password/page.tsx | 2 +- web/app/page.tsx | 2 +- web/app/sign-up/page.tsx | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/space/core/components/views/auth.tsx b/space/core/components/views/auth.tsx index fb68d8fbab..2c5a8a2f4d 100644 --- a/space/core/components/views/auth.tsx +++ b/space/core/components/views/auth.tsx @@ -30,7 +30,7 @@ export const AuthView = observer(() => { />
-
+
Plane logo diff --git a/web/app/accounts/forgot-password/page.tsx b/web/app/accounts/forgot-password/page.tsx index 0e203a1f88..3e86e8eff5 100644 --- a/web/app/accounts/forgot-password/page.tsx +++ b/web/app/accounts/forgot-password/page.tsx @@ -104,7 +104,7 @@ export default function ForgotPasswordPage() { />
-
+
Plane logo diff --git a/web/app/accounts/reset-password/page.tsx b/web/app/accounts/reset-password/page.tsx index 43f001abe9..4d5303b985 100644 --- a/web/app/accounts/reset-password/page.tsx +++ b/web/app/accounts/reset-password/page.tsx @@ -116,7 +116,7 @@ export default function ResetPasswordPage() { />
-
+
Plane logo diff --git a/web/app/accounts/set-password/page.tsx b/web/app/accounts/set-password/page.tsx index e74b506e60..df1b5d5675 100644 --- a/web/app/accounts/set-password/page.tsx +++ b/web/app/accounts/set-password/page.tsx @@ -118,7 +118,7 @@ const SetPasswordPage = observer(() => { />
-
+
Plane logo diff --git a/web/app/page.tsx b/web/app/page.tsx index 4982f40825..63ef855cab 100644 --- a/web/app/page.tsx +++ b/web/app/page.tsx @@ -46,7 +46,7 @@ const HomePage = observer(() => { />
-
+
Plane logo diff --git a/web/app/sign-up/page.tsx b/web/app/sign-up/page.tsx index 8bd2e87991..f08ccbae7b 100644 --- a/web/app/sign-up/page.tsx +++ b/web/app/sign-up/page.tsx @@ -41,7 +41,7 @@ const SignInPage = observer(() => { />
-
+
Plane logo From 2136872351e4e86b6f66b873d5d9c6d099385330 Mon Sep 17 00:00:00 2001 From: guru_sainath Date: Thu, 11 Jul 2024 13:19:07 +0530 Subject: [PATCH 2/8] [WEB-1916] ui: updated the empty state design in workspace notifications and ui changes (#5093) * ui: updated the empty state design in workspace notifications and ui changes * chore: updated the popover custom components * ui: updated the badge ui on the sidrbar options * ui: broken down the menu components --- .../(projects)/notifications/page.tsx | 46 +++-- .../notification-app-sidebar-option.tsx | 2 +- .../sidebar/filters/index.ts | 2 +- .../sidebar/filters/menu/index.ts | 2 + .../sidebar/filters/menu/menu-option-item.tsx | 46 +++++ .../sidebar/filters/menu/root.tsx | 32 ++++ .../sidebar/filters/root.tsx | 80 --------- .../sidebar/header/options/menu-option.tsx | 160 ------------------ .../header/options/menu-option/index.ts | 2 + .../header/options/menu-option/menu-item.tsx | 28 +++ .../header/options/menu-option/root.tsx | 114 +++++++++++++ .../workspace-notifications/sidebar/root.tsx | 9 +- web/core/constants/empty-state.ts | 6 + 13 files changed, 263 insertions(+), 266 deletions(-) create mode 100644 web/core/components/workspace-notifications/sidebar/filters/menu/index.ts create mode 100644 web/core/components/workspace-notifications/sidebar/filters/menu/menu-option-item.tsx create mode 100644 web/core/components/workspace-notifications/sidebar/filters/menu/root.tsx delete mode 100644 web/core/components/workspace-notifications/sidebar/filters/root.tsx delete mode 100644 web/core/components/workspace-notifications/sidebar/header/options/menu-option.tsx create mode 100644 web/core/components/workspace-notifications/sidebar/header/options/menu-option/index.ts create mode 100644 web/core/components/workspace-notifications/sidebar/header/options/menu-option/menu-item.tsx create mode 100644 web/core/components/workspace-notifications/sidebar/header/options/menu-option/root.tsx diff --git a/web/app/[workspaceSlug]/(projects)/notifications/page.tsx b/web/app/[workspaceSlug]/(projects)/notifications/page.tsx index 5fa81a8e1e..c6003c2590 100644 --- a/web/app/[workspaceSlug]/(projects)/notifications/page.tsx +++ b/web/app/[workspaceSlug]/(projects)/notifications/page.tsx @@ -6,9 +6,11 @@ import useSWR from "swr"; // components import { LogoSpinner } from "@/components/common"; import { PageHead } from "@/components/core"; +import { EmptyState } from "@/components/empty-state"; import { InboxContentRoot } from "@/components/inbox"; import { IssuePeekOverview } from "@/components/issues"; // constants +import { EmptyStateType } from "@/constants/empty-state"; import { ENotificationLoader, ENotificationQueryParamType } from "@/constants/notification"; // hooks import { useIssueDetail, useUser, useWorkspace, useWorkspaceNotifications } from "@/hooks/store"; @@ -62,36 +64,44 @@ const WorkspaceDashboardPage = observer(() => { setCurrentSelectedNotificationId(undefined); setPeekIssue(undefined); }, - [] + [setCurrentSelectedNotificationId, setPeekIssue] ); return ( <>
- {is_inbox_issue === true && workspace_slug && project_id && issue_id ? ( + {!currentSelectedNotificationId ? ( +
+ +
+ ) : ( <> - {projectMemberInfoLoader ? ( -
- -
+ {is_inbox_issue === true && workspace_slug && project_id && issue_id ? ( + <> + {projectMemberInfoLoader ? ( +
+ +
+ ) : ( + {}} + isMobileSidebar={false} + workspaceSlug={workspace_slug} + projectId={project_id} + inboxIssueId={issue_id} + isNotificationEmbed + embedRemoveCurrentNotification={() => setCurrentSelectedNotificationId(undefined)} + /> + )} + ) : ( - {}} - isMobileSidebar={false} - workspaceSlug={workspace_slug} - projectId={project_id} - inboxIssueId={issue_id} - isNotificationEmbed + setCurrentSelectedNotificationId(undefined)} /> )} - ) : ( - setCurrentSelectedNotificationId(undefined)} - /> )}
diff --git a/web/core/components/workspace-notifications/notification-app-sidebar-option.tsx b/web/core/components/workspace-notifications/notification-app-sidebar-option.tsx index 3d33bdd72b..cfffe1265c 100644 --- a/web/core/components/workspace-notifications/notification-app-sidebar-option.tsx +++ b/web/core/components/workspace-notifications/notification-app-sidebar-option.tsx @@ -38,7 +38,7 @@ export const NotificationAppSidebarOption: FC = o return (
- +
); }); diff --git a/web/core/components/workspace-notifications/sidebar/filters/index.ts b/web/core/components/workspace-notifications/sidebar/filters/index.ts index 4f7dbf49f4..b4d269c8a3 100644 --- a/web/core/components/workspace-notifications/sidebar/filters/index.ts +++ b/web/core/components/workspace-notifications/sidebar/filters/index.ts @@ -1,2 +1,2 @@ -export * from "./root"; +export * from "./menu"; export * from "./applied-filter"; diff --git a/web/core/components/workspace-notifications/sidebar/filters/menu/index.ts b/web/core/components/workspace-notifications/sidebar/filters/menu/index.ts new file mode 100644 index 0000000000..5d76f42637 --- /dev/null +++ b/web/core/components/workspace-notifications/sidebar/filters/menu/index.ts @@ -0,0 +1,2 @@ +export * from "./root"; +export * from "./menu-option-item"; diff --git a/web/core/components/workspace-notifications/sidebar/filters/menu/menu-option-item.tsx b/web/core/components/workspace-notifications/sidebar/filters/menu/menu-option-item.tsx new file mode 100644 index 0000000000..cf894e1879 --- /dev/null +++ b/web/core/components/workspace-notifications/sidebar/filters/menu/menu-option-item.tsx @@ -0,0 +1,46 @@ +"use client"; + +import { FC } from "react"; +import { observer } from "mobx-react"; +import { Check } from "lucide-react"; +// constants +import { ENotificationFilterType } from "@/constants/notification"; +// helpers +import { cn } from "@/helpers/common.helper"; +// hooks +import { useWorkspaceNotifications } from "@/hooks/store"; + +export const NotificationFilterOptionItem: FC<{ label: string; value: ENotificationFilterType }> = observer((props) => { + const { value, label } = props; + // hooks + const { filters, updateFilters } = useWorkspaceNotifications(); + + const handleFilterTypeChange = (filterType: ENotificationFilterType, filterValue: boolean) => + updateFilters("type", { + ...filters.type, + [filterType]: filterValue, + }); + + // derived values + const isSelected = filters?.type?.[value] || false; + + return ( +
handleFilterTypeChange(value, !isSelected)} + > +
+ {isSelected && } +
+
+ {label} +
+
+ ); +}); diff --git a/web/core/components/workspace-notifications/sidebar/filters/menu/root.tsx b/web/core/components/workspace-notifications/sidebar/filters/menu/root.tsx new file mode 100644 index 0000000000..09f8427d35 --- /dev/null +++ b/web/core/components/workspace-notifications/sidebar/filters/menu/root.tsx @@ -0,0 +1,32 @@ +"use client"; + +import { FC } from "react"; +import { observer } from "mobx-react"; +import { ListFilter } from "lucide-react"; +import { PopoverMenu, Tooltip } from "@plane/ui"; +// components +import { NotificationFilterOptionItem } from "@/components/workspace-notifications"; +// constants +import { ENotificationFilterType, FILTER_TYPE_OPTIONS } from "@/constants/notification"; +// hooks +import { usePlatformOS } from "@/hooks/use-platform-os"; + +export const NotificationFilter: FC = observer(() => { + // hooks + const { isMobile } = usePlatformOS(); + + return ( + +
+ +
+ + } + keyExtractor={(item: { label: string; value: ENotificationFilterType }) => item.value} + render={(item) => } + /> + ); +}); diff --git a/web/core/components/workspace-notifications/sidebar/filters/root.tsx b/web/core/components/workspace-notifications/sidebar/filters/root.tsx deleted file mode 100644 index 86994c8194..0000000000 --- a/web/core/components/workspace-notifications/sidebar/filters/root.tsx +++ /dev/null @@ -1,80 +0,0 @@ -"use client"; - -import { FC, Fragment } from "react"; -import { observer } from "mobx-react"; -import { Check, ListFilter } from "lucide-react"; -import { Popover, Transition } from "@headlessui/react"; -import { Tooltip } from "@plane/ui"; -// constants -import { ENotificationFilterType, FILTER_TYPE_OPTIONS } from "@/constants/notification"; -// helpers -import { cn } from "@/helpers/common.helper"; -// hooks -import { useWorkspaceNotifications } from "@/hooks/store"; -import { usePlatformOS } from "@/hooks/use-platform-os"; - -export const NotificationFilter: FC = observer(() => { - // hooks - const { isMobile } = usePlatformOS(); - const { filters, updateFilters } = useWorkspaceNotifications(); - - const handleFilterTypeChange = (filterType: ENotificationFilterType, filterValue: boolean) => - updateFilters("type", { - ...filters.type, - [filterType]: filterValue, - }); - - return ( - - - (open ? "bg-custom-background-80" : "") - )} - > - - - - - - -
- {FILTER_TYPE_OPTIONS.map((filter) => { - const isSelected = filters?.type?.[filter?.value] || false; - return ( -
handleFilterTypeChange(filter?.value, !isSelected)} - > -
- {isSelected && } -
-
- {filter.label} -
-
- ); - })} -
-
-
-
- ); -}); diff --git a/web/core/components/workspace-notifications/sidebar/header/options/menu-option.tsx b/web/core/components/workspace-notifications/sidebar/header/options/menu-option.tsx deleted file mode 100644 index 509dd9de3b..0000000000 --- a/web/core/components/workspace-notifications/sidebar/header/options/menu-option.tsx +++ /dev/null @@ -1,160 +0,0 @@ -"use client"; - -import { FC, Fragment } from "react"; -import { observer } from "mobx-react"; -import { Check, CheckCheck, CheckCircle, Clock, MoreVertical } from "lucide-react"; -import { Popover, Transition } from "@headlessui/react"; -import { TNotificationFilter } from "@plane/types"; -import { ArchiveIcon, Spinner, Tooltip } from "@plane/ui"; -// constants -import { NOTIFICATIONS_READ } from "@/constants/event-tracker"; -import { ENotificationLoader } from "@/constants/notification"; -import { cn } from "@/helpers/common.helper"; -// hooks -import { useEventTracker, useWorkspaceNotifications } from "@/hooks/store"; -import { usePlatformOS } from "@/hooks/use-platform-os"; - -type TNotificationHeaderMenuOption = { - workspaceSlug: string; -}; - -export const NotificationHeaderMenuOption: FC = observer((props) => { - const { workspaceSlug } = props; - // hooks - const { captureEvent } = useEventTracker(); - const { isMobile } = usePlatformOS(); - const { loader, filters, updateFilters, updateBulkFilters, markAllNotificationsAsRead } = useWorkspaceNotifications(); - - const handleFilterChange = (filterType: keyof TNotificationFilter, filterValue: boolean) => - updateFilters(filterType, filterValue); - - const handleBulkFilterChange = (filter: Partial) => updateBulkFilters(filter); - - const handleMarkAllNotificationsAsRead = async () => { - // NOTE: We are using loader to prevent continues request when we are making all the notification to read - if (loader) return; - try { - await markAllNotificationsAsRead(workspaceSlug); - } catch (error) { - console.error(error); - } - }; - - return ( - - - (open ? "bg-custom-background-80" : "") - )} - > - - - - - - -
-
-
{ - handleMarkAllNotificationsAsRead(); - captureEvent(NOTIFICATIONS_READ); - }} - > - -
Mark all as read
- {loader === ENotificationLoader.MARK_ALL_AS_READY && ( -
- -
- )} -
-
- -
- -
-
handleFilterChange("read", !filters?.read)} - > - -
- Show unread -
- {filters?.read && ( -
- -
- )} -
- -
- handleBulkFilterChange({ - archived: !filters?.archived, - snoozed: false, - }) - } - > - -
- Show Archived -
- {filters?.archived && ( -
- -
- )} -
- -
- handleBulkFilterChange({ - snoozed: !filters?.snoozed, - archived: false, - }) - } - > - -
- Show Snoozed -
- {filters?.snoozed && ( -
- -
- )} -
-
-
- - - - ); -}); diff --git a/web/core/components/workspace-notifications/sidebar/header/options/menu-option/index.ts b/web/core/components/workspace-notifications/sidebar/header/options/menu-option/index.ts new file mode 100644 index 0000000000..808d90c76f --- /dev/null +++ b/web/core/components/workspace-notifications/sidebar/header/options/menu-option/index.ts @@ -0,0 +1,2 @@ +export * from "./root"; +export * from "./menu-item"; diff --git a/web/core/components/workspace-notifications/sidebar/header/options/menu-option/menu-item.tsx b/web/core/components/workspace-notifications/sidebar/header/options/menu-option/menu-item.tsx new file mode 100644 index 0000000000..9189663102 --- /dev/null +++ b/web/core/components/workspace-notifications/sidebar/header/options/menu-option/menu-item.tsx @@ -0,0 +1,28 @@ +"use client"; + +import { FC } from "react"; +import { observer } from "mobx-react"; +// components +import type { TPopoverMenuOptions } from "@/components/workspace-notifications"; +// helpers +import { cn } from "@/helpers/common.helper"; + +export const NotificationMenuOptionItem: FC = observer((props) => { + const { type, label = "", isActive, prependIcon, appendIcon, onClick } = props; + + if (type === "menu-item") + return ( +
onClick && onClick()} + > + {prependIcon && prependIcon} +
+ {label} +
+ {appendIcon &&
{appendIcon}
} +
+ ); + + return
; +}); diff --git a/web/core/components/workspace-notifications/sidebar/header/options/menu-option/root.tsx b/web/core/components/workspace-notifications/sidebar/header/options/menu-option/root.tsx new file mode 100644 index 0000000000..ea0eb130f2 --- /dev/null +++ b/web/core/components/workspace-notifications/sidebar/header/options/menu-option/root.tsx @@ -0,0 +1,114 @@ +"use client"; + +import { FC, ReactNode } from "react"; +import { observer } from "mobx-react"; +import { Check, CheckCheck, CheckCircle, Clock } from "lucide-react"; +import { TNotificationFilter } from "@plane/types"; +import { ArchiveIcon, PopoverMenu, Spinner } from "@plane/ui"; +// components +import { NotificationMenuOptionItem } from "@/components/workspace-notifications"; +// constants +import { NOTIFICATIONS_READ } from "@/constants/event-tracker"; +import { ENotificationLoader } from "@/constants/notification"; +// hooks +import { useEventTracker, useWorkspaceNotifications } from "@/hooks/store"; + +type TNotificationHeaderMenuOption = { + workspaceSlug: string; +}; + +export type TPopoverMenuOptions = { + key: string; + type: string; + label?: string | undefined; + isActive?: boolean | undefined; + prependIcon?: ReactNode | undefined; + appendIcon?: ReactNode | undefined; + onClick?: (() => void) | undefined; +}; + +export const NotificationHeaderMenuOption: FC = observer((props) => { + const { workspaceSlug } = props; + // hooks + const { captureEvent } = useEventTracker(); + const { loader, filters, updateFilters, updateBulkFilters, markAllNotificationsAsRead } = useWorkspaceNotifications(); + + const handleFilterChange = (filterType: keyof TNotificationFilter, filterValue: boolean) => + updateFilters(filterType, filterValue); + + const handleBulkFilterChange = (filter: Partial) => updateBulkFilters(filter); + + const handleMarkAllNotificationsAsRead = async () => { + // NOTE: We are using loader to prevent continues request when we are making all the notification to read + if (loader) return; + try { + await markAllNotificationsAsRead(workspaceSlug); + } catch (error) { + console.error(error); + } + }; + + const popoverMenuOptions: TPopoverMenuOptions[] = [ + { + key: "menu-mark-all-read", + type: "menu-item", + label: "Mark all as read", + isActive: true, + prependIcon: , + appendIcon: loader === ENotificationLoader.MARK_ALL_AS_READY ? : undefined, + onClick: () => { + captureEvent(NOTIFICATIONS_READ); + handleMarkAllNotificationsAsRead(); + }, + }, + { + key: "menu-divider", + type: "divider", + }, + { + key: "menu-unread", + type: "menu-item", + label: "Show unread", + isActive: filters?.read, + prependIcon: , + appendIcon: filters?.read ? : undefined, + onClick: () => handleFilterChange("read", !filters?.read), + }, + { + key: "menu-archived", + type: "menu-item", + label: "Show archived", + isActive: filters?.archived, + prependIcon: , + appendIcon: filters?.archived ? : undefined, + onClick: () => + handleBulkFilterChange({ + archived: !filters?.archived, + snoozed: false, + }), + }, + { + key: "menu-snoozed", + type: "menu-item", + label: "Show snoozed", + isActive: filters?.snoozed, + prependIcon: , + appendIcon: filters?.snoozed ? : undefined, + onClick: () => + handleBulkFilterChange({ + snoozed: !filters?.snoozed, + archived: false, + }), + }, + ]; + + return ( + item.key} + panelClassName="p-0 py-2 rounded-md border border-custom-border-200 bg-custom-background-100 space-y-1" + render={(item: TPopoverMenuOptions) => } + /> + ); +}); diff --git a/web/core/components/workspace-notifications/sidebar/root.tsx b/web/core/components/workspace-notifications/sidebar/root.tsx index 679df0b319..26ad1d76a1 100644 --- a/web/core/components/workspace-notifications/sidebar/root.tsx +++ b/web/core/components/workspace-notifications/sidebar/root.tsx @@ -66,12 +66,9 @@ export const NotificationsSidebar: FC = observer(() => { )} >
{tab.label}
- + {tab.count(unreadNotificationsCount) > 0 && ( + + )}
{currentNotificationTab === tab.value && (
diff --git a/web/core/constants/empty-state.ts b/web/core/constants/empty-state.ts index cad133dd0c..56eb1d4727 100644 --- a/web/core/constants/empty-state.ts +++ b/web/core/constants/empty-state.ts @@ -80,6 +80,7 @@ export enum EmptyStateType { ISSUE_RELATION_EMPTY_STATE = "issue-relation-empty-state", ISSUE_COMMENT_EMPTY_STATE = "issue-comment-empty-state", + NOTIFICATION_DETAIL_EMPTY_STATE = "notification-detail-empty-state", NOTIFICATION_ALL_EMPTY_STATE = "notification-all-empty-state", NOTIFICATION_MENTIONS_EMPTY_STATE = "notification-mentions-empty-state", NOTIFICATION_MY_ISSUE_EMPTY_STATE = "notification-my-issues-empty-state", @@ -595,6 +596,11 @@ const emptyStateDetails = { path: "/empty-state/search/comments", }, + [EmptyStateType.NOTIFICATION_DETAIL_EMPTY_STATE]: { + key: EmptyStateType.INBOX_DETAIL_EMPTY_STATE, + title: "Select to view details.", + path: "/empty-state/inbox/issue-detail", + }, [EmptyStateType.NOTIFICATION_ALL_EMPTY_STATE]: { key: EmptyStateType.NOTIFICATION_ALL_EMPTY_STATE, title: "No issues assigned", From ac8e588ac397bfe324a036b570b2e9576495c122 Mon Sep 17 00:00:00 2001 From: Akshita Goyal <36129505+gakshita@users.noreply.github.com> Date: Thu, 11 Jul 2024 13:36:34 +0530 Subject: [PATCH 3/8] [WEB-1820] fix: analytics truncate project name (#5089) * fix: Truncated project name under custom analytics's project selection dropdown * fix: project name truncated * fix: removed static width * fix: hardcoded width * fix: css --- .../components/analytics/custom-analytics/select/project.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/core/components/analytics/custom-analytics/select/project.tsx b/web/core/components/analytics/custom-analytics/select/project.tsx index 5eb209d0e1..1d34ed7b92 100644 --- a/web/core/components/analytics/custom-analytics/select/project.tsx +++ b/web/core/components/analytics/custom-analytics/select/project.tsx @@ -23,7 +23,7 @@ export const SelectProject: React.FC = observer((props) => { value: projectDetails?.id, query: `${projectDetails?.name} ${projectDetails?.identifier}`, content: ( -
+
{projectDetails?.identifier} {projectDetails?.name}
@@ -44,6 +44,7 @@ export const SelectProject: React.FC = observer((props) => { .join(", ") : "All projects" } + optionsClassName={"w-48"} multiple /> ); From 77694ee8baff3aab3c3accbe8d2cd87f65b2cd79 Mon Sep 17 00:00:00 2001 From: Akshita Goyal <36129505+gakshita@users.noreply.github.com> Date: Thu, 11 Jul 2024 13:37:07 +0530 Subject: [PATCH 4/8] [WEB-1876] fix: "Show sub-issues" checkbox checked by default under Archives (#5091) * fix: "Show sub-issues" checkbox checked by default under Archives * fix: default value set --- web/core/store/issue/archived/filter.store.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/web/core/store/issue/archived/filter.store.ts b/web/core/store/issue/archived/filter.store.ts index 3f0a4fedc9..9d86cc9df5 100644 --- a/web/core/store/issue/archived/filter.store.ts +++ b/web/core/store/issue/archived/filter.store.ts @@ -133,7 +133,10 @@ export class ArchivedIssuesFilter extends IssueFilterHelperStore implements IArc ); const filters: IIssueFilterOptions = this.computedFilters(_filters?.filters); - const displayFilters: IIssueDisplayFilterOptions = this.computedDisplayFilters(_filters?.display_filters); + const displayFilters: IIssueDisplayFilterOptions = this.computedDisplayFilters({ + ..._filters?.display_filters, + sub_issue: true, + }); const displayProperties: IIssueDisplayProperties = this.computedDisplayProperties(_filters?.display_properties); const kanbanFilters = { group_by: [], From 2d78f6fd22729e1c2dabfda03e0bcdcd4a8754c0 Mon Sep 17 00:00:00 2001 From: Akshita Goyal <36129505+gakshita@users.noreply.github.com> Date: Thu, 11 Jul 2024 13:37:40 +0530 Subject: [PATCH 5/8] fix: empty state for view page fixed (#5090) --- web/core/components/views/views-list.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/core/components/views/views-list.tsx b/web/core/components/views/views-list.tsx index 6001b668e0..b6579912f8 100644 --- a/web/core/components/views/views-list.tsx +++ b/web/core/components/views/views-list.tsx @@ -25,7 +25,7 @@ export const ProjectViewsList = observer(() => { if (loader || !projectViews || !filteredProjectViews) return ; - if (filteredProjectViews.length === 0 && projectViews) { + if (filteredProjectViews.length === 0 && projectViews.length > 0) { return (
From 4d484577b513192e947ce91e05c6b62d62e2868a Mon Sep 17 00:00:00 2001 From: Nikhil <118773738+pablohashescobar@users.noreply.github.com> Date: Thu, 11 Jul 2024 13:47:32 +0530 Subject: [PATCH 6/8] dev: fix page versioning task (#5104) --- apiserver/plane/bgtasks/page_version_task.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apiserver/plane/bgtasks/page_version_task.py b/apiserver/plane/bgtasks/page_version_task.py index e29d28a85b..d8be197432 100644 --- a/apiserver/plane/bgtasks/page_version_task.py +++ b/apiserver/plane/bgtasks/page_version_task.py @@ -30,7 +30,7 @@ def page_version( workspace_id=page.workspace_id, description_html=page.description_html, description_binary=page.description_binary, - ownned_by_id=user_id, + owned_by_id=user_id, last_saved_at=page.updated_at, ) From 15b0a448eeacd1984fe63124342015b563e03202 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Thu, 11 Jul 2024 14:34:56 +0530 Subject: [PATCH 7/8] [WEB-1925] dev: issue detail widget enhancement (#5101) * chore: collapsible button border color updated * chore: TIssueDetailWidget type added * chore: issue link modal onClose updated * chore: issue detail widgets collapse state added to store * chore: issue detail widget interaction added * chore: issue detail widget interaction added --- packages/types/src/issues/issue.d.ts | 8 +++++- .../ui/src/collapsible/collapsible-button.tsx | 2 +- .../attachments/quick-action-button.tsx | 14 ++++++++--- .../issue-detail-widgets/attachments/root.tsx | 23 +++++++++++------ .../links/quick-action-button.tsx | 9 +++++-- .../issue-detail-widgets/links/root.tsx | 23 +++++++++++------ .../relations/quick-action-button.tsx | 4 ++- .../issue-detail-widgets/relations/root.tsx | 23 +++++++++++------ .../sub-issues/quick-action-button.tsx | 3 +++ .../issue-detail-widgets/sub-issues/root.tsx | 24 ++++++++++++------ .../links/create-update-link-modal.tsx | 6 ++--- .../issues/issue-detail/links/link-detail.tsx | 6 ++++- .../issues/issue-detail/links/link-item.tsx | 5 +++- .../issues/issue-detail/links/root.tsx | 6 ++++- .../store/issue/issue-details/root.store.ts | 25 +++++++++++++++++++ 15 files changed, 135 insertions(+), 46 deletions(-) diff --git a/packages/types/src/issues/issue.d.ts b/packages/types/src/issues/issue.d.ts index d86ab24d23..577b865c1f 100644 --- a/packages/types/src/issues/issue.d.ts +++ b/packages/types/src/issues/issue.d.ts @@ -84,7 +84,7 @@ export type TIssuesResponse = { total_pages: number; extra_stats: null; results: TIssueResponseResults; -} +}; export type TBulkIssueProperties = Pick< TIssue, @@ -100,3 +100,9 @@ export type TBulkOperationsPayload = { issue_ids: string[]; properties: Partial; }; + +export type TIssueDetailWidget = + | "sub-issues" + | "relations" + | "links" + | "attachments"; diff --git a/packages/ui/src/collapsible/collapsible-button.tsx b/packages/ui/src/collapsible/collapsible-button.tsx index 92b7ef90ac..a56a724b4c 100644 --- a/packages/ui/src/collapsible/collapsible-button.tsx +++ b/packages/ui/src/collapsible/collapsible-button.tsx @@ -13,7 +13,7 @@ type Props = { export const CollapsibleButton: FC = (props) => { const { isOpen, title, hideChevron = false, indicatorElement, actionItemElement } = props; return ( -
+
{!hideChevron && ( diff --git a/web/core/components/issues/issue-detail-widgets/attachments/quick-action-button.tsx b/web/core/components/issues/issue-detail-widgets/attachments/quick-action-button.tsx index fe2cfde308..2d7a5de86f 100644 --- a/web/core/components/issues/issue-detail-widgets/attachments/quick-action-button.tsx +++ b/web/core/components/issues/issue-detail-widgets/attachments/quick-action-button.tsx @@ -8,7 +8,7 @@ import { MAX_FILE_SIZE } from "@/constants/common"; // helper import { generateFileName } from "@/helpers/attachment.helper"; // hooks -import { useInstance } from "@/hooks/store"; +import { useInstance, useIssueDetail } from "@/hooks/store"; import { useAttachmentOperations } from "./helper"; @@ -22,11 +22,16 @@ type Props = { export const IssueAttachmentActionButton: FC = observer((props) => { const { workspaceSlug, projectId, issueId, customButton, disabled = false } = props; - // helper + // state const [isLoading, setIsLoading] = useState(false); + // store hooks const { config } = useInstance(); + const { setLastWidgetAction } = useIssueDetail(); + + // operations const handleAttachmentOperations = useAttachmentOperations(workspaceSlug, projectId, issueId); + // handlers const onDrop = useCallback( (acceptedFiles: File[]) => { const currentFile: File = acceptedFiles[0]; @@ -45,7 +50,10 @@ export const IssueAttachmentActionButton: FC = observer((props) => { }) ); setIsLoading(true); - handleAttachmentOperations.create(formData).finally(() => setIsLoading(false)); + handleAttachmentOperations.create(formData).finally(() => { + setLastWidgetAction("attachments"); + setIsLoading(false); + }); }, [handleAttachmentOperations, workspaceSlug] ); diff --git a/web/core/components/issues/issue-detail-widgets/attachments/root.tsx b/web/core/components/issues/issue-detail-widgets/attachments/root.tsx index 2c564f8149..3c7529cecc 100644 --- a/web/core/components/issues/issue-detail-widgets/attachments/root.tsx +++ b/web/core/components/issues/issue-detail-widgets/attachments/root.tsx @@ -1,11 +1,14 @@ "use client"; -import React, { FC, useState } from "react"; +import React, { FC } from "react"; +import { observer } from "mobx-react"; import { Collapsible } from "@plane/ui"; // components import { IssueAttachmentsCollapsibleContent, IssueAttachmentsCollapsibleTitle, } from "@/components/issues/issue-detail-widgets"; +// hooks +import { useIssueDetail } from "@/hooks/store"; type Props = { workspaceSlug: string; @@ -14,17 +17,21 @@ type Props = { disabled?: boolean; }; -export const AttachmentsCollapsible: FC = (props) => { +export const AttachmentsCollapsible: FC = observer((props) => { const { workspaceSlug, projectId, issueId, disabled = false } = props; - // state - const [isOpen, setIsOpen] = useState(false); + // store hooks + const { activeIssueDetailWidgets, toggleActiveIssueDetailWidget } = useIssueDetail(); + + // derived values + const isCollapsibleOpen = activeIssueDetailWidgets.includes("attachments"); + return ( setIsOpen((prev) => !prev)} + isOpen={isCollapsibleOpen} + onToggle={() => toggleActiveIssueDetailWidget("attachments")} title={ = (props) => { /> ); -}; +}); diff --git a/web/core/components/issues/issue-detail-widgets/links/quick-action-button.tsx b/web/core/components/issues/issue-detail-widgets/links/quick-action-button.tsx index 99c1ccf4d1..981005d78b 100644 --- a/web/core/components/issues/issue-detail-widgets/links/quick-action-button.tsx +++ b/web/core/components/issues/issue-detail-widgets/links/quick-action-button.tsx @@ -23,7 +23,7 @@ export const IssueLinksActionButton: FC = observer((props) => { const [isIssueLinkModal, setIsIssueLinkModal] = useState(false); // store hooks - const { toggleIssueLinkModal: toggleIssueLinkModalStore } = useIssueDetail(); + const { toggleIssueLinkModal: toggleIssueLinkModalStore, setLastWidgetAction } = useIssueDetail(); // helper const handleLinkOperations = useLinkOperations(workspaceSlug, projectId, issueId); @@ -43,11 +43,16 @@ export const IssueLinksActionButton: FC = observer((props) => { toggleIssueLinkModal(true); }; + const handleOnClose = () => { + toggleIssueLinkModal(false); + setLastWidgetAction("links"); + }; + return ( <>