From 9275e6f373ca48107a36d5744c92acc1ee9a41c1 Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com> Date: Thu, 20 Jul 2023 15:14:57 +0530 Subject: [PATCH] promote: develop to stage-release (#1589) * fix: onboarding invitations overflow (#1575) * fix: onboarding invitations overflow * fix: user avatar in the notification card * style: update graph grid color * fix: no 'Create by me' label coming up (#1573) * feat: added new issue subscriber table * dev: notification model * feat: added CRUD operation for issue subscriber * Revert "feat: added CRUD operation for issue subscriber" This reverts commit b22e0625768f0b096b5898936ace76d6882b0736. * feat: added CRUD operation for issue subscriber * dev: notification models and operations * dev: remove delete endpoint response data * dev: notification endpoints and fix bg worker for saving notifications * feat: added list and unsubscribe function in issue subscriber * dev: filter by snoozed and response update for list and permissions * dev: update issue notifications * dev: notification segregation * dev: update notifications * dev: notification filtering * dev: add issue name in notifications * dev: notification new endpoints * fix: pushing local settings * feat: notification workflow setup and made basic UI * style: improved UX with toast alerts and other interactions refactor: changed classnames according to new theme structure, changed all icons to material icons * feat: showing un-read notification count * feat: not showing 'subscribe' button on issue created by user & assigned to user not showing 'Create by you' for view & guest of the workspace * fix: 'read' -> 'unread' heading, my issue wrong filter * feat: made snooze dropdown & modal feat: switched to calendar * fix: minor ui fixes * feat: snooze modal date/time select * fix: params for read/un-read notification * style: snooze notification modal * fix: no label for 'Create by me' * fix: no label for 'Create by me' * fix: removed console log * fix: tooltip going behind popover --------- Co-authored-by: NarayanBavisetti Co-authored-by: pablohashescobar Co-authored-by: Aaryan Khandelwal * style: tooltip on notification header actions (#1577) * style: tooltip on notification header * chore: update tooltip content --------- Co-authored-by: Aaryan Khandelwal * fix: user migrations for back population (#1578) * fix: total notifications count (#1579) * fix: notification card (#1583) * feat: add new icons package (#1586) * feat: add material icons package * chore: replace issue view icons * chore: notification ordering (#1584) * fix: uuid error when cycle and module updates (#1585) * refactor: height of popover & api fetch call (#1587) * fix: snooze dropdown overflow (#1588) --------- Co-authored-by: Dakshesh Jain <65905942+dakshesh14@users.noreply.github.com> Co-authored-by: NarayanBavisetti Co-authored-by: pablohashescobar Co-authored-by: Nikhil <118773738+pablohashescobar@users.noreply.github.com> --- apiserver/plane/api/views/notification.py | 3 +- .../plane/bgtasks/issue_activites_task.py | 147 ++++++----- ...archived_at_project_archive_in_and_more.py | 4 +- .../components/account/email-code-form.tsx | 2 +- .../core/filters/issues-view-filter.tsx | 36 +-- .../notifications/notification-card.tsx | 229 ++++++++-------- .../notifications/notification-popover.tsx | 111 ++++---- .../components/onboarding/join-workspaces.tsx | 8 +- .../components/onboarding/tour/sidebar.tsx | 31 ++- .../project/single-sidebar-project.tsx | 38 ++- apps/app/components/ui/custom-menu.tsx | 187 ------------- .../components/ui/dropdowns/custom-menu.tsx | 18 +- .../app/components/workspace/help-section.tsx | 199 ++++---------- .../components/workspace/sidebar-dropdown.tsx | 6 +- .../app/components/workspace/sidebar-menu.tsx | 25 +- .../workspace/upgrade-to-pro-modal.tsx | 248 ------------------ apps/app/constants/graph.ts | 4 +- apps/app/helpers/date-time.helper.ts | 2 +- apps/app/hooks/use-user-notifications.tsx | 98 ++++--- apps/app/package.json | 2 + apps/app/pages/[workspaceSlug]/index.tsx | 8 +- .../[workspaceSlug]/settings/billing.tsx | 14 +- .../pages/[workspaceSlug]/settings/index.tsx | 5 +- apps/app/pages/index.tsx | 4 +- apps/app/pages/invitations.tsx | 162 ++++++------ apps/app/services/notifications.service.ts | 2 +- apps/app/styles/globals.css | 4 + yarn.lock | 157 +++++++++++ 28 files changed, 736 insertions(+), 1018 deletions(-) delete mode 100644 apps/app/components/ui/custom-menu.tsx delete mode 100644 apps/app/components/workspace/upgrade-to-pro-modal.tsx diff --git a/apiserver/plane/api/views/notification.py b/apiserver/plane/api/views/notification.py index e81fd2b5f..f0c8e05d5 100644 --- a/apiserver/plane/api/views/notification.py +++ b/apiserver/plane/api/views/notification.py @@ -30,7 +30,6 @@ class NotificationViewSet(BaseViewSet): def list(self, request, slug): try: - order_by = request.GET.get("order_by", "-created_at") snoozed = request.GET.get("snoozed", "false") archived = request.GET.get("archived", "false") read = request.GET.get("read", "true") @@ -40,7 +39,7 @@ class NotificationViewSet(BaseViewSet): notifications = Notification.objects.filter( workspace__slug=slug, receiver_id=request.user.id - ).order_by(order_by) + ).order_by("snoozed_till", "-created_at") # Filter for snoozed notifications if snoozed == "false": diff --git a/apiserver/plane/bgtasks/issue_activites_task.py b/apiserver/plane/bgtasks/issue_activites_task.py index e45ad9b32..523e4bc30 100644 --- a/apiserver/plane/bgtasks/issue_activites_task.py +++ b/apiserver/plane/bgtasks/issue_activites_task.py @@ -1028,21 +1028,26 @@ def issue_activity( actor = User.objects.get(pk=actor_id) project = Project.objects.get(pk=project_id) + if type not in [ + "cycle.activity.created", + "cycle.activity.deleted", + "module.activity.created", + "module.activity.deleted", + ]: + issue = Issue.objects.filter(pk=issue_id, project_id=project_id).first() - issue = Issue.objects.filter(pk=issue_id, project_id=project_id).first() + if issue is not None: + issue.updated_at = timezone.now() + issue.save(update_fields=["updated_at"]) - if issue is not None: - issue.updated_at = timezone.now() - issue.save(update_fields=["updated_at"]) - - if subscriber: - # add the user to issue subscriber - try: - _ = IssueSubscriber.objects.get_or_create( - issue_id=issue_id, subscriber=actor - ) - except Exception as e: - pass + if subscriber: + # add the user to issue subscriber + try: + _ = IssueSubscriber.objects.get_or_create( + issue_id=issue_id, subscriber=actor + ) + except Exception as e: + pass ACTIVITY_MAPPER = { "issue.activity.created": create_issue_activity, @@ -1094,67 +1099,79 @@ def issue_activity( except Exception as e: capture_exception(e) - # Create Notifications - bulk_notifications = [] + if type not in [ + "cycle.activity.created", + "cycle.activity.deleted", + "module.activity.created", + "module.activity.deleted", + ]: + # Create Notifications + bulk_notifications = [] - issue_subscribers = list( - IssueSubscriber.objects.filter(project=project, issue_id=issue_id) - .exclude(subscriber_id=actor_id) - .values_list("subscriber", flat=True) - ) + issue_subscribers = list( + IssueSubscriber.objects.filter(project=project, issue_id=issue_id) + .exclude(subscriber_id=actor_id) + .values_list("subscriber", flat=True) + ) - issue_assignees = list( - IssueAssignee.objects.filter(project=project, issue_id=issue_id) - .exclude(assignee_id=actor_id) - .values_list("assignee", flat=True) - ) + issue_assignees = list( + IssueAssignee.objects.filter(project=project, issue_id=issue_id) + .exclude(assignee_id=actor_id) + .values_list("assignee", flat=True) + ) - issue_subscribers = issue_subscribers + issue_assignees + issue_subscribers = issue_subscribers + issue_assignees - issue = Issue.objects.filter(pk=issue_id, project_id=project_id).first() + issue = Issue.objects.filter(pk=issue_id, project_id=project_id).first() - # Add bot filtering - if issue is not None and issue.created_by_id is not None and not issue.created_by.is_bot: - issue_subscribers = issue_subscribers + [issue.created_by_id] + # Add bot filtering + if ( + issue is not None + and issue.created_by_id is not None + and not issue.created_by.is_bot + ): + issue_subscribers = issue_subscribers + [issue.created_by_id] - for subscriber in issue_subscribers: - for issue_activity in issue_activities_created: - bulk_notifications.append( - Notification( - workspace=project.workspace, - sender="in_app:issue_activities", - triggered_by_id=actor_id, - receiver_id=subscriber, - entity_identifier=issue_id, - entity_name="issue", - project=project, - title=issue_activity.comment, - data={ - "issue": { - "id": str(issue_id), - "name": str(issue.name), - "identifier": str(project.identifier), - "sequence_id": issue.sequence_id, - "state_name": issue.state.name, - "state_group": issue.state.group, + for subscriber in issue_subscribers: + for issue_activity in issue_activities_created: + bulk_notifications.append( + Notification( + workspace=project.workspace, + sender="in_app:issue_activities", + triggered_by_id=actor_id, + receiver_id=subscriber, + entity_identifier=issue_id, + entity_name="issue", + project=project, + title=issue_activity.comment, + data={ + "issue": { + "id": str(issue_id), + "name": str(issue.name), + "identifier": str(project.identifier), + "sequence_id": issue.sequence_id, + "state_name": issue.state.name, + "state_group": issue.state.group, + }, + "issue_activity": { + "id": str(issue_activity.id), + "verb": str(issue_activity.verb), + "field": str(issue_activity.field), + "actor": str(issue_activity.actor_id), + "new_value": str(issue_activity.new_value), + "old_value": str(issue_activity.old_value), + "issue_comment": str( + issue_activity.issue_comment.comment_stripped + if issue_activity.issue_comment is not None + else "" + ), + }, }, - "issue_activity": { - "id": str(issue_activity.id), - "verb": str(issue_activity.verb), - "field": str(issue_activity.field), - "actor": str(issue_activity.actor_id), - "new_value": str(issue_activity.new_value), - "old_value": str(issue_activity.old_value), - "issue_comment": str( - issue_activity.issue_comment.comment_stripped if issue_activity.issue_comment is not None else "" - ), - }, - }, + ) ) - ) - # Bulk create notifications - Notification.objects.bulk_create(bulk_notifications, batch_size=100) + # Bulk create notifications + Notification.objects.bulk_create(bulk_notifications, batch_size=100) return except Exception as e: diff --git a/apiserver/plane/db/migrations/0037_issue_archived_at_project_archive_in_and_more.py b/apiserver/plane/db/migrations/0037_issue_archived_at_project_archive_in_and_more.py index bd2ff322f..d11e1afd8 100644 --- a/apiserver/plane/db/migrations/0037_issue_archived_at_project_archive_in_and_more.py +++ b/apiserver/plane/db/migrations/0037_issue_archived_at_project_archive_in_and_more.py @@ -8,6 +8,7 @@ import plane.db.models.user import uuid + def onboarding_default_steps(apps, schema_editor): default_onboarding_schema = { "workspace_join": True, @@ -23,7 +24,7 @@ def onboarding_default_steps(apps, schema_editor): obj.is_tour_completed = True updated_user.append(obj) - Model.objects.bulk_update(updated_user, ["onboarding_step"], batch_size=100) + Model.objects.bulk_update(updated_user, ["onboarding_step", "is_tour_completed"], batch_size=100) class Migration(migrations.Migration): @@ -79,6 +80,7 @@ class Migration(migrations.Migration): name="onboarding_step", field=models.JSONField(default=plane.db.models.user.get_default_onboarding), ), + migrations.RunPython(onboarding_default_steps), migrations.CreateModel( name="Notification", fields=[ diff --git a/apps/app/components/account/email-code-form.tsx b/apps/app/components/account/email-code-form.tsx index f745c5521..1e68cbb29 100644 --- a/apps/app/components/account/email-code-form.tsx +++ b/apps/app/components/account/email-code-form.tsx @@ -120,7 +120,7 @@ export const EmailCodeForm = ({ handleSignIn }: any) => { Please check your inbox at {watch("email")}

)} -
+
, + Icon: FormatListBulletedOutlined, }, { type: "kanban", - icon: , + Icon: GridViewOutlined, }, { type: "calendar", - icon: , + Icon: CalendarMonthOutlined, }, { type: "spreadsheet", - icon: , + Icon: TableChartOutlined, }, { type: "gantt_chart", - icon: , + Icon: WaterfallChartOutlined, }, ]; @@ -98,7 +100,12 @@ export const IssuesFilterView: React.FC = () => { }`} onClick={() => setIssueView(option.type)} > - {option.icon} + ))} @@ -177,7 +184,6 @@ export const IssuesFilterView: React.FC = () => { GROUP_BY_OPTIONS.find((option) => option.key === groupByProperty) ?.name ?? "Select" } - width="lg" > {GROUP_BY_OPTIONS.map((option) => issueView === "kanban" && option.key === null ? null : ( @@ -198,7 +204,6 @@ export const IssuesFilterView: React.FC = () => { ORDER_BY_OPTIONS.find((option) => option.key === orderBy)?.name ?? "Select" } - width="lg" > {ORDER_BY_OPTIONS.map((option) => groupByProperty === "priority" && option.key === "priority" ? null : ( @@ -223,7 +228,6 @@ export const IssuesFilterView: React.FC = () => { FILTER_ISSUE_OPTIONS.find((option) => option.key === filters.type) ?.name ?? "Select" } - width="lg" > {FILTER_ISSUE_OPTIONS.map((option) => ( = (props) => { `/${workspaceSlug}/projects/${notification.project}/issues/${notification.data.issue.id}` ); }} - className={`group relative py-3 px-6 cursor-pointer ${ + className={`group w-full flex items-center gap-4 p-3 pl-6 relative cursor-pointer ${ notification.read_at === null ? "bg-custom-primary-70/5" : "hover:bg-custom-background-200" }`} > {notification.read_at === null && ( )} -
-
- {notification.triggered_by_details.avatar && - notification.triggered_by_details.avatar !== "" ? ( +
+ {notification.triggered_by_details.avatar && + notification.triggered_by_details.avatar !== "" ? ( +
profile image - ) : ( -
- - {notification.triggered_by_details.first_name[0].toUpperCase()} - -
- )} -
-
-
- - {notification.triggered_by_details.first_name}{" "} - {notification.triggered_by_details.last_name}{" "} +
+ ) : ( +
+ + {notification.triggered_by_details.first_name[0].toUpperCase()} - {notification.data.issue_activity.field !== "comment" && - notification.data.issue_activity.verb}{" "} - {notification.data.issue_activity.field === "comment" - ? "commented" - : notification.data.issue_activity.field === "None" - ? null - : replaceUnderscoreIfSnakeCase(notification.data.issue_activity.field)}{" "} - {notification.data.issue_activity.field !== "comment" && - notification.data.issue_activity.field !== "None" - ? "to" - : ""} - - {" "} - {notification.data.issue_activity.field !== "None" ? ( - notification.data.issue_activity.field !== "comment" ? ( - notification.data.issue_activity.field === "target_date" ? ( - renderShortDateWithYearFormat(notification.data.issue_activity.new_value) - ) : notification.data.issue_activity.field === "attachment" ? ( - "the issue" - ) : stripHTML(notification.data.issue_activity.new_value).length > 55 ? ( - stripHTML(notification.data.issue_activity.new_value).slice(0, 50) + "..." - ) : ( - stripHTML(notification.data.issue_activity.new_value) - ) +
+ )} +
+
+
+ + {notification.triggered_by_details.first_name}{" "} + {notification.triggered_by_details.last_name}{" "} + + {notification.data.issue_activity.field !== "comment" && + notification.data.issue_activity.verb}{" "} + {notification.data.issue_activity.field === "comment" + ? "commented" + : notification.data.issue_activity.field === "None" + ? null + : replaceUnderscoreIfSnakeCase(notification.data.issue_activity.field)}{" "} + {notification.data.issue_activity.field !== "comment" && + notification.data.issue_activity.field !== "None" + ? "to" + : ""} + + {" "} + {notification.data.issue_activity.field !== "None" ? ( + notification.data.issue_activity.field !== "comment" ? ( + notification.data.issue_activity.field === "target_date" ? ( + renderShortDateWithYearFormat(notification.data.issue_activity.new_value) + ) : notification.data.issue_activity.field === "attachment" ? ( + "the issue" + ) : stripHTML(notification.data.issue_activity.new_value).length > 55 ? ( + stripHTML(notification.data.issue_activity.new_value).slice(0, 50) + "..." ) : ( - - {`"`} - {notification.data.issue_activity.new_value.length > 55 - ? notification?.data?.issue_activity?.issue_comment?.slice(0, 50) + "..." - : notification.data.issue_activity.issue_comment} - {`"`} - + stripHTML(notification.data.issue_activity.new_value) ) ) : ( - "the issue and assigned it to you." - )} - -
- -
-

- {notification.data.issue.identifier}-{notification.data.issue.sequence_id}{" "} - {notification.data.issue.name} -

- {notification.snoozed_till ? ( -

- - Till {renderShortDate(notification.snoozed_till)},{" "} - {render12HourFormatTime(notification.snoozed_till)} + {`"`} + {notification.data.issue_activity.new_value.length > 55 + ? notification?.data?.issue_activity?.issue_comment?.slice(0, 50) + "..." + : notification.data.issue_activity.issue_comment} + {`"`} -

+ ) ) : ( -

{formatDateDistance(notification.created_at)}

+ "the issue and assigned it to you." )} -
+ +
+ +
+

+ {truncateText( + `${notification.data.issue.identifier}-${notification.data.issue.sequence_id} ${notification.data.issue.name}`, + 50 + )} +

+ {notification.snoozed_till ? ( +

+ + + Till {renderShortDate(notification.snoozed_till)},{" "} + {render12HourFormatTime(notification.snoozed_till)} + +

+ ) : ( +

+ {formatDateDistance(notification.created_at)} +

+ )}
-
{[ { id: 1, - name: notification.read_at ? "Mark as Unread" : "Mark as Read", + name: notification.read_at ? "Mark as unread" : "Mark as read", icon: "chat_bubble", onClick: () => { markNotificationReadStatus(notification.id).then(() => { @@ -189,8 +192,8 @@ export const NotificationCard: React.FC = (props) => { }, { id: 2, - name: notification.archived_at ? "Unarchive Notification" : "Archive Notification", - icon: "archive", + name: notification.archived_at ? "Unarchive" : "Archive", + icon: notification.archived_at ? "unarchive" : "archive", onClick: () => { markNotificationArchivedStatus(notification.id).then(() => { setToastAlert({ @@ -203,7 +206,7 @@ export const NotificationCard: React.FC = (props) => { }, }, ].map((item) => ( - + ))} - - { - e.stopPropagation(); - }} - customButton={ - - } - optionsClassName="!z-20" - > - {snoozeOptions.map((item) => ( - { - e.stopPropagation(); + +
+ { + e.stopPropagation(); + }} + customButton={ + + } + optionsClassName="!z-20" + > + {snoozeOptions.map((item) => ( + { + e.stopPropagation(); - if (!item.value) { - setSelectedNotificationForSnooze(notification.id); - return; - } + if (!item.value) { + setSelectedNotificationForSnooze(notification.id); + return; + } - markSnoozeNotification(notification.id, item.value).then(() => { - setToastAlert({ - title: `Notification snoozed till ${renderLongDateFormat(item.value)}`, - type: "success", + markSnoozeNotification(notification.id, item.value).then(() => { + setToastAlert({ + title: `Notification snoozed till ${renderLongDateFormat(item.value)}`, + type: "success", + }); }); - }); - }} - > - {item.label} - - ))} - + }} + > + {item.label} + + ))} + +
diff --git a/apps/app/components/notifications/notification-popover.tsx b/apps/app/components/notifications/notification-popover.tsx index 5ab2220f5..a8652e7ff 100644 --- a/apps/app/components/notifications/notification-popover.tsx +++ b/apps/app/components/notifications/notification-popover.tsx @@ -12,8 +12,10 @@ import useWorkspaceMembers from "hooks/use-workspace-members"; import useUserNotification from "hooks/use-user-notifications"; // components -import { Icon, Loader, EmptyState } from "components/ui"; +import { Icon, Loader, EmptyState, Tooltip } from "components/ui"; import { SnoozeNotificationModal, NotificationCard } from "components/notifications"; +// icons +import { NotificationsOutlined } from "@mui/icons-material"; // images import emptyNotification from "public/empty-state/notification.svg"; // helpers @@ -69,7 +71,7 @@ export const NotificationPopover = () => { { label: "Subscribed", value: "watching", - unreadCount: notificationCount?.watching_notifications, + unreadCount: notificationCount?.watching_issues, }, ]; @@ -96,10 +98,10 @@ export const NotificationPopover = () => { className={`group flex w-full items-center gap-2.5 rounded-md px-3 py-2 text-sm font-medium outline-none ${ isActive ? "bg-custom-primary-100/10 text-custom-primary-100" - : "text-custom-sidebar-text-200 hover:bg-custom-sidebar-background-80 focus:bg-custom-sidebar-background-80" + : "text-custom-sidebar-text-200 hover:bg-custom-sidebar-background-80" } ${sidebarCollapse ? "justify-center" : ""}`} > - + {sidebarCollapse ? null : Notifications} {totalNotificationCount && totalNotificationCount > 0 ? ( @@ -116,54 +118,62 @@ export const NotificationPopover = () => { leaveFrom="opacity-100 translate-y-0" leaveTo="opacity-0 translate-y-1" > - +

Notifications

- - - - + const target = e.target as HTMLButtonElement; + target?.classList.add("animate-spin"); + setTimeout(() => { + target?.classList.remove("animate-spin"); + }, 1000); + }} + > + + + + + + + + + + + + @@ -205,6 +215,7 @@ export const NotificationPopover = () => { : "border-transparent text-custom-text-200" }`} > + {tab.label} {tab.unreadCount && tab.unreadCount > 0 ? ( { {notifications ? ( notifications.length > 0 ? ( -
+
{notifications.map((notification) => ( {
) ) : ( - + diff --git a/apps/app/components/onboarding/join-workspaces.tsx b/apps/app/components/onboarding/join-workspaces.tsx index b49fad60d..2441542d6 100644 --- a/apps/app/components/onboarding/join-workspaces.tsx +++ b/apps/app/components/onboarding/join-workspaces.tsx @@ -88,7 +88,7 @@ export const JoinWorkspaces: React.FC = ({ stepChange }) => {
We see that someone has invited you to

Join a workspace

-
+
{invitations && invitations.map((invitation) => { const isSelected = invitationsRespond.includes(invitation.id); @@ -146,7 +146,11 @@ export const JoinWorkspaces: React.FC = ({ stepChange }) => { > Accept & Join - + Skip for now
diff --git a/apps/app/components/onboarding/tour/sidebar.tsx b/apps/app/components/onboarding/tour/sidebar.tsx index 99832c166..dce49f098 100644 --- a/apps/app/components/onboarding/tour/sidebar.tsx +++ b/apps/app/components/onboarding/tour/sidebar.tsx @@ -1,31 +1,37 @@ -// ui -import { Icon } from "components/ui"; +// icons +import { + ArticleOutlined, + ContrastOutlined, + DatasetOutlined, + FilterNoneOutlined, + PhotoFilterOutlined, +} from "@mui/icons-material"; // types import { TTourSteps } from "./root"; const sidebarOptions: { key: TTourSteps; - icon: string; + Icon: any; }[] = [ { key: "issues", - icon: "stack", + Icon: FilterNoneOutlined, }, { key: "cycles", - icon: "contrast", + Icon: ContrastOutlined, }, { key: "modules", - icon: "dataset", + Icon: DatasetOutlined, }, { key: "views", - icon: "photo_filter", + Icon: PhotoFilterOutlined, }, { key: "pages", - icon: "article", + Icon: ArticleOutlined, }, ]; @@ -52,11 +58,10 @@ export const TourSidebar: React.FC = ({ step, setStep }) => ( }`} onClick={() => setStep(option.key)} > -
{!sidebarCollapse && ( - )} @@ -211,7 +221,7 @@ export const SingleSidebarProject: React.FC = ({ } >
- + Archived Issues
@@ -248,13 +258,17 @@ export const SingleSidebarProject: React.FC = ({ disabled={!sidebarCollapse} >
- + {!sidebarCollapse && item.name}
diff --git a/apps/app/components/ui/custom-menu.tsx b/apps/app/components/ui/custom-menu.tsx deleted file mode 100644 index ab11ca16f..000000000 --- a/apps/app/components/ui/custom-menu.tsx +++ /dev/null @@ -1,187 +0,0 @@ -import React from "react"; -// next -import Link from "next/link"; -// headless ui -import { Menu, Transition } from "@headlessui/react"; -// icons -import { ChevronDownIcon } from "@heroicons/react/24/outline"; -import { Icon } from "./icon"; - -type Props = { - children: React.ReactNode; - label?: string | JSX.Element; - className?: string; - ellipsis?: boolean; - verticalEllipsis?: boolean; - height?: "sm" | "md" | "rg" | "lg"; - width?: "sm" | "md" | "lg" | "xl" | "auto"; - textAlignment?: "left" | "center" | "right"; - noBorder?: boolean; - noChevron?: boolean; - position?: "left" | "right"; - verticalPosition?: "top" | "bottom"; - menuItemsClassName?: string; - customButton?: JSX.Element; - menuItemsWhiteBg?: boolean; -}; - -type MenuItemProps = { - children: JSX.Element | string; - renderAs?: "button" | "a"; - href?: string; - onClick?: (args?: any) => void; - className?: string; -}; - -const CustomMenu = ({ - children, - label, - className = "", - ellipsis = false, - verticalEllipsis = false, - height = "md", - width = "auto", - textAlignment, - noBorder = false, - noChevron = false, - position = "right", - verticalPosition = "bottom", - menuItemsClassName = "", - customButton, - menuItemsWhiteBg = false, -}: Props) => ( - - {({ open }) => ( - <> - {customButton ? ( - {customButton} - ) : ( -
- {ellipsis || verticalEllipsis ? ( - - - - ) : ( - - {label} - {!noChevron && - )} -
- )} - - - -
{children}
-
-
- - )} -
-); - -const MenuItem: React.FC = ({ - children, - renderAs, - href, - onClick, - className = "", -}) => ( - - {({ active, close }) => - renderAs === "a" ? ( - - - {children} - - - ) : ( - - ) - } - -); - -CustomMenu.MenuItem = MenuItem; - -export { CustomMenu }; diff --git a/apps/app/components/ui/dropdowns/custom-menu.tsx b/apps/app/components/ui/dropdowns/custom-menu.tsx index e33583ce0..315349195 100644 --- a/apps/app/components/ui/dropdowns/custom-menu.tsx +++ b/apps/app/components/ui/dropdowns/custom-menu.tsx @@ -4,9 +4,10 @@ import Link from "next/link"; // headless ui import { Menu, Transition } from "@headlessui/react"; +// ui +import { DropdownProps } from "components/ui"; // icons -import { DropdownProps, Icon } from "components/ui"; -import { ChevronDownIcon } from "@heroicons/react/24/outline"; +import { ExpandMoreOutlined, MoreHorizOutlined } from "@mui/icons-material"; export type CustomMenuProps = DropdownProps & { children: React.ReactNode; @@ -53,8 +54,8 @@ const CustomMenu = ({ disabled ? "cursor-not-allowed" : "cursor-pointer hover:bg-custom-background-80" } ${buttonClassName}`} > - @@ -72,7 +73,14 @@ const CustomMenu = ({ } ${buttonClassName}`} > {label} - {!noChevron &&
diff --git a/apps/app/pages/[workspaceSlug]/settings/index.tsx b/apps/app/pages/[workspaceSlug]/settings/index.tsx index c80386da9..6306605ed 100644 --- a/apps/app/pages/[workspaceSlug]/settings/index.tsx +++ b/apps/app/pages/[workspaceSlug]/settings/index.tsx @@ -207,7 +207,10 @@ const WorkspaceSettings: NextPage = () => { {isImageUploading ? "Uploading..." : "Upload"} {activeWorkspace.logo && activeWorkspace.logo !== "" && ( - handleDelete(activeWorkspace.logo)}> + handleDelete(activeWorkspace.logo)} + loading={isImageRemoving} + > {isImageRemoving ? "Removing..." : "Remove"} )} diff --git a/apps/app/pages/index.tsx b/apps/app/pages/index.tsx index 121bd9f70..6cef211c0 100644 --- a/apps/app/pages/index.tsx +++ b/apps/app/pages/index.tsx @@ -145,11 +145,11 @@ const HomePage: NextPage = () => {

Sign in to Plane

-
+
-
+
diff --git a/apps/app/pages/invitations.tsx b/apps/app/pages/invitations.tsx index e93fabd17..40a687ff6 100644 --- a/apps/app/pages/invitations.tsx +++ b/apps/app/pages/invitations.tsx @@ -105,91 +105,93 @@ const OnBoard: NextPage = () => { {user?.email}
- {invitations && invitations.length > 0 ? ( -
-
-
We see that someone has invited you to
-

Join a workspace

-
- {invitations.map((invitation) => { - const isSelected = invitationsRespond.includes(invitation.id); + {invitations ? ( + invitations.length > 0 ? ( +
+
+
We see that someone has invited you to
+

Join a workspace

+
+ {invitations.map((invitation) => { + const isSelected = invitationsRespond.includes(invitation.id); - return ( -
- handleInvitation(invitation, isSelected ? "withdraw" : "accepted") - } - > -
-
- {invitation.workspace.logo && invitation.workspace.logo !== "" ? ( - {invitation.workspace.name} - ) : ( - - {invitation.workspace.name[0]} - - )} -
-
-
-
- {truncateText(invitation.workspace.name, 30)} -
-

{ROLE[invitation.role]}

-
- + handleInvitation(invitation, isSelected ? "withdraw" : "accepted") + } > - - -
- ); - })} -
-
- - Accept & Join - - - - - Go Home - - - +
+
+ {invitation.workspace.logo && invitation.workspace.logo !== "" ? ( + {invitation.workspace.name} + ) : ( + + {invitation.workspace.name[0]} + + )} +
+
+
+
+ {truncateText(invitation.workspace.name, 30)} +
+

{ROLE[invitation.role]}

+
+ + + +
+ ); + })} +
+
+ + Accept & Join + + + + + Go Home + + + +
-
- ) : ( -
- router.push("/")} - /> -
- )} + ) : ( +
+ router.push("/")} + /> +
+ ) + ) : null}
diff --git a/apps/app/services/notifications.service.ts b/apps/app/services/notifications.service.ts index f2b49b954..412b03988 100644 --- a/apps/app/services/notifications.service.ts +++ b/apps/app/services/notifications.service.ts @@ -159,7 +159,7 @@ class UserNotificationsServices extends APIService { async getUnreadNotificationsCount(workspaceSlug: string): Promise<{ created_issues: number; my_issues: number; - watching_notifications: number; + watching_issues: number; }> { return this.get(`/api/workspaces/${workspaceSlug}/users/notifications/unread/`) .then((response) => response?.data) diff --git a/apps/app/styles/globals.css b/apps/app/styles/globals.css index 4e68cd503..aba03a248 100644 --- a/apps/app/styles/globals.css +++ b/apps/app/styles/globals.css @@ -295,3 +295,7 @@ body { :-ms-input-placeholder { color: rgb(var(--color-text-400)); } + +.bp4-overlay-content { + z-index: 555 !important; +} diff --git a/yarn.lock b/yarn.lock index 652df3ed8..4a8d0a942 100644 --- a/yarn.lock +++ b/yarn.lock @@ -899,6 +899,13 @@ dependencies: regenerator-runtime "^0.13.11" +"@babel/runtime@^7.22.5", "@babel/runtime@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.6.tgz#57d64b9ae3cff1d67eb067ae117dac087f5bd438" + integrity sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ== + dependencies: + regenerator-runtime "^0.13.11" + "@babel/template@^7.18.10", "@babel/template@^7.20.7": version "7.20.7" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8" @@ -1005,6 +1012,17 @@ "@emotion/weak-memoize" "^0.3.0" stylis "4.1.4" +"@emotion/cache@^11.11.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.11.0.tgz#809b33ee6b1cb1a625fef7a45bc568ccd9b8f3ff" + integrity sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ== + dependencies: + "@emotion/memoize" "^0.8.1" + "@emotion/sheet" "^1.2.2" + "@emotion/utils" "^1.2.1" + "@emotion/weak-memoize" "^0.3.1" + stylis "4.2.0" + "@emotion/css@^11.10.6": version "11.10.8" resolved "https://registry.yarnpkg.com/@emotion/css/-/css-11.10.8.tgz#9dec9996ad9a1cc28ec8d26b1b27ab0b8f6fb053" @@ -1028,11 +1046,23 @@ dependencies: "@emotion/memoize" "^0.8.0" +"@emotion/is-prop-valid@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz#23116cf1ed18bfeac910ec6436561ecb1a3885cc" + integrity sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw== + dependencies: + "@emotion/memoize" "^0.8.1" + "@emotion/memoize@^0.8.0": version "0.8.0" resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.0.tgz#f580f9beb67176fa57aae70b08ed510e1b18980f" integrity sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA== +"@emotion/memoize@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17" + integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA== + "@emotion/react@^11.10.6": version "11.10.8" resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.10.8.tgz#02e274ecb45e03ab9d7a8eb9f0f0c064613eaf7b" @@ -1063,6 +1093,11 @@ resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.1.tgz#0767e0305230e894897cadb6c8df2c51e61a6c2c" integrity sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA== +"@emotion/sheet@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.2.tgz#d58e788ee27267a14342303e1abb3d508b6d0fec" + integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA== + "@emotion/styled@^11.10.6": version "11.10.8" resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.10.8.tgz#a3fd68efd90bd7e8a06b82b95adec643d386fa69" @@ -1090,11 +1125,21 @@ resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.0.tgz#9716eaccbc6b5ded2ea5a90d65562609aab0f561" integrity sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw== +"@emotion/utils@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.1.tgz#bbab58465738d31ae4cb3dbb6fc00a5991f755e4" + integrity sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg== + "@emotion/weak-memoize@^0.3.0": version "0.3.0" resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz#ea89004119dc42db2e1dba0f97d553f7372f6fcb" integrity sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg== +"@emotion/weak-memoize@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz#d0fce5d07b0620caa282b5131c297bb60f9d87e6" + integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww== + "@eslint-community/eslint-utils@^4.2.0": version "4.4.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" @@ -1333,11 +1378,37 @@ prop-types "^15.8.1" react-is "^18.2.0" +"@mui/base@5.0.0-beta.8": + version "5.0.0-beta.8" + resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-beta.8.tgz#a0a9531ae9147be92d17e4f0e3b9accc57916841" + integrity sha512-b4vVjMZx5KzzEMf4arXKoeV5ZegAMOoPwoy1vfUBwhvXc2QtaaAyBp50U7OA2L06Leubc1A+lEp3eqwZoFn87g== + dependencies: + "@babel/runtime" "^7.22.6" + "@emotion/is-prop-valid" "^1.2.1" + "@mui/types" "^7.2.4" + "@mui/utils" "^5.14.1" + "@popperjs/core" "^2.11.8" + clsx "^1.2.1" + prop-types "^15.8.1" + react-is "^18.2.0" + "@mui/core-downloads-tracker@^5.12.3": version "5.12.3" resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.12.3.tgz#3dffe62dccc065ddd7338e97d7be4b917004287e" integrity sha512-yiJZ+knaknPHuRKhRk4L6XiwppwkAahVal3LuYpvBH7GkA2g+D9WLEXOEnNYtVFUggyKf6fWGLGnx0iqzkU5YA== +"@mui/core-downloads-tracker@^5.14.1": + version "5.14.1" + resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.1.tgz#af156cb3e15b202f5c09f66e7d8b71ca86aef525" + integrity sha512-mIa1WmDmNr1LoupV1Rbxt9bTFKMbIn10RHG1bnZ/FJCkAYpuU/D4n+R+ttiycgcZNngU++zyh/OQeJblzbQPzg== + +"@mui/icons-material@^5.14.1": + version "5.14.1" + resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.14.1.tgz#2f145c15047a0c7f01353ce620cb88276dadba9e" + integrity sha512-xV/f26muQqtWzerzOIdGPrXoxp/OKaE2G2Wp9gnmG47mHua5Slup/tMc3fA4ZYUreGGrK6+tT81TEvt1Wsng8Q== + dependencies: + "@babel/runtime" "^7.22.6" + "@mui/material@^5.12.1": version "5.12.3" resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.12.3.tgz#398c1b123fb065763558bc1f9fc47d1f8cb87d0c" @@ -1356,6 +1427,24 @@ react-is "^18.2.0" react-transition-group "^4.4.5" +"@mui/material@^5.14.1": + version "5.14.1" + resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.14.1.tgz#2711e4ca5c9bdc67b916d01faee650a7a5260bb8" + integrity sha512-WtsgYuageTunLfxH3Ri+o1RuQTFImtRHxMcVNyD0Hhd2/znjW6KODNz0XfjvLRnNCAynBxZNiflcoIBW40h9PQ== + dependencies: + "@babel/runtime" "^7.22.6" + "@mui/base" "5.0.0-beta.8" + "@mui/core-downloads-tracker" "^5.14.1" + "@mui/system" "^5.14.1" + "@mui/types" "^7.2.4" + "@mui/utils" "^5.14.1" + "@types/react-transition-group" "^4.4.6" + clsx "^1.2.1" + csstype "^3.1.2" + prop-types "^15.8.1" + react-is "^18.2.0" + react-transition-group "^4.4.5" + "@mui/private-theming@^5.12.3": version "5.12.3" resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.12.3.tgz#f5e4704e25d9d91b906561cae573cda8f3801e10" @@ -1365,6 +1454,15 @@ "@mui/utils" "^5.12.3" prop-types "^15.8.1" +"@mui/private-theming@^5.13.7": + version "5.13.7" + resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.13.7.tgz#2f8ef5da066f3c6c6423bd4260d003a28d10b099" + integrity sha512-qbSr+udcij5F9dKhGX7fEdx2drXchq7htLNr2Qg2Ma+WJ6q0ERlEqGSBiPiVDJkptcjeVL4DGmcf1wl5+vD4EA== + dependencies: + "@babel/runtime" "^7.22.5" + "@mui/utils" "^5.13.7" + prop-types "^15.8.1" + "@mui/styled-engine@^5.12.3": version "5.12.3" resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.12.3.tgz#3307643d52c81947a624cdd0437536cc8109c4f0" @@ -1375,6 +1473,16 @@ csstype "^3.1.2" prop-types "^15.8.1" +"@mui/styled-engine@^5.13.2": + version "5.13.2" + resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.13.2.tgz#c87bd61c0ab8086d34828b6defe97c02bcd642ef" + integrity sha512-VCYCU6xVtXOrIN8lcbuPmoG+u7FYuOERG++fpY74hPpEWkyFQG97F+/XfTQVYzlR2m7nPjnwVUgATcTCMEaMvw== + dependencies: + "@babel/runtime" "^7.21.0" + "@emotion/cache" "^11.11.0" + csstype "^3.1.2" + prop-types "^15.8.1" + "@mui/system@^5.12.3": version "5.12.3" resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.12.3.tgz#306b3cdffa3046067640219c1e5dd7e3dae38ff9" @@ -1389,6 +1497,20 @@ csstype "^3.1.2" prop-types "^15.8.1" +"@mui/system@^5.14.1": + version "5.14.1" + resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.14.1.tgz#ec8ae69f63963b5916dad4bca2f8a86a001a2392" + integrity sha512-u+xlsU34Jdkgx1CxmBnIC4Y08uPdVX5iEd3S/1dggDFtOGp+Lj8xmKRJAQ8PJOOJLOh8pDwaZx4AwXikL4l1QA== + dependencies: + "@babel/runtime" "^7.22.6" + "@mui/private-theming" "^5.13.7" + "@mui/styled-engine" "^5.13.2" + "@mui/types" "^7.2.4" + "@mui/utils" "^5.14.1" + clsx "^1.2.1" + csstype "^3.1.2" + prop-types "^15.8.1" + "@mui/types@^7.2.4": version "7.2.4" resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.4.tgz#b6fade19323b754c5c6de679a38f068fd50b9328" @@ -1405,6 +1527,17 @@ prop-types "^15.8.1" react-is "^18.2.0" +"@mui/utils@^5.13.7", "@mui/utils@^5.14.1": + version "5.14.1" + resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.14.1.tgz#29696371016552a6eb3af975bc7af429ec88b29a" + integrity sha512-39KHKK2JeqRmuUcLDLwM+c2XfVC136C5/yUyQXmO2PVbOb2Bol4KxtkssEqCbTwg87PSCG3f1Tb0keRsK7cVGw== + dependencies: + "@babel/runtime" "^7.22.6" + "@types/prop-types" "^15.7.5" + "@types/react-is" "^18.2.1" + prop-types "^15.8.1" + react-is "^18.2.0" + "@next/env@12.3.2": version "12.3.2" resolved "https://registry.yarnpkg.com/@next/env/-/env-12.3.2.tgz#fb819366771f5721e9438ca3a42ad18684f0949b" @@ -1684,6 +1817,11 @@ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.7.tgz#ccab5c8f7dc557a52ca3288c10075c9ccd37fff7" integrity sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw== +"@popperjs/core@^2.11.8": + version "2.11.8" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" + integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== + "@radix-ui/primitive@1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.0.0.tgz#e1d8ef30b10ea10e69c76e896f608d9276352253" @@ -3230,6 +3368,13 @@ dependencies: "@types/react" "^17" +"@types/react-is@^18.2.1": + version "18.2.1" + resolved "https://registry.yarnpkg.com/@types/react-is/-/react-is-18.2.1.tgz#61d01c2a6fc089a53520c0b66996d458fdc46863" + integrity sha512-wyUkmaaSZEzFZivD8F2ftSyAfk6L+DfFliVj/mYdOXbVjRcS87fQJLTnhk6dRZPuJjI+9g6RZJO4PNCngUrmyw== + dependencies: + "@types/react" "*" + "@types/react-redux@^7.1.20": version "7.1.25" resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.25.tgz#de841631205b24f9dfb4967dd4a7901e048f9a88" @@ -3247,6 +3392,13 @@ dependencies: "@types/react" "*" +"@types/react-transition-group@^4.4.6": + version "4.4.6" + resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.6.tgz#18187bcda5281f8e10dfc48f0943e2fdf4f75e2e" + integrity sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew== + dependencies: + "@types/react" "*" + "@types/react@*", "@types/react@^18.0.17": version "18.2.3" resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.3.tgz#509ad6c4c77378e686f9bb6e0f8756936392f0e8" @@ -7947,6 +8099,11 @@ stylis@4.1.4: resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.1.4.tgz#9cb60e7153d8ac6d02d773552bf51c7a0344535b" integrity sha512-USf5pszRYwuE6hg9by0OkKChkQYEXfkeTtm0xKw+jqQhwyjCVLdYyMBK7R+n7dhzsblAWJnGxju4vxq5eH20GQ== +stylis@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51" + integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== + sucrase@^3.32.0: version "3.32.0" resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.32.0.tgz#c4a95e0f1e18b6847127258a75cf360bc568d4a7"