diff --git a/README.md b/README.md index 20e34b673..2bc2764f3 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,16 @@ chmod +x setup.sh > If running in a cloud env replace localhost with public facing IP address of the VM +- Setup Tiptap Pro + + Visit [Tiptap Pro](https://collab.tiptap.dev/pro-extensions) and signup (it is free). + + Create a **`.npmrc`** file, copy the following and replace your registry token generated from Tiptap Pro. + +``` +@tiptap-pro:registry=https://registry.tiptap.dev/ +//registry.tiptap.dev/:_authToken=YOUR_REGISTRY_TOKEN +``` - Run Docker compose up ```bash diff --git a/apiserver/plane/api/views/issue.py b/apiserver/plane/api/views/issue.py index 77432e1e0..6f0f1e6ae 100644 --- a/apiserver/plane/api/views/issue.py +++ b/apiserver/plane/api/views/issue.py @@ -370,7 +370,7 @@ class UserWorkSpaceIssues(BaseAPIView): ) ) .filter(**filters) - ) + ).distinct() # Priority Ordering if order_by_param == "priority" or order_by_param == "-priority": diff --git a/apiserver/plane/api/views/workspace.py b/apiserver/plane/api/views/workspace.py index eca18163a..cfdd0dd9b 100644 --- a/apiserver/plane/api/views/workspace.py +++ b/apiserver/plane/api/views/workspace.py @@ -994,11 +994,11 @@ class UserWorkspaceDashboardEndpoint(BaseAPIView): upcoming_issues = Issue.issue_objects.filter( ~Q(state__group__in=["completed", "cancelled"]), - target_date__gte=timezone.now(), + start_date__gte=timezone.now(), workspace__slug=slug, assignees__in=[request.user], completed_at__isnull=True, - ).values("id", "name", "workspace__slug", "project_id", "target_date") + ).values("id", "name", "workspace__slug", "project_id", "start_date") return Response( { @@ -1083,6 +1083,7 @@ class WorkspaceUserProfileStatsEndpoint(BaseAPIView): .filter(**filters) .values("priority") .annotate(priority_count=Count("priority")) + .filter(priority_count__gte=1) .annotate( priority_order=Case( *[ diff --git a/apiserver/plane/bgtasks/issue_activites_task.py b/apiserver/plane/bgtasks/issue_activites_task.py index 9150d7c94..1cc6c85cc 100644 --- a/apiserver/plane/bgtasks/issue_activites_task.py +++ b/apiserver/plane/bgtasks/issue_activites_task.py @@ -184,19 +184,24 @@ def track_description( if current_instance.get("description_html") != requested_data.get( "description_html" ): - issue_activities.append( - IssueActivity( - issue_id=issue_id, - actor=actor, - verb="updated", - old_value=current_instance.get("description_html"), - new_value=requested_data.get("description_html"), - field="description", - project=project, - workspace=project.workspace, - comment=f"updated the description to {requested_data.get('description_html')}", - ) - ) + last_activity = IssueActivity.objects.filter(issue_id=issue_id).order_by("-created_at").first() + if(last_activity is not None and last_activity.field == "description" and actor.id == last_activity.actor_id): + last_activity.created_at = timezone.now() + last_activity.save(update_fields=["created_at"]) + else: + issue_activities.append( + IssueActivity( + issue_id=issue_id, + actor=actor, + verb="updated", + old_value=current_instance.get("description_html"), + new_value=requested_data.get("description_html"), + field="description", + project=project, + workspace=project.workspace, + comment=f"updated the description to {requested_data.get('description_html')}", + ) + ) # Track changes in issue target date diff --git a/apiserver/plane/db/migrations/0041_cycle_sort_order_issuecomment_access_and_more.py b/apiserver/plane/db/migrations/0041_cycle_sort_order_issuecomment_access_and_more.py index bffa89d23..07c302c76 100644 --- a/apiserver/plane/db/migrations/0041_cycle_sort_order_issuecomment_access_and_more.py +++ b/apiserver/plane/db/migrations/0041_cycle_sort_order_issuecomment_access_and_more.py @@ -227,6 +227,11 @@ class Migration(migrations.Migration): 'unique_together': {('issue', 'actor')}, }, ), + migrations.AlterField( + model_name='modulelink', + name='title', + field=models.CharField(blank=True, max_length=255, null=True), + ), migrations.RunPython(generate_display_name), migrations.RunPython(rectify_field_issue_activity), migrations.RunPython(update_assignee_issue_activity), diff --git a/apiserver/plane/db/models/module.py b/apiserver/plane/db/models/module.py index ad1e16080..e286d297a 100644 --- a/apiserver/plane/db/models/module.py +++ b/apiserver/plane/db/models/module.py @@ -98,7 +98,7 @@ class ModuleIssue(ProjectBaseModel): class ModuleLink(ProjectBaseModel): - title = models.CharField(max_length=255, null=True) + title = models.CharField(max_length=255, blank=True, null=True) url = models.URLField() module = models.ForeignKey( Module, on_delete=models.CASCADE, related_name="link_module" diff --git a/apps/app/components/analytics/scope-and-demand/leaderboard.tsx b/apps/app/components/analytics/scope-and-demand/leaderboard.tsx index 156c09d4c..e52657c03 100644 --- a/apps/app/components/analytics/scope-and-demand/leaderboard.tsx +++ b/apps/app/components/analytics/scope-and-demand/leaderboard.tsx @@ -1,3 +1,8 @@ +// ui +import { ProfileEmptyState } from "components/ui"; +// image +import emptyUsers from "public/empty-state/empty_users.svg"; + type Props = { users: { avatar: string | null; @@ -8,10 +13,16 @@ type Props = { id: string; }[]; title: string; + emptyStateMessage: string; workspaceSlug: string; }; -export const AnalyticsLeaderboard: React.FC = ({ users, title, workspaceSlug }) => ( +export const AnalyticsLeaderboard: React.FC = ({ + users, + title, + emptyStateMessage, + workspaceSlug, +}) => (
{title}
{users.length > 0 ? ( @@ -47,7 +58,9 @@ export const AnalyticsLeaderboard: React.FC = ({ users, title, workspaceS ))}
) : ( -
No matching data found.
+
+ +
)} ); diff --git a/apps/app/components/analytics/scope-and-demand/scope-and-demand.tsx b/apps/app/components/analytics/scope-and-demand/scope-and-demand.tsx index 7f40ee79a..dc7e65515 100644 --- a/apps/app/components/analytics/scope-and-demand/scope-and-demand.tsx +++ b/apps/app/components/analytics/scope-and-demand/scope-and-demand.tsx @@ -63,6 +63,7 @@ export const ScopeAndDemand: React.FC = ({ fullScreen = true }) => { id: user?.created_by__id, }))} title="Most issues created" + emptyStateMessage="Co-workers and the number issues created by them appears here." workspaceSlug={workspaceSlug?.toString() ?? ""} /> = ({ fullScreen = true }) => { id: user?.assignees__id, }))} title="Most issues closed" + emptyStateMessage="Co-workers and the number issues closed by them appears here." workspaceSlug={workspaceSlug?.toString() ?? ""} />
diff --git a/apps/app/components/analytics/scope-and-demand/scope.tsx b/apps/app/components/analytics/scope-and-demand/scope.tsx index 15b9e18de..b01354b93 100644 --- a/apps/app/components/analytics/scope-and-demand/scope.tsx +++ b/apps/app/components/analytics/scope-and-demand/scope.tsx @@ -1,5 +1,7 @@ // ui -import { BarGraph } from "components/ui"; +import { BarGraph, ProfileEmptyState } from "components/ui"; +// image +import emptyBarGraph from "public/empty-state/empty_bar_graph.svg"; // types import { IDefaultAnalyticsResponse } from "types"; @@ -70,8 +72,12 @@ export const AnalyticsScope: React.FC = ({ defaultAnalytics }) => ( }} /> ) : ( -
- No matching data found. +
+
)}
diff --git a/apps/app/components/analytics/scope-and-demand/year-wise-issues.tsx b/apps/app/components/analytics/scope-and-demand/year-wise-issues.tsx index 621706f0e..87127ed60 100644 --- a/apps/app/components/analytics/scope-and-demand/year-wise-issues.tsx +++ b/apps/app/components/analytics/scope-and-demand/year-wise-issues.tsx @@ -1,5 +1,7 @@ // ui -import { LineGraph } from "components/ui"; +import { LineGraph, ProfileEmptyState } from "components/ui"; +// image +import emptyGraph from "public/empty-state/empty_graph.svg"; // types import { IDefaultAnalyticsResponse } from "types"; // constants @@ -48,7 +50,13 @@ export const AnalyticsYearWiseIssues: React.FC = ({ defaultAnalytics }) = enableArea /> ) : ( -
No matching data found.
+
+ +
)}
); diff --git a/apps/app/components/command-palette/change-interface-theme.tsx b/apps/app/components/command-palette/change-interface-theme.tsx index 34ebf3562..87d1289ae 100644 --- a/apps/app/components/command-palette/change-interface-theme.tsx +++ b/apps/app/components/command-palette/change-interface-theme.tsx @@ -9,12 +9,18 @@ import userService from "services/user.service"; import useUser from "hooks/use-user"; // helper import { unsetCustomCssVariables } from "helpers/theme.helper"; +// mobx react lite +import { observer } from "mobx-react-lite"; +// mobx store +import { useMobxStore } from "lib/mobx/store-provider"; type Props = { setIsPaletteOpen: Dispatch>; }; -export const ChangeInterfaceTheme: React.FC = ({ setIsPaletteOpen }) => { +export const ChangeInterfaceTheme: React.FC = observer(({ setIsPaletteOpen }) => { + const store: any = useMobxStore(); + const [mounted, setMounted] = useState(false); const { setTheme } = useTheme(); @@ -23,29 +29,11 @@ export const ChangeInterfaceTheme: React.FC = ({ setIsPaletteOpen }) => { const updateUserTheme = (newTheme: string) => { if (!user) return; - - unsetCustomCssVariables(); - setTheme(newTheme); - - mutateUser((prevData: any) => { - if (!prevData) return prevData; - - return { - ...prevData, - theme: { - ...prevData?.theme, - theme: newTheme, - }, - }; - }, false); - - userService.updateUser({ - theme: { - ...user.theme, - theme: newTheme, - }, - }); + return store.user + .updateCurrentUserSettings({ theme: { ...user.theme, theme: newTheme } }) + .then((response: any) => response) + .catch((error: any) => error); }; // useEffect only runs on the client, so now we can safely show the UI @@ -74,4 +62,4 @@ export const ChangeInterfaceTheme: React.FC = ({ setIsPaletteOpen }) => { ))} ); -}; +}); diff --git a/apps/app/components/core/modals/gpt-assistant-modal.tsx b/apps/app/components/core/modals/gpt-assistant-modal.tsx index 6b06256cf..a3b748d66 100644 --- a/apps/app/components/core/modals/gpt-assistant-modal.tsx +++ b/apps/app/components/core/modals/gpt-assistant-modal.tsx @@ -145,7 +145,7 @@ export const GptAssistantModal: React.FC = ({ }`} > {((content && content !== "") || (htmlContent && htmlContent !== "

")) && ( -
+
Content: ${content}

`} diff --git a/apps/app/components/core/modals/link-modal.tsx b/apps/app/components/core/modals/link-modal.tsx index fc1641767..bed74fca0 100644 --- a/apps/app/components/core/modals/link-modal.tsx +++ b/apps/app/components/core/modals/link-modal.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useEffect } from "react"; // react-hook-form import { useForm } from "react-hook-form"; @@ -7,12 +7,15 @@ import { Dialog, Transition } from "@headlessui/react"; // ui import { Input, PrimaryButton, SecondaryButton } from "components/ui"; // types -import type { IIssueLink, ModuleLink } from "types"; +import type { IIssueLink, linkDetails, ModuleLink } from "types"; type Props = { isOpen: boolean; handleClose: () => void; - onFormSubmit: (formData: IIssueLink | ModuleLink) => Promise; + data?: linkDetails | null; + status: boolean; + createIssueLink: (formData: IIssueLink | ModuleLink) => Promise; + updateIssueLink: (formData: IIssueLink | ModuleLink, linkId: string) => Promise; }; const defaultValues: IIssueLink | ModuleLink = { @@ -20,7 +23,14 @@ const defaultValues: IIssueLink | ModuleLink = { url: "", }; -export const LinkModal: React.FC = ({ isOpen, handleClose, onFormSubmit }) => { +export const LinkModal: React.FC = ({ + isOpen, + handleClose, + createIssueLink, + updateIssueLink, + status, + data, +}) => { const { register, formState: { errors, isSubmitting }, @@ -30,11 +40,6 @@ export const LinkModal: React.FC = ({ isOpen, handleClose, onFormSubmit } defaultValues, }); - const onSubmit = async (formData: IIssueLink | ModuleLink) => { - await onFormSubmit({ title: formData.title, url: formData.url }); - onClose(); - }; - const onClose = () => { handleClose(); const timeout = setTimeout(() => { @@ -43,6 +48,27 @@ export const LinkModal: React.FC = ({ isOpen, handleClose, onFormSubmit } }, 500); }; + const handleFormSubmit = async (formData: IIssueLink | ModuleLink) => { + if (!data) await createIssueLink({ title: formData.title, url: formData.url }); + else await updateIssueLink({ title: formData.title, url: formData.url }, data.id); + onClose(); + }; + + const handleCreateUpdatePage = async (formData: IIssueLink | ModuleLink) => { + await handleFormSubmit(formData); + + reset({ + ...defaultValues, + }); + }; + + useEffect(() => { + reset({ + ...defaultValues, + ...data, + }); + }, [data, reset]); + return ( @@ -70,14 +96,14 @@ export const LinkModal: React.FC = ({ isOpen, handleClose, onFormSubmit } leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" > -
+
- Add Link + {status ? "Update Link" : "Add Link"}
@@ -113,7 +139,13 @@ export const LinkModal: React.FC = ({ isOpen, handleClose, onFormSubmit }
Cancel - {isSubmitting ? "Adding Link..." : "Add Link"} + {status + ? isSubmitting + ? "Updating Link..." + : "Update Link" + : isSubmitting + ? "Adding Link..." + : "Add Link"}
diff --git a/apps/app/components/core/sidebar/links-list.tsx b/apps/app/components/core/sidebar/links-list.tsx index af008fec4..fb8f3243d 100644 --- a/apps/app/components/core/sidebar/links-list.tsx +++ b/apps/app/components/core/sidebar/links-list.tsx @@ -1,25 +1,24 @@ // icons import { ArrowTopRightOnSquareIcon, LinkIcon, TrashIcon } from "@heroicons/react/24/outline"; +import { Icon } from "components/ui"; // helpers import { timeAgo } from "helpers/date-time.helper"; // types -import { IUserLite, UserAuth } from "types"; +import { linkDetails, UserAuth } from "types"; type Props = { - links: { - id: string; - created_at: Date; - created_by: string; - created_by_detail: IUserLite; - metadata: any; - title: string; - url: string; - }[]; + links: linkDetails[]; handleDeleteLink: (linkId: string) => void; + handleEditLink: (link: linkDetails) => void; userAuth: UserAuth; }; -export const LinksList: React.FC = ({ links, handleDeleteLink, userAuth }) => { +export const LinksList: React.FC = ({ + links, + handleDeleteLink, + handleEditLink, + userAuth, +}) => { const isNotAllowed = userAuth.isGuest || userAuth.isViewer; return ( @@ -28,6 +27,13 @@ export const LinksList: React.FC = ({ links, handleDeleteLink, userAuth }
{!isNotAllowed && (
+ = observer( currentThemeObj ? (
-
+ > +
+
+
+ {currentThemeObj.label}
) : ( "Select your theme" @@ -98,18 +106,26 @@ export const ThemeSwitch: React.FC = observer(
-
+ > +
+
+
+ {label}
))} diff --git a/apps/app/components/core/views/board-view/single-issue.tsx b/apps/app/components/core/views/board-view/single-issue.tsx index e87ea434f..4a1f25fe0 100644 --- a/apps/app/components/core/views/board-view/single-issue.tsx +++ b/apps/app/components/core/views/board-view/single-issue.tsx @@ -88,6 +88,7 @@ export const SingleBoardIssue: React.FC = ({ const [contextMenu, setContextMenu] = useState(false); const [contextMenuPosition, setContextMenuPosition] = useState({ x: 0, y: 0 }); const [isMenuActive, setIsMenuActive] = useState(false); + const [isDropdownActive, setIsDropdownActive] = useState(false); const actionSectionRef = useRef(null); @@ -245,7 +246,7 @@ export const SingleBoardIssue: React.FC = ({ setContextMenuPosition({ x: e.pageX, y: e.pageY }); }} > -
+
{!isNotAllowed && (
= ({
)} - + {properties.key && ( -
+
{issue.project_detail.identifier}-{issue.sequence_id}
)}
{issue.name}
-
+
{properties.priority && ( = ({ setIsDropdownActive(true)} + handleOnClose={() => setIsDropdownActive(false)} user={user} isNotAllowed={isNotAllowed} /> @@ -335,6 +342,8 @@ export const SingleBoardIssue: React.FC = ({ setIsDropdownActive(true)} + handleOnClose={() => setIsDropdownActive(false)} user={user} isNotAllowed={isNotAllowed} /> diff --git a/apps/app/components/cycles/single-cycle-card.tsx b/apps/app/components/cycles/single-cycle-card.tsx index 8808940f1..0822ba26a 100644 --- a/apps/app/components/cycles/single-cycle-card.tsx +++ b/apps/app/components/cycles/single-cycle-card.tsx @@ -45,7 +45,6 @@ type TSingleStatProps = { handleDeleteCycle: () => void; handleAddToFavorites: () => void; handleRemoveFromFavorites: () => void; - isCompleted?: boolean; }; const stateGroups = [ @@ -82,7 +81,6 @@ export const SingleCycleCard: React.FC = ({ handleDeleteCycle, handleAddToFavorites, handleRemoveFromFavorites, - isCompleted = false, }) => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; @@ -90,6 +88,7 @@ export const SingleCycleCard: React.FC = ({ const { setToastAlert } = useToast(); const cycleStatus = getDateRangeStatus(cycle.start_date, cycle.end_date); + const isCompleted = cycleStatus === "completed"; const endDate = new Date(cycle.end_date ?? ""); const startDate = new Date(cycle.start_date ?? ""); diff --git a/apps/app/components/cycles/single-cycle-list.tsx b/apps/app/components/cycles/single-cycle-list.tsx index 813264986..7518568ed 100644 --- a/apps/app/components/cycles/single-cycle-list.tsx +++ b/apps/app/components/cycles/single-cycle-list.tsx @@ -34,7 +34,6 @@ type TSingleStatProps = { handleDeleteCycle: () => void; handleAddToFavorites: () => void; handleRemoveFromFavorites: () => void; - isCompleted?: boolean; }; const stateGroups = [ @@ -113,7 +112,6 @@ export const SingleCycleList: React.FC = ({ handleDeleteCycle, handleAddToFavorites, handleRemoveFromFavorites, - isCompleted = false, }) => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; @@ -121,6 +119,7 @@ export const SingleCycleList: React.FC = ({ const { setToastAlert } = useToast(); const cycleStatus = getDateRangeStatus(cycle.start_date, cycle.end_date); + const isCompleted = cycleStatus === "completed"; const endDate = new Date(cycle.end_date ?? ""); const startDate = new Date(cycle.start_date ?? ""); diff --git a/apps/app/components/issues/activity.tsx b/apps/app/components/issues/activity.tsx index 1b5cd6e4c..83da7d521 100644 --- a/apps/app/components/issues/activity.tsx +++ b/apps/app/components/issues/activity.tsx @@ -134,7 +134,9 @@ export const IssueActivitySection: React.FC = ({ issueId, user }) => {
- {activityItem.actor_detail.display_name.charAt(0)} + {activityItem.actor_detail.is_bot + ? activityItem.actor_detail.first_name.charAt(0) + : activityItem.actor_detail.display_name.charAt(0)}
)}
@@ -153,7 +155,9 @@ export const IssueActivitySection: React.FC = ({ issueId, user }) => { ) : (
- {activityItem.actor_detail.display_name} + {activityItem.actor_detail.is_bot + ? activityItem.actor_detail.first_name + : activityItem.actor_detail.display_name} )}{" "} diff --git a/apps/app/components/issues/comment/add-comment.tsx b/apps/app/components/issues/comment/add-comment.tsx index 6f49e900a..15b67b157 100644 --- a/apps/app/components/issues/comment/add-comment.tsx +++ b/apps/app/components/issues/comment/add-comment.tsx @@ -87,7 +87,7 @@ export const AddComment: React.FC = ({ issueId, user, disabled = false }) return (
-
+
= ({ issueId, user, disabled = false }) ? watch("comment_html") : value } - customClassName="p-3 min-h-[50px]" + customClassName="p-3 min-h-[50px] shadow-sm" debouncedUpdatesEnabled={false} onChange={(comment_json: Object, comment_html: string) => { onChange(comment_html); diff --git a/apps/app/components/issues/comment/comment-card.tsx b/apps/app/components/issues/comment/comment-card.tsx index 21e503a09..4e95e1334 100644 --- a/apps/app/components/issues/comment/comment-card.tsx +++ b/apps/app/components/issues/comment/comment-card.tsx @@ -65,7 +65,11 @@ export const CommentCard: React.FC = ({ comment, onSubmit, handleCommentD {comment.actor_detail.avatar && comment.actor_detail.avatar !== "" ? ( {comment.actor_detail.display_name} = ({ comment, onSubmit, handleCommentD
- {comment.actor_detail.display_name.charAt(0)} + {comment.actor_detail.is_bot + ? comment.actor_detail.first_name.charAt(0) + : comment.actor_detail.display_name.charAt(0)}
)} @@ -101,12 +107,12 @@ export const CommentCard: React.FC = ({ comment, onSubmit, handleCommentD className={`flex-col gap-2 ${isEditing ? "flex" : "hidden"}`} onSubmit={handleSubmit(onEnter)} > -
+
{ setValue("comment_json", comment_json); setValue("comment_html", comment_html); diff --git a/apps/app/components/issues/description-form.tsx b/apps/app/components/issues/description-form.tsx index 7c163527a..553a9fa7a 100644 --- a/apps/app/components/issues/description-form.tsx +++ b/apps/app/components/issues/description-form.tsx @@ -112,8 +112,9 @@ export const IssueDescriptionForm: FC = ({ {characterLimit && (
255 ? "text-red-500" : "" - }`} + className={`${ + watch("name").length === 0 || watch("name").length > 255 ? "text-red-500" : "" + }`} > {watch("name").length} @@ -122,7 +123,7 @@ export const IssueDescriptionForm: FC = ({ )}
{errors.name ? errors.name.message : null} -
+
= ({ { setIsSubmitting("submitting"); @@ -154,8 +155,12 @@ export const IssueDescriptionForm: FC = ({ ); }} /> -
- {isSubmitting === 'submitting' ? 'Saving...' : 'Saved'} +
+ {isSubmitting === "submitting" ? "Saving..." : "Saved"}
diff --git a/apps/app/components/issues/form.tsx b/apps/app/components/issues/form.tsx index a7913b3cf..0e73ca349 100644 --- a/apps/app/components/issues/form.tsx +++ b/apps/app/components/issues/form.tsx @@ -333,7 +333,7 @@ export const IssueForm: FC = ({
)} {(fieldsToShow.includes("all") || fieldsToShow.includes("description")) && ( -
+
{issueName && issueName !== "" && ( +
)} {orderedFavProjects.map((project, index) => ( @@ -241,10 +256,7 @@ export const ProjectSidebarList: FC = () => { diff --git a/apps/app/components/tiptap/bubble-menu/index.tsx b/apps/app/components/tiptap/bubble-menu/index.tsx index 590dfab5e..259b5ecea 100644 --- a/apps/app/components/tiptap/bubble-menu/index.tsx +++ b/apps/app/components/tiptap/bubble-menu/index.tsx @@ -97,10 +97,14 @@ export const EditorBubbleMenu: FC = (props) => { {items.map((item, index) => ( +const { NEXT_PUBLIC_DEPLOY_URL } = process.env; +const plane_deploy_url = NEXT_PUBLIC_DEPLOY_URL ? NEXT_PUBLIC_DEPLOY_URL : "http://localhost:3001"; + +const Header: React.FC = ({ breadcrumbs, left, right, setToggleSidebar, noHeader }) => { + const { projectDetails } = useProjectDetails(); + + const router = useRouter(); + const { workspaceSlug, projectId } = router.query; + + return ( +
+
+
+ +
+
{breadcrumbs}
+ + {projectDetails && projectDetails?.is_deployed && ( + + + +
+
+ + radio_button_checked + +
+
Public
+
+ open_in_new +
+
+
+
+ + )} + +
{left}
- {breadcrumbs} -
{left}
+
{right}
-
{right}
-
-); + ); +}; export default Header; diff --git a/apps/app/public/empty-state/priority_graph.svg b/apps/app/public/empty-state/empty_bar_graph.svg similarity index 58% rename from apps/app/public/empty-state/priority_graph.svg rename to apps/app/public/empty-state/empty_bar_graph.svg index 15d8f9b4c..7742a4238 100644 --- a/apps/app/public/empty-state/priority_graph.svg +++ b/apps/app/public/empty-state/empty_bar_graph.svg @@ -1,5 +1,5 @@ - - - + + + diff --git a/apps/app/public/empty-state/empty_graph.svg b/apps/app/public/empty-state/empty_graph.svg new file mode 100644 index 000000000..5eae523a5 --- /dev/null +++ b/apps/app/public/empty-state/empty_graph.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/apps/app/public/empty-state/empty_users.svg b/apps/app/public/empty-state/empty_users.svg new file mode 100644 index 000000000..7298e9e8f --- /dev/null +++ b/apps/app/public/empty-state/empty_users.svg @@ -0,0 +1,3 @@ + + + diff --git a/apps/app/public/empty-state/recent_activity.svg b/apps/app/public/empty-state/recent_activity.svg index 48ea2277c..bef318fae 100644 --- a/apps/app/public/empty-state/recent_activity.svg +++ b/apps/app/public/empty-state/recent_activity.svg @@ -1,3 +1,3 @@ - + diff --git a/apps/app/public/empty-state/state_graph.svg b/apps/app/public/empty-state/state_graph.svg index 7265784a8..07337991e 100644 --- a/apps/app/public/empty-state/state_graph.svg +++ b/apps/app/public/empty-state/state_graph.svg @@ -1,26 +1,26 @@ - + - - + + - - + + - - + + - - + + - - + + - + diff --git a/apps/app/services/issues.service.ts b/apps/app/services/issues.service.ts index ea92e6dec..53c6c1a2d 100644 --- a/apps/app/services/issues.service.ts +++ b/apps/app/services/issues.service.ts @@ -459,6 +459,29 @@ class ProjectIssuesServices extends APIService { }); } + async updateIssueLink( + workspaceSlug: string, + projectId: string, + issueId: string, + linkId: string, + data: { + metadata: any; + title: string; + url: string; + }, + + ): Promise { + return this.patch( + `/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/issue-links/${linkId}/`, + data + ) + .then((response) => response?.data) + .catch((error) => { + throw error?.response; + }); + } + + async deleteIssueLink( workspaceSlug: string, projectId: string, diff --git a/apps/app/services/modules.service.ts b/apps/app/services/modules.service.ts index 357b92fa3..c70066a1e 100644 --- a/apps/app/services/modules.service.ts +++ b/apps/app/services/modules.service.ts @@ -212,6 +212,28 @@ class ProjectIssuesServices extends APIService { }); } + async updateModuleLink( + workspaceSlug: string, + projectId: string, + moduleId: string, + linkId: string, + data: { + metadata: any; + title: string; + url: string; + }, + + ): Promise { + return this.patch( + `/api/workspaces/${workspaceSlug}/projects/${projectId}/modules/${moduleId}/module-links/${linkId}/`, + data + ) + .then((response) => response?.data) + .catch((error) => { + throw error?.response; + }); + } + async deleteModuleLink( workspaceSlug: string, projectId: string, diff --git a/apps/app/store/project-publish.tsx b/apps/app/store/project-publish.tsx index d1b4c58a7..1b27d5fff 100644 --- a/apps/app/store/project-publish.tsx +++ b/apps/app/store/project-publish.tsx @@ -259,15 +259,13 @@ class ProjectPublishStore implements IProjectPublishStore { user ); - if (response) { - runInAction(() => { - this.projectPublishSettings = "not-initialized"; - this.loader = false; - this.error = null; - }); + runInAction(() => { + this.projectPublishSettings = "not-initialized"; + this.loader = false; + this.error = null; + }); - return response; - } + return response; } catch (error) { this.loader = false; this.error = error; diff --git a/apps/app/types/issues.d.ts b/apps/app/types/issues.d.ts index 683704f9f..9cbcef847 100644 --- a/apps/app/types/issues.d.ts +++ b/apps/app/types/issues.d.ts @@ -56,6 +56,16 @@ export interface IIssueLink { url: string; } +export interface linkDetails { + created_at: Date; + created_by: string; + created_by_detail: IUserLite; + id: string; + metadata: any; + title: string; + url: string; +} + export interface IIssue { archived_at: string; assignees: string[]; @@ -80,15 +90,7 @@ export interface IIssue { estimate_point: number | null; id: string; issue_cycle: IIssueCycle | null; - issue_link: { - created_at: Date; - created_by: string; - created_by_detail: IUserLite; - id: string; - metadata: any; - title: string; - url: string; - }[]; + issue_link: linkDetails[]; issue_module: IIssueModule | null; labels: string[]; label_details: any[]; @@ -205,7 +207,8 @@ export interface IIssueLite { id: string; name: string; project_id: string; - target_date: string; + start_date?: string | null; + target_date?: string | null; workspace__slug: string; } diff --git a/apps/app/types/modules.d.ts b/apps/app/types/modules.d.ts index eefd42788..e395f6f16 100644 --- a/apps/app/types/modules.d.ts +++ b/apps/app/types/modules.d.ts @@ -7,6 +7,7 @@ import type { IWorkspaceLite, IProjectLite, IIssueFilterOptions, + linkDetails, } from "types"; export interface IModule { @@ -26,15 +27,7 @@ export interface IModule { id: string; lead: string | null; lead_detail: IUserLite | null; - link_module: { - created_at: Date; - created_by: string; - created_by_detail: IUserLite; - id: string; - metadata: any; - title: string; - url: string; - }[]; + link_module: linkDetails[]; links_list: ModuleLink[]; members: string[]; members_list: string[]; diff --git a/apps/app/types/projects.d.ts b/apps/app/types/projects.d.ts index d620a24b7..a3d8b997a 100644 --- a/apps/app/types/projects.d.ts +++ b/apps/app/types/projects.d.ts @@ -57,6 +57,7 @@ export interface IProject { updated_by: string; workspace: IWorkspace | string; workspace_detail: IWorkspaceLite; + is_deployed: boolean; } export interface IProjectLite { diff --git a/apps/space/app/404/page.tsx b/apps/space/app/404/page.tsx new file mode 100644 index 000000000..d10d95fb9 --- /dev/null +++ b/apps/space/app/404/page.tsx @@ -0,0 +1,30 @@ +// next imports +import Image from "next/image"; + +const Custom404Error = () => ( +
+
+
+
+ 404- Page not found +
+
Oops! Something went wrong.
+
+ Sorry, the page you are looking for cannot be found. It may have been removed, had its name changed, or is + temporarily unavailable. +
+
+ + +
+
+); + +export default Custom404Error; diff --git a/apps/space/app/[workspace_slug]/[project_slug]/layout.tsx b/apps/space/app/[workspace_slug]/[project_slug]/layout.tsx index fde4f5d99..7b4ed6142 100644 --- a/apps/space/app/[workspace_slug]/[project_slug]/layout.tsx +++ b/apps/space/app/[workspace_slug]/[project_slug]/layout.tsx @@ -7,6 +7,7 @@ import IssueNavbar from "components/issues/navbar"; import IssueFilter from "components/issues/filters-render"; // service import ProjectService from "services/project.service"; +import { redirect } from "next/navigation"; type LayoutProps = { params: { workspace_slug: string; project_slug: string }; @@ -17,17 +18,26 @@ export async function generateMetadata({ params }: LayoutProps): Promise${ - typeof project?.project_details?.emoji != "object" - ? String.fromCodePoint(parseInt(project?.project_details?.emoji)) - : "✈️" - }`, - }; + return { + title: `${project?.project_details?.name} | ${workspace_slug}`, + description: `${ + project?.project_details?.description || `${project?.project_details?.name} | ${workspace_slug}` + }`, + icons: `data:image/svg+xml,${ + typeof project?.project_details?.emoji != "object" + ? String.fromCodePoint(parseInt(project?.project_details?.emoji)) + : "✈️" + }`, + }; + } catch (error: any) { + if (error?.data?.error) { + redirect(`/project-not-published`); + } + return {}; + } } const RootLayout = ({ children }: { children: React.ReactNode }) => ( diff --git a/apps/space/app/[workspace_slug]/[project_slug]/page.tsx b/apps/space/app/[workspace_slug]/[project_slug]/page.tsx index 0aa9b164d..f6ccf5081 100644 --- a/apps/space/app/[workspace_slug]/[project_slug]/page.tsx +++ b/apps/space/app/[workspace_slug]/[project_slug]/page.tsx @@ -29,15 +29,41 @@ const WorkspaceProjectPage = observer(() => { // updating default board view when we are in the issues page useEffect(() => { - if (workspace_slug && project_slug) { - if (!board) { - store.issue.setCurrentIssueBoardView("list"); - router.replace(`/${workspace_slug}/${project_slug}?board=${store?.issue?.currentIssueBoardView}`); - } else { - if (board != store?.issue?.currentIssueBoardView) store.issue.setCurrentIssueBoardView(board); + if (workspace_slug && project_slug && store?.project?.workspaceProjectSettings) { + const workspacePRojectSettingViews = store?.project?.workspaceProjectSettings?.views; + const userAccessViews: TIssueBoardKeys[] = []; + + Object.keys(workspacePRojectSettingViews).filter((_key) => { + if (_key === "list" && workspacePRojectSettingViews.list === true) userAccessViews.push(_key); + if (_key === "kanban" && workspacePRojectSettingViews.kanban === true) userAccessViews.push(_key); + if (_key === "calendar" && workspacePRojectSettingViews.calendar === true) userAccessViews.push(_key); + if (_key === "spreadsheet" && workspacePRojectSettingViews.spreadsheet === true) userAccessViews.push(_key); + if (_key === "gantt" && workspacePRojectSettingViews.gantt === true) userAccessViews.push(_key); + }); + + if (userAccessViews && userAccessViews.length > 0) { + if (!board) { + store.issue.setCurrentIssueBoardView(userAccessViews[0]); + router.replace(`/${workspace_slug}/${project_slug}?board=${userAccessViews[0]}`); + } else { + if (userAccessViews.includes(board)) { + if (store.issue.currentIssueBoardView === null) store.issue.setCurrentIssueBoardView(board); + else { + if (board === store.issue.currentIssueBoardView) + router.replace(`/${workspace_slug}/${project_slug}?board=${board}`); + else { + store.issue.setCurrentIssueBoardView(board); + router.replace(`/${workspace_slug}/${project_slug}?board=${board}`); + } + } + } else { + store.issue.setCurrentIssueBoardView(userAccessViews[0]); + router.replace(`/${workspace_slug}/${project_slug}?board=${userAccessViews[0]}`); + } + } } } - }, [workspace_slug, project_slug, board, router, store?.issue]); + }, [workspace_slug, project_slug, board, router, store?.issue, store?.project?.workspaceProjectSettings]); useEffect(() => { if (workspace_slug && project_slug) { diff --git a/apps/space/app/project-not-published/page.tsx b/apps/space/app/project-not-published/page.tsx new file mode 100644 index 000000000..82a2ff5da --- /dev/null +++ b/apps/space/app/project-not-published/page.tsx @@ -0,0 +1,31 @@ +// next imports +import Image from "next/image"; + +const CustomProjectNotPublishedError = () => ( +
+
+
+
+ 404- Page not found +
+
+ Oops! The page you{`'`}re looking for isn{`'`}t live at the moment. +
+
+ If this is your project, login to your workspace to adjust its visibility settings and make it public. +
+
+ + +
+
+); + +export default CustomProjectNotPublishedError; diff --git a/apps/space/components/issues/board-views/kanban/block.tsx b/apps/space/components/issues/board-views/kanban/block.tsx index 304e05612..22af77568 100644 --- a/apps/space/components/issues/board-views/kanban/block.tsx +++ b/apps/space/components/issues/board-views/kanban/block.tsx @@ -27,7 +27,7 @@ export const IssueListBlock = ({ issue }: { issue: IIssue }) => {
{issue.name}
{/* priority */} -
+
{issue?.priority && (
diff --git a/apps/space/lib/mobx/store-init.tsx b/apps/space/lib/mobx/store-init.tsx index 2ba2f9024..4f4b6662c 100644 --- a/apps/space/lib/mobx/store-init.tsx +++ b/apps/space/lib/mobx/store-init.tsx @@ -24,11 +24,6 @@ const MobxStoreInit = () => { else localStorage.setItem("app_theme", _theme && _theme != "light" ? "dark" : "light"); }, [store?.theme]); - // updating default board view when we are in the issues page - useEffect(() => { - if (board && board != store?.issue?.currentIssueBoardView) store.issue.setCurrentIssueBoardView(board); - }, [board, store?.issue]); - return <>; }; diff --git a/apps/space/package.json b/apps/space/package.json index c2eaa8af1..dd7a3058c 100644 --- a/apps/space/package.json +++ b/apps/space/package.json @@ -20,7 +20,7 @@ "js-cookie": "^3.0.1", "mobx": "^6.10.0", "mobx-react-lite": "^4.0.3", - "next": "^13.4.13", + "next": "^13.4.16", "nprogress": "^0.2.0", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/apps/space/public/404.svg b/apps/space/public/404.svg new file mode 100644 index 000000000..4c298417d --- /dev/null +++ b/apps/space/public/404.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/apps/space/public/project-not-published.svg b/apps/space/public/project-not-published.svg new file mode 100644 index 000000000..db4b404df --- /dev/null +++ b/apps/space/public/project-not-published.svg @@ -0,0 +1,4 @@ + + + + diff --git a/setup.sh b/setup.sh index 8c1f81a48..a5a8e9b6a 100755 --- a/setup.sh +++ b/setup.sh @@ -1,5 +1,5 @@ #!/bin/bash -cp ./.env.example ./.env +# cp ./.env.example ./.env # Export for tr error in mac export LC_ALL=C @@ -14,3 +14,16 @@ echo -e "SECRET_KEY=\"$(tr -dc 'a-z0-9' < /dev/urandom | head -c50)\"" >> ./.en # WEB_URL for email redirection and image saving echo -e "WEB_URL=$1" >> ./.env + +# Generate Prompt for taking tiptap auth key +echo -e "\n\e[1;38m Instructions for generating TipTap Pro Extensions Auth Token \e[0m \n" + +echo -e "\e[1;38m 1. Head over to TipTap cloud's Pro Extensions Page, https://collab.tiptap.dev/pro-extensions \e[0m" +echo -e "\e[1;38m 2. Copy the token given to you under the first paragraph, after 'Here it is' \e[0m \n" + +read -p $'\e[1;32m Please Enter Your TipTap Pro Extensions Authentication Token: \e[0m \e[1;36m' authToken + + +echo "@tiptap-pro:registry=https://registry.tiptap.dev/ +//registry.tiptap.dev/:_authToken=${authToken}" > .npmrc + diff --git a/yarn.lock b/yarn.lock index 4d62e7f7c..b4cf55f2f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1384,10 +1384,10 @@ resolved "https://registry.yarnpkg.com/@next/env/-/env-12.3.2.tgz#fb819366771f5721e9438ca3a42ad18684f0949b" integrity sha512-upwtMaHxlv/udAWGq0kE+rg8huwmcxQPsKZFhS1R5iVO323mvxEBe1YrSXe1awLbg9sTIuEHbgxjLLt7JbeuAQ== -"@next/env@13.4.13": - version "13.4.13" - resolved "https://registry.yarnpkg.com/@next/env/-/env-13.4.13.tgz#50250cec7626904b93a4a934933d6a747763259d" - integrity sha512-fwz2QgVg08v7ZL7KmbQBLF2PubR/6zQdKBgmHEl3BCyWTEDsAQEijjw2gbFhI1tcKfLdOOJUXntz5vZ4S0Polg== +"@next/env@13.4.16": + version "13.4.16" + resolved "https://registry.yarnpkg.com/@next/env/-/env-13.4.16.tgz#382b565b35a2a69bd0e6b50f74c7b95f0c4b1097" + integrity sha512-pCU0sJBqdfKP9mwDadxvZd+eLz3fZrTlmmDHY12Hdpl3DD0vy8ou5HWKVfG0zZS6tqhL4wnQqRbspdY5nqa7MA== "@next/eslint-plugin-next@12.2.2": version "12.2.2" @@ -1425,20 +1425,20 @@ resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.3.2.tgz#97c532d35c66ce6b6941ae24b5b8b267b9b0d0d8" integrity sha512-PTUfe1ZrwjsiuTmr3bOM9lsoy5DCmfYsLOUF9ZVhtbi5MNJVmUTy4VZ06GfrvnCO5hGCr48z3vpFE9QZ0qLcPw== -"@next/swc-darwin-arm64@13.4.13": - version "13.4.13" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.13.tgz#700fddf66c936c89f98eb60d88cc3d06642aa0bf" - integrity sha512-ZptVhHjzUuivnXMNCJ6lER33HN7lC+rZ01z+PM10Ows21NHFYMvGhi5iXkGtBDk6VmtzsbqnAjnx4Oz5um0FjA== +"@next/swc-darwin-arm64@13.4.16": + version "13.4.16" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.16.tgz#ed6a342f95e5f21213fdadbceb65b40ae678cee0" + integrity sha512-Rl6i1uUq0ciRa3VfEpw6GnWAJTSKo9oM2OrkGXPsm7rMxdd2FR5NkKc0C9xzFCI4+QtmBviWBdF2m3ur3Nqstw== "@next/swc-darwin-x64@12.3.2": version "12.3.2" resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-12.3.2.tgz#e0cb4ff4b11faaff3a891bd1d18ed72f71e30ebe" integrity sha512-1HkjmS9awwlaeEY8Y01nRSNkSv3y+qnC/mjMPe/W66hEh3QKa/LQHqHeS7NOdEs19B2mhZ7w+EgMRXdLQ0Su8w== -"@next/swc-darwin-x64@13.4.13": - version "13.4.13" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.13.tgz#762d422cb31b27807c9bf4eac766986742a051fe" - integrity sha512-t9nTiWCLApw8W4G1kqJyYP7y6/7lyal3PftmRturIxAIBlZss9wrtVN8nci50StDHmIlIDxfguYIEGVr9DbFTg== +"@next/swc-darwin-x64@13.4.16": + version "13.4.16" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.16.tgz#36c16066a1a3ef8211e84a6a5d72bef15826b291" + integrity sha512-o1vIKYbZORyDmTrPV1hApt9NLyWrS5vr2p5hhLGpOnkBY1cz6DAXjv8Lgan8t6X87+83F0EUDlu7klN8ieZ06A== "@next/swc-freebsd-x64@12.3.2": version "12.3.2" @@ -1455,70 +1455,70 @@ resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.3.2.tgz#26df7d7cdc18cf413f12a408179ee4ac315f383a" integrity sha512-T9GCFyOIb4S3acA9LqflUYD+QZ94iZketHCqKdoO0Nx0OCHIgGJV5rotDe8TDXwh/goYpIfyHU4j1qqw4w4VnA== -"@next/swc-linux-arm64-gnu@13.4.13": - version "13.4.13" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.13.tgz#d567943a0111dcf26de6e5e034874b405057facc" - integrity sha512-xEHUqC8eqR5DHe8SOmMnDU1K3ggrJ28uIKltrQAwqFSSSmzjnN/XMocZkcVhuncuxYrpbri0iMQstRyRVdQVWg== +"@next/swc-linux-arm64-gnu@13.4.16": + version "13.4.16" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.16.tgz#a5b5500737f07e3aa7f184014d8df7973420df26" + integrity sha512-JRyAl8lCfyTng4zoOmE6hNI2f1MFUr7JyTYCHl1RxX42H4a5LMwJhDVQ7a9tmDZ/yj+0hpBn+Aan+d6lA3v0UQ== "@next/swc-linux-arm64-musl@12.3.2": version "12.3.2" resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.3.2.tgz#fd42232a6b10d9f9a4f71433d59c280a4532d06f" integrity sha512-hxNVZS6L3c2z3l9EH2GP0MGQ9exu6O8cohYNZyqC9WUl6C03sEn8xzDH1y+NgD3fVurvYkGU5F0PDddJJLfDIw== -"@next/swc-linux-arm64-musl@13.4.13": - version "13.4.13" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.13.tgz#775f246123b8f1f3726dc14d80c7f7b67bc50cb4" - integrity sha512-sNf3MnLAm8rquSSAoeD9nVcdaDeRYOeey4stOWOyWIgbBDtP+C93amSgH/LPTDoUV7gNiU6f+ghepTjTjRgIUQ== +"@next/swc-linux-arm64-musl@13.4.16": + version "13.4.16" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.16.tgz#381b7662c5b10ed5750dce41dd57841aa0713e77" + integrity sha512-9gqVqNzUMWbUDgDiND18xoUqhwSm2gmksqXgCU0qaOKt6oAjWz8cWYjgpPVD0WICKFylEY/gvPEP1fMZDVFZ/g== "@next/swc-linux-x64-gnu@12.3.2": version "12.3.2" resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.3.2.tgz#5307579e3d8fbdb03adbe6cfc915b51548e0a103" integrity sha512-fCPkLuwDwY8/QeXxciJJjDHG09liZym/Bhb4A+RLFQ877wUkwFsNWDUTSdUx0YXlYK/1gf67BKauqKkOKp6CYw== -"@next/swc-linux-x64-gnu@13.4.13": - version "13.4.13" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.13.tgz#d5fc6441c181bfa09f3cb0285bf3cbb5b111e53b" - integrity sha512-WhcRaJJSHyx9OWmKjjz+OWHumiPZWRqmM/09Bt7Up4UqUJFFhGExeztR4trtv3rflvULatu9IH/nTV8fUUgaMA== +"@next/swc-linux-x64-gnu@13.4.16": + version "13.4.16" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.16.tgz#6e0b0eab1c316506950aeb4a09a5ea5c38edabe7" + integrity sha512-KcQGwchAKmZVPa8i5PLTxvTs1/rcFnSltfpTm803Tr/BtBV3AxCkHLfhtoyVtVzx/kl/oue8oS+DSmbepQKwhw== "@next/swc-linux-x64-musl@12.3.2": version "12.3.2" resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.3.2.tgz#d5cb920a825a8dc80ffba8a6b797fb845af0b84c" integrity sha512-o+GifBIQ2K+/MEFxHsxUZoU3bsuVFLXZYWd3idimFHiVdDCVYiKsY6mYMmKDlucX+9xRyOCkKL9Tjf+3tuXJpw== -"@next/swc-linux-x64-musl@13.4.13": - version "13.4.13" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.13.tgz#6286557e7cc7a0acb3cf0c69e279b3ae2b9a9259" - integrity sha512-+Y4LLhOWWZQIDKVwr2R17lq2KSN0F1c30QVgGIWfnjjHpH8nrIWHEndhqYU+iFuW8It78CiJjQKTw4f51HD7jA== +"@next/swc-linux-x64-musl@13.4.16": + version "13.4.16" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.16.tgz#36b84e4509168a5cadf9dfd728c239002d4311fe" + integrity sha512-2RbMZNxYnJmW8EPHVBsGZPq5zqWAyBOc/YFxq/jIQ/Yn3RMFZ1dZVCjtIcsiaKmgh7mjA/W0ApbumutHNxRqqQ== "@next/swc-win32-arm64-msvc@12.3.2": version "12.3.2" resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.3.2.tgz#2a0d619e5bc0cec17ed093afd1ca6b1c37c2690c" integrity sha512-crii66irzGGMSUR0L8r9+A06eTv7FTXqw4rgzJ33M79EwQJOdpY7RVKXLQMurUhniEeQEEOfamiEdPIi/qxisw== -"@next/swc-win32-arm64-msvc@13.4.13": - version "13.4.13" - resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.13.tgz#6a50b4b8ee55eb5564c2bd33eefedb9306986b0a" - integrity sha512-rWurdOR20uxjfqd1X9vDAgv0Jb26KjyL8akF9CBeFqX8rVaBAnW/Wf6A2gYEwyYY4Bai3T7p1kro6DFrsvBAAw== +"@next/swc-win32-arm64-msvc@13.4.16": + version "13.4.16" + resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.16.tgz#52d36f909ccdefa2761617b6d4e9ae65f99880a9" + integrity sha512-thDcGonELN7edUKzjzlHrdoKkm7y8IAdItQpRvvMxNUXa4d9r0ElofhTZj5emR7AiXft17hpen+QAkcWpqG7Jg== "@next/swc-win32-ia32-msvc@12.3.2": version "12.3.2" resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.3.2.tgz#769bef60d0d678c3d7606a4dc7fee018d6199227" integrity sha512-5hRUSvn3MdQ4nVRu1rmKxq5YJzpTtZfaC/NyGw6wa4NSF1noUn/pdQGUr+I5Qz3CZkd1gZzzC0eaXQHlrk0E2g== -"@next/swc-win32-ia32-msvc@13.4.13": - version "13.4.13" - resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.13.tgz#02e98e1d4cd7a81de58a78044c5f2a5d7fdf4c83" - integrity sha512-E8bSPwRuY5ibJ3CzLQmJEt8qaWrPYuUTwnrwygPUEWoLzD5YRx9SD37oXRdU81TgGwDzCxpl7z5Nqlfk50xAog== +"@next/swc-win32-ia32-msvc@13.4.16": + version "13.4.16" + resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.16.tgz#a9cb0556d19c33fbb39ac9bef195fd490d6c7673" + integrity sha512-f7SE1Mo4JAchUWl0LQsbtySR9xCa+x55C0taetjUApKtcLR3AgAjASrrP+oE1inmLmw573qRnE1eZN8YJfEBQw== "@next/swc-win32-x64-msvc@12.3.2": version "12.3.2" resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.3.2.tgz#45beb4b9d28e6dd6abf63cab1c5b92dc84323a6b" integrity sha512-tpQJYUH+TzPMIsdVl9fH8uDg47iwiNjKY+8e9da3dXqlkztKzjSw0OwSADoqh3KrifplXeKSta+BBGLdBqg3sg== -"@next/swc-win32-x64-msvc@13.4.13": - version "13.4.13" - resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.13.tgz#db150b7d84e6218e53e748a6f0ab2159afc2cd6a" - integrity sha512-4KlyC6jWRubPnppgfYsNTPeWfGCxtWLh5vaOAW/kdzAk9widqho8Qb5S4K2vHmal1tsURi7Onk2MMCV1phvyqA== +"@next/swc-win32-x64-msvc@13.4.16": + version "13.4.16" + resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.16.tgz#79a151d94583e03992c80df3d3e7f7686390ddac" + integrity sha512-WamDZm1M/OEM4QLce3lOmD1XdLEl37zYZwlmOLhmF7qYJ2G6oYm9+ejZVv+LakQIsIuXhSpVlOvrxIAHqwRkPQ== "@nivo/annotations@0.80.0": version "0.80.0" @@ -5884,12 +5884,12 @@ next@12.3.2: "@next/swc-win32-ia32-msvc" "12.3.2" "@next/swc-win32-x64-msvc" "12.3.2" -next@^13.4.13: - version "13.4.13" - resolved "https://registry.yarnpkg.com/next/-/next-13.4.13.tgz#8824c5702daa2ef691386871c9158a6324df33d6" - integrity sha512-A3YVbVDNeXLhWsZ8Nf6IkxmNlmTNz0yVg186NJ97tGZqPDdPzTrHotJ+A1cuJm2XfuWPrKOUZILl5iBQkIf8Jw== +next@^13.4.16: + version "13.4.16" + resolved "https://registry.yarnpkg.com/next/-/next-13.4.16.tgz#327ef6885b22161ed001cd5943c20b5e409a9406" + integrity sha512-1xaA/5DrfpPu0eV31Iro7JfPeqO8uxQWb1zYNTe+KDKdzqkAGapLcDYHMLNKXKB7lHjZ7LfKUOf9dyuzcibrhA== dependencies: - "@next/env" "13.4.13" + "@next/env" "13.4.16" "@swc/helpers" "0.5.1" busboy "1.6.0" caniuse-lite "^1.0.30001406" @@ -5898,15 +5898,15 @@ next@^13.4.13: watchpack "2.4.0" zod "3.21.4" optionalDependencies: - "@next/swc-darwin-arm64" "13.4.13" - "@next/swc-darwin-x64" "13.4.13" - "@next/swc-linux-arm64-gnu" "13.4.13" - "@next/swc-linux-arm64-musl" "13.4.13" - "@next/swc-linux-x64-gnu" "13.4.13" - "@next/swc-linux-x64-musl" "13.4.13" - "@next/swc-win32-arm64-msvc" "13.4.13" - "@next/swc-win32-ia32-msvc" "13.4.13" - "@next/swc-win32-x64-msvc" "13.4.13" + "@next/swc-darwin-arm64" "13.4.16" + "@next/swc-darwin-x64" "13.4.16" + "@next/swc-linux-arm64-gnu" "13.4.16" + "@next/swc-linux-arm64-musl" "13.4.16" + "@next/swc-linux-x64-gnu" "13.4.16" + "@next/swc-linux-x64-musl" "13.4.16" + "@next/swc-win32-arm64-msvc" "13.4.16" + "@next/swc-win32-ia32-msvc" "13.4.16" + "@next/swc-win32-x64-msvc" "13.4.16" no-case@^3.0.4: version "3.0.4"