fix: merge conflicts and build errors (#1469)

* dev: private bucket implementation (#1339)

* chore: migrations and backmigration to move attachments to file asset

* chore: move attachments to file assets

* chore: update migration file to include created by and updated by and size

* chore: remove uninmport errors

* chore: make size as float field

* fix: file asset uploads

* chore: asset uploads migration changes

* chore: v2 assets endpoint

* chore: remove unused imports

* chore: issue attachments

* chore: issue attachments

* chore: workspace logo endpoints

* chore: private bucket changes

* chore: user asset endpoint

* chore: add logo_url validation

* chore: cover image urlk

* chore: change asset max length

* chore: pages endpoint

* chore: store the storage_metadata only when none

* chore: attachment asset apis

* chore: update create private bucket

* chore: make bucket private

* chore: fix response of user uploads

* fix: response of user uploads

* fix: job to fix file asset uploads

* fix: user asset endpoints

* chore: avatar for user profile

* chore: external apis user url endpoint

* chore: upload workspace and user asset actions updated

* chore: analytics endpoint

* fix: analytics export

* chore: avatar urls

* chore: update user avatar instances

* chore: avatar urls for assignees and creators

* chore: bucket permission script

* fix: all user avatr instances in the web app

* chore: update project cover image logic

* fix: issue attachment endpoint

* chore: patch endpoint for issue attachment

* chore: attachments

* chore: change attachment storage class

* chore: update issue attachment endpoints

* fix: issue attachment

* chore: update issue attachment implementation

* chore: page asset endpoints

* fix: web build errors

* chore: attachments

* chore: page asset urls

* chore: comment and issue asset endpoints

* chore: asset endpoints

* chore: attachment endpoints

* chore: bulk asset endpoint

* chore: restore endpoint

* chore: project assets endpoints

* chore: asset url

* chore: add delete asset endpoints

* chore: fix asset upload endpoint

* chore: update patch endpoints

* chore: update patch endpoint

* chore: update editor image handling

* chore: asset restore endpoints

* chore: avatar url for space assets

* chore: space app assets migration

* fix: space app urls

* chore: space endpoints

* fix: old editor images rendering logic

* fix: issue archive and attachment activity

* chore: asset deletes

* chore: update images

* chore: attachment delete

* fix: issue attachment

* fix: issue attachment get

* chore: cover image url for projects

* chore: remove duplicate py file

* fix: url check function

* chore: chore project cover asset delete

* fix: migrations

* chore: delete migration files

---------

Co-authored-by: pablohashescobar <[email protected]>

* fix: private bucket build errors (#1347)

* fix: private bucket build errors

* fix: build errors

* revert: issue type select changes. (#1355)

* chore: private bucket implementation for workspace level pages (#1371)

* chore: update project modal

* chore: update rich-text read-only editor

* chore: update workspace pages' components

* chore: remove entity identifier in favour of multiple columns of entities (#1405)

* fix: issue attachments (#1411)

* fix: issue attachments (#1422)

* chore: file size limit for pro workspaces (#1437)

* chore: file size limit for pro

* chore: update maximum file size logic

* chore: update editor max file size logic

* chore: update max file size limit logic

* chore: add comments

* fix: close modal after removing workspace logo

* chore: update uploaded asstes' status post issue creation

* chore: memoize max file size var

* chore: check for pro file size limits

* chore: added file size limit to the space app

---------

Co-authored-by: Aaryan Khandelwal <[email protected]>

* chore: add max file size limit to workspace pages (#1440)

* fix: remove old workspace logo and user avatar (#1445)

* fix: intake exception error (#5810)

* chore: filtered active cycles for guest (#1468)

* fix: build error

---------

Co-authored-by: pablohashescobar <[email protected]>
Co-authored-by: Nikhil <[email protected]>
Co-authored-by: Prateek Shourya <[email protected]>
Co-authored-by: sriram veeraghanta <[email protected]>
Co-authored-by: Anmol Singh Bhatia <[email protected]>
Co-authored-by: Bavisetti Narayan <[email protected]>
This commit is contained in:
Aaryan Khandelwal
2024-10-12 01:47:13 +05:30
committed by GitHub
co-authored by pablohashescobar Nikhil Prateek Shourya sriram veeraghanta Anmol Singh Bhatia Bavisetti Narayan
parent fcb4cd11b6
commit b9ce8ea8b1
39 changed files with 466 additions and 204 deletions
+42 -11
View File
@@ -21,6 +21,8 @@ from plane.db.models import (
)
from plane.settings.storage import S3Storage
from plane.app.permissions import allow_permission, ROLE
from plane.payment.flags.flag_decorator import check_workspace_feature_flag
from plane.payment.flags.flag import FeatureFlag
class UserAssetsV2Endpoint(BaseAPIView):
@@ -82,6 +84,9 @@ class UserAssetsV2Endpoint(BaseAPIView):
size = int(request.data.get("size", settings.FILE_SIZE_LIMIT))
entity_type = request.data.get("entity_type", False)
# Check if the file size is within the limit
size_limit = min(size, settings.FILE_SIZE_LIMIT)
# Check if the entity type is allowed
if not entity_type or entity_type not in ["USER_AVATAR", "USER_COVER"]:
return Response(
@@ -103,9 +108,6 @@ class UserAssetsV2Endpoint(BaseAPIView):
status=status.HTTP_400_BAD_REQUEST,
)
# Get the size limit
size_limit = min(settings.FILE_SIZE_LIMIT, size)
# asset key
asset_key = f"{uuid.uuid4().hex}-{name}"
@@ -174,16 +176,19 @@ class WorkspaceFileAssetEndpoint(BaseAPIView):
"""This endpoint is used to upload cover images/logos etc for workspace, projects and users."""
def get_entity_id_field(self, entity_type, entity_id):
# Workspace Logo
if entity_type == FileAsset.EntityTypeContext.WORKSPACE_LOGO:
return {
"workspace_id": entity_id,
}
# Project Cover
if entity_type == FileAsset.EntityTypeContext.PROJECT_COVER:
return {
"project_id": entity_id,
}
# User Avatar and Cover
if entity_type in [
FileAsset.EntityTypeContext.USER_AVATAR,
FileAsset.EntityTypeContext.USER_COVER,
@@ -192,6 +197,7 @@ class WorkspaceFileAssetEndpoint(BaseAPIView):
"user_id": entity_id,
}
# Issue Attachment and Description
if entity_type in [
FileAsset.EntityTypeContext.ISSUE_ATTACHMENT,
FileAsset.EntityTypeContext.ISSUE_DESCRIPTION,
@@ -200,11 +206,13 @@ class WorkspaceFileAssetEndpoint(BaseAPIView):
"issue_id": entity_id,
}
# Page Description
if entity_type == FileAsset.EntityTypeContext.PAGE_DESCRIPTION:
return {
"page_id": entity_id,
}
# Comment Description
if entity_type == FileAsset.EntityTypeContext.COMMENT_DESCRIPTION:
return {
"comment_id": entity_id,
@@ -301,8 +309,20 @@ class WorkspaceFileAssetEndpoint(BaseAPIView):
status=status.HTTP_400_BAD_REQUEST,
)
# Get the size limit
size_limit = min(settings.FILE_SIZE_LIMIT, size)
if entity_type in [
FileAsset.EntityTypeContext.WORKSPACE_LOGO,
FileAsset.EntityTypeContext.PROJECT_COVER,
]:
size_limit = min(size, settings.FILE_SIZE_LIMIT)
else:
if settings.IS_MULTI_TENANT and check_workspace_feature_flag(
feature_key=FeatureFlag.FILE_SIZE_LIMIT_PRO,
slug=slug,
user_id=str(request.user.id),
):
size_limit = min(size, settings.PRO_FILE_SIZE_LIMIT)
else:
size_limit = min(size, settings.FILE_SIZE_LIMIT)
# Get the workspace
workspace = Workspace.objects.get(slug=slug)
@@ -454,7 +474,7 @@ class AssetRestoreEndpoint(BaseAPIView):
class ProjectAssetEndpoint(BaseAPIView):
"""This endpoint is used to upload cover images/logos etc for workspace, projects and users."""
def get_entity_id_fiekd(self, entity_type, entity_id):
def get_entity_id_field(self, entity_type, entity_id):
if entity_type == FileAsset.EntityTypeContext.WORKSPACE_LOGO:
return {
"workspace_id": entity_id,
@@ -513,7 +533,7 @@ class ProjectAssetEndpoint(BaseAPIView):
)
# Check if the file type is allowed
allowed_types = ["image/jpeg", "image/png", "image/webp"]
allowed_types = ["image/jpeg", "image/png", "image/webp", "image/jpg"]
if type not in allowed_types:
return Response(
{
@@ -523,8 +543,20 @@ class ProjectAssetEndpoint(BaseAPIView):
status=status.HTTP_400_BAD_REQUEST,
)
# Get the size limit
size_limit = min(settings.FILE_SIZE_LIMIT, size)
if entity_type in [
FileAsset.EntityTypeContext.WORKSPACE_LOGO,
FileAsset.EntityTypeContext.PROJECT_COVER,
]:
size_limit = min(size, settings.FILE_SIZE_LIMIT)
else:
if check_workspace_feature_flag(
feature_key=FeatureFlag.FILE_SIZE_LIMIT_PRO,
slug=slug,
user_id=str(request.user.id),
):
size_limit = min(size, settings.PRO_FILE_SIZE_LIMIT)
else:
size_limit = min(size, settings.FILE_SIZE_LIMIT)
# Get the workspace
workspace = Workspace.objects.get(slug=slug)
@@ -545,7 +577,7 @@ class ProjectAssetEndpoint(BaseAPIView):
created_by=request.user,
entity_type=entity_type,
project_id=project_id,
**self.get_entity_id_fiekd(entity_type, entity_identifier),
**self.get_entity_id_field(entity_type, entity_identifier),
)
# Get the presigned URL
@@ -633,7 +665,6 @@ class ProjectAssetEndpoint(BaseAPIView):
class ProjectBulkAssetEndpoint(BaseAPIView):
@allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST])
def post(self, request, slug, project_id, entity_id):
asset_ids = request.data.get("asset_ids", [])
+23 -5
View File
@@ -20,6 +20,8 @@ from plane.db.models import FileAsset, Workspace
from plane.bgtasks.issue_activities_task import issue_activity
from plane.app.permissions import allow_permission, ROLE
from plane.settings.storage import S3Storage
from plane.payment.flags.flag_decorator import check_workspace_feature_flag
from plane.payment.flags.flag import FeatureFlag
class IssueAttachmentEndpoint(BaseAPIView):
@@ -71,7 +73,6 @@ class IssueAttachmentEndpoint(BaseAPIView):
notification=True,
origin=request.META.get("HTTP_ORIGIN"),
)
return Response(status=status.HTTP_204_NO_CONTENT)
@allow_permission(
@@ -97,7 +98,27 @@ class IssueAttachmentV2Endpoint(BaseAPIView):
def post(self, request, slug, project_id, issue_id):
name = request.data.get("name")
type = request.data.get("type", False)
size = int(request.data.get("size", settings.FILE_SIZE_LIMIT))
size = request.data.get("size")
# Check if the request is valid
if not name or not size:
return Response(
{
"error": "Invalid request.",
"status": False,
},
status=status.HTTP_400_BAD_REQUEST,
)
# Check if the file size is greater than the limit
if check_workspace_feature_flag(
feature_key=FeatureFlag.FILE_SIZE_LIMIT_PRO,
slug=slug,
user_id=str(request.user.id),
):
size_limit = min(size, settings.PRO_FILE_SIZE_LIMIT)
else:
size_limit = min(size, settings.FILE_SIZE_LIMIT)
if not type or type not in settings.ATTACHMENT_MIME_TYPES:
return Response(
@@ -114,9 +135,6 @@ class IssueAttachmentV2Endpoint(BaseAPIView):
# asset key
asset_key = f"{workspace.id}/{uuid.uuid4().hex}-{name}"
# Get the size limit
size_limit = min(size, settings.FILE_SIZE_LIMIT)
# Create a File Asset
asset = FileAsset.objects.create(
attributes={
@@ -1,9 +1,5 @@
# Django imports
from django.db.models import (
Exists,
OuterRef,
Prefetch,
)
from django.db.models import Exists, OuterRef, Prefetch, Q
from django.utils import timezone
# Module imports
@@ -69,6 +65,15 @@ class WorkspaceActiveCycleEndpoint(BaseAPIView):
.order_by("-is_favorite", "name")
.distinct()
)
active_cycles = active_cycles.filter(
~Q(
project__project_projectmember__role=5,
project__project_projectmember__member=self.request.user,
project__project_projectmember__is_active=True,
)
)
return self.paginate(
request=request,
queryset=active_cycles,
+4 -3
View File
@@ -27,7 +27,7 @@ from plane.db.models import (
IssueVote,
IssueView,
IssueLink,
IssueAttachment,
FileAsset,
)
from plane.utils.issue_filters import issue_filters
from plane.ee.serializers import (
@@ -131,8 +131,9 @@ class IssueViewsPublicEndpoint(BaseAPIView):
.values("count")
)
.annotate(
attachment_count=IssueAttachment.objects.filter(
issue=OuterRef("id")
attachment_count=FileAsset.objects.filter(
entity_type=FileAsset.EntityTypeContext.ISSUE_ATTACHMENT,
entity_identifier=OuterRef("id"),
)
.order_by()
.annotate(count=Func(F("id"), function="Count"))
+4 -3
View File
@@ -24,7 +24,7 @@ from plane.db.models import (
IssueAssignee,
IssueLabel,
Workspace,
IssueAttachment,
FileAsset,
IssueSubscriber,
)
@@ -291,9 +291,10 @@ class IssueAttachmentMutation:
issue: strawberry.ID,
attachment: strawberry.ID,
) -> bool:
issue_attachment = await sync_to_async(IssueAttachment.objects.get)(
issue_attachment = await sync_to_async(FileAsset.objects.get)(
id=attachment,
issue_id=issue,
entity_type=FileAsset.EntityTypeContext.ISSUE_ATTACHMENT,
entity_identifier=issue,
project_id=project,
workspace__slug=slug,
)
@@ -9,7 +9,7 @@ from strawberry.types import Info
from strawberry.permission import PermissionExtension
# Module Imports
from plane.db.models import IssueAttachment
from plane.db.models import FileAsset
from plane.graphql.types.attachment import IssueAttachmentType
from plane.graphql.permissions.project import ProjectBasePermission
@@ -28,8 +28,11 @@ class IssueAttachmentQuery:
) -> list[IssueAttachmentType]:
issue_attachments = await sync_to_async(list)(
IssueAttachment.objects.filter(
issue_id=issue, workspace__slug=slug, project_id=project
FileAsset.objects.filter(
entity_identifier=issue,
entity_type=FileAsset.EntityTypeContext.ISSUE_ATTACHMENT,
workspace__slug=slug,
project_id=project,
)
)
return issue_attachments
+5 -4
View File
@@ -8,10 +8,10 @@ import strawberry_django
from strawberry.scalars import JSON
# Module Imports
from plane.db.models import IssueAttachment
from plane.db.models import FileAsset
@strawberry_django.type(IssueAttachment)
@strawberry_django.type(FileAsset)
class IssueAttachmentType:
id: strawberry.ID
created_at: datetime
@@ -24,7 +24,8 @@ class IssueAttachmentType:
updated_by: strawberry.ID
project: strawberry.ID
workspace: strawberry.ID
issue: strawberry.ID
entity_identifier: strawberry.ID
entity_type: str
@strawberry.field
def workspace(self) -> int:
@@ -36,7 +37,7 @@ class IssueAttachmentType:
@strawberry.field
def issue(self) -> int:
return self.issue_id
return self.entity_identifier
@strawberry.field
def created_by(self) -> int:
+2
View File
@@ -30,6 +30,8 @@ class FeatureFlag(Enum):
PROJECT_GROUPING = "PROJECT_GROUPING"
# Active cycle progress
ACTIVE_CYCLE_PRO = "ACTIVE_CYCLE_PRO"
# Pro file size limit
FILE_SIZE_LIMIT_PRO = "FILE_SIZE_LIMIT_PRO"
class AdminFeatureFlag(Enum):
+1
View File
@@ -340,6 +340,7 @@ if bool(os.environ.get("SENTRY_DSN", False)) and os.environ.get(
# Application Envs
SLACK_BOT_TOKEN = os.environ.get("SLACK_BOT_TOKEN", False)
FILE_SIZE_LIMIT = int(os.environ.get("FILE_SIZE_LIMIT", 5242880))
PRO_FILE_SIZE_LIMIT = int(os.environ.get("PRO_FILE_SIZE_LIMIT", 104857600))
# Unsplash Access key
UNSPLASH_ACCESS_KEY = os.environ.get("UNSPLASH_ACCESS_KEY")
@@ -20,8 +20,8 @@ interface IDocumentReadOnlyEditor {
containerClassName: string;
displayConfig?: TDisplayConfig;
editorClassName?: string;
fileHandler: Pick<TFileHandler, "getAssetSrc">;
embedHandler: TReadOnlyEmbedConfig;
fileHandler: Pick<TFileHandler, "getAssetSrc">;
tabIndex?: number;
handleEditorReady?: (value: boolean) => void;
mentionHandler: {
@@ -6,6 +6,8 @@ import { FileText } from "lucide-react";
import { DocumentReadOnlyEditorWithRef, EditorRefApi } from "@plane/editor";
// ui
import { Logo } from "@plane/ui";
// helpers
import { getReadOnlyEditorFileHandlers } from "@/helpers/editor.helper";
// hooks
import { usePublish } from "@/hooks/store";
import { useMention } from "@/hooks/use-mention";
@@ -63,6 +65,9 @@ export const PageDetailsMainContent: React.FC<Props> = observer((props) => {
id={pageDetails.id}
initialValue={pageDetails.description_html ?? "<p></p>"}
containerClassName="p-0 pb-64 border-none"
fileHandler={getReadOnlyEditorFileHandlers({
anchor,
})}
mentionHandler={{
highlights: mentionHighlights,
}}
@@ -21,11 +21,11 @@ import { EIssuesStoreType } from "@/constants/issue";
// helpers
import { cn } from "@/helpers/common.helper";
import { renderFormattedDate, renderFormattedDateWithoutYear } from "@/helpers/date-time.helper";
import { getFileURL } from "@/helpers/file.helper";
// hooks
import { useIssues, useProjectState } from "@/hooks/store";
import useLocalStorage from "@/hooks/use-local-storage";
export type ActiveCycleStatsProps = {
workspaceSlug: string;
projectId: string;
@@ -165,7 +165,7 @@ export const ActiveCycleStats: FC<ActiveCycleStatsProps> = observer((props) => {
<div className="flex items-center gap-1.5 flex-shrink-0">
<StateDropdown
value={issue.state_id ?? undefined}
onChange={() => { }}
onChange={() => {}}
projectId={projectId?.toString() ?? ""}
disabled
buttonVariant="background-with-text"
@@ -216,7 +216,10 @@ export const ActiveCycleStats: FC<ActiveCycleStatsProps> = observer((props) => {
key={assignee.assignee_id}
title={
<div className="flex items-center gap-2">
<Avatar name={assignee?.display_name ?? undefined} src={assignee?.avatar ?? undefined} />
<Avatar
name={assignee?.display_name ?? undefined}
src={getFileURL(assignee?.avatar_url ?? "")}
/>
<span>{assignee.display_name}</span>
</div>
+3 -2
View File
@@ -6,6 +6,7 @@ import { ICycle, TCycleGroups } from "@plane/types";
import { Tooltip, CycleGroupIcon, getButtonStyling, Avatar, AvatarGroup } from "@plane/ui";
// helpers
import { renderFormattedDate, findHowManyDaysLeft } from "@/helpers/date-time.helper";
import { getFileURL } from "@/helpers/file.helper";
import { truncateText } from "@/helpers/string.helper";
// hooks
import { useMember } from "@/hooks/store";
@@ -48,7 +49,7 @@ export const ActiveCycleHeader: FC<ActiveCycleHeaderProps> = (props) => {
<div className="flex items-center gap-4">
<div className="rounded-sm text-sm">
<div className="flex gap-2 divide-x spac divide-x-border-300 text-sm whitespace-nowrap text-custom-text-300 font-medium">
<Avatar name={cycleOwnerDetails?.display_name} src={cycleOwnerDetails?.avatar} />
<Avatar name={cycleOwnerDetails?.display_name} src={getFileURL(cycleOwnerDetails?.avatar_url ?? "")} />
{cycleAssignee.length > 0 && (
<span className="pl-2">
<AvatarGroup showTooltip>
@@ -56,7 +57,7 @@ export const ActiveCycleHeader: FC<ActiveCycleHeaderProps> = (props) => {
<Avatar
key={member.assignee_id}
name={member?.display_name ?? ""}
src={member?.avatar ?? ""}
src={getFileURL(member?.avatar_url ?? "")}
showTooltip={false}
/>
))}
@@ -0,0 +1,80 @@
import { FC } from "react";
import Link from "next/link";
// icons
import { UserCircle2 } from "lucide-react";
// types
import { ICycle, TCycleGroups } from "@plane/types";
// ui
import { Tooltip, CycleGroupIcon, getButtonStyling } from "@plane/ui";
// helpers
import { renderFormattedDate, findHowManyDaysLeft } from "@/helpers/date-time.helper";
import { getFileURL } from "@/helpers/file.helper";
import { truncateText } from "@/helpers/string.helper";
// hooks
import { useMember } from "@/hooks/store";
export type ActiveCycleHeaderProps = {
cycle: ICycle;
workspaceSlug: string;
projectId: string;
};
export const ActiveCycleHeader: FC<ActiveCycleHeaderProps> = (props) => {
const { cycle, workspaceSlug, projectId } = props;
// store
const { getUserDetails } = useMember();
const cycleOwnerDetails = cycle && cycle.owned_by_id ? getUserDetails(cycle.owned_by_id) : undefined;
const daysLeft = findHowManyDaysLeft(cycle.end_date) ?? 0;
const currentCycleStatus = cycle?.status?.toLocaleLowerCase() as TCycleGroups;
return (
<div className="flex items-center justify-between px-3 py-1.5 rounded-lg border-[0.5px] border-custom-border-100 bg-custom-background-90">
<div className="flex items-center gap-2 cursor-default">
<CycleGroupIcon cycleGroup={currentCycleStatus} className="h-4 w-4" />
<Tooltip tooltipContent={cycle.name} position="top-left">
<h3 className="break-words text-lg font-medium">{truncateText(cycle.name, 70)}</h3>
</Tooltip>
<Tooltip
tooltipContent={`Start date: ${renderFormattedDate(cycle.start_date ?? "")} Due Date: ${renderFormattedDate(
cycle.end_date ?? ""
)}`}
position="top-left"
>
<span className="flex gap-1 whitespace-nowrap rounded-sm text-custom-text-400 font-semibold text-sm leading-5">
{`${daysLeft} ${daysLeft > 1 ? "days" : "day"} left`}
</span>
</Tooltip>
</div>
<div className="flex items-center gap-4">
<div className="rounded-sm text-sm">
<div className="flex gap-2 text-sm whitespace-nowrap text-custom-text-300 font-medium">
<span className="flex items-center gap-1.5">
<UserCircle2 className="h-4 w-4" />
<span className="text-base leading-5">Lead</span>
</span>
<div className="flex items-center gap-1.5">
{cycleOwnerDetails?.avatar_url && cycleOwnerDetails?.avatar_url !== "" ? (
<img
src={getFileURL(cycleOwnerDetails?.avatar_url)}
className="rounded-full flex-shrink-0 w-5 h-5 object-cover"
alt={cycleOwnerDetails?.display_name}
/>
) : (
<span className="flex h-5 w-5 items-center justify-center rounded-full bg-custom-background-100 capitalize">
{cycleOwnerDetails?.display_name.charAt(0)}
</span>
)}
<span className="text-base leading-5">{cycleOwnerDetails?.display_name}</span>
</div>
</div>
</div>
<Link
href={`/${workspaceSlug}/projects/${projectId}/cycles/${cycle.id}`}
className={`${getButtonStyling("primary", "sm")} cursor-pointer`}
>
View Cycle
</Link>
</div>
</div>
);
};
@@ -1,15 +1,18 @@
import { FC, useRef, useState } from "react";
import { observer } from "mobx-react-lite";
import Image from "next/image";
import { useParams } from "next/navigation";
import useSWR from "swr";
import { ExternalLink, RefreshCw } from "lucide-react";
// editor
// plane editor
import { DocumentReadOnlyEditorWithRef, EditorRefApi } from "@plane/editor";
// ui
// plane ui
import { Button, EModalPosition, EModalWidth, getButtonStyling, ModalCore, setToast, TOAST_TYPE } from "@plane/ui";
// helpers
// components
import { LogoSpinner } from "@/components/common";
// helpers
import { cn } from "@/helpers/common.helper";
import { getReadOnlyEditorFileHandlers } from "@/helpers/editor.helper";
// hooks
import { useInstance } from "@/hooks/store";
// assets
@@ -29,6 +32,8 @@ export const ProductUpdatesModal: FC<ProductUpdatesModalProps> = observer((props
const { isOpen, handleClose } = props;
// states
const [isCheckingForUpdates, setIsCheckingForUpdates] = useState(false);
// params
const { workspaceSlug, projectId } = useParams();
// store
const { isUpdateAvailable, updateInstanceInfo } = useInstance();
const { currentWorkspaceSubscribedPlanDetail: subscriptionDetail } = useWorkspaceSubscription();
@@ -137,6 +142,10 @@ export const ProductUpdatesModal: FC<ProductUpdatesModalProps> = observer((props
id={data.id}
initialValue={data.description_html ?? "<p></p>"}
containerClassName="p-0 border-none"
fileHandler={getReadOnlyEditorFileHandlers({
projectId: projectId?.toString() ?? "",
workspaceSlug: workspaceSlug?.toString() ?? "",
})}
mentionHandler={{
highlights: () => Promise.resolve([]),
}}
@@ -12,6 +12,7 @@ import {
renderFormattedDate,
renderFormattedTime,
} from "@/helpers/date-time.helper";
import { getFileURL } from "@/helpers/file.helper";
// hooks
import { useMember } from "@/hooks/store";
import { usePlatformOS } from "@/hooks/use-platform-os";
@@ -69,9 +70,9 @@ export const IssueActivityWorklog: FC<TIssueActivityWorklog> = observer((props)
>
<div className="absolute left-[13px] top-0 bottom-0 w-0.5 bg-custom-background-80" aria-hidden />
<div className="flex-shrink-0 relative w-7 h-7 rounded-full flex justify-center items-center z-10 bg-gray-500 text-white border border-white uppercase font-medium">
{currentUser?.member?.avatar && currentUser?.member?.avatar !== "" ? (
{currentUser?.member?.avatar_url && currentUser?.member?.avatar_url !== "" ? (
<img
src={currentUser?.member?.avatar}
src={getFileURL(currentUser?.member?.avatar_url)}
alt={currentUser?.member?.display_name}
height={30}
width={30}
+5 -4
View File
@@ -1,7 +1,6 @@
"use client";
import React, { RefObject, useEffect, useRef, useState } from "react";
import { useParams } from "next/navigation";
import { ChevronRight, CornerDownRight, LucideIcon, PencilLine, RefreshCcw, Sparkles } from "lucide-react";
// plane editor
import { EditorRefApi } from "@plane/editor";
@@ -21,6 +20,8 @@ type Props = {
editorRef: RefObject<EditorRefApi>;
isOpen: boolean;
onClose: () => void;
projectId?: string;
workspaceSlug: string;
};
const MENU_ITEMS: {
@@ -93,15 +94,13 @@ const TONES_LIST = [
];
export const EditorAIMenu: React.FC<Props> = (props) => {
const { editorRef, isOpen, onClose } = props;
const { editorRef, isOpen, onClose, projectId, workspaceSlug } = props;
// states
const [activeTask, setActiveTask] = useState<AI_EDITOR_TASKS | null>(null);
const [response, setResponse] = useState<string | undefined>(undefined);
const [isRegenerating, setIsRegenerating] = useState(false);
// refs
const responseContainerRef = useRef<HTMLDivElement>(null);
// params
const { workspaceSlug } = useParams();
const handleGenerateResponse = async (payload: TTaskPayload) => {
if (!workspaceSlug) return;
await aiService.performEditorTask(workspaceSlug.toString(), payload).then((res) => setResponse(res.response));
@@ -235,6 +234,8 @@ export const EditorAIMenu: React.FC<Props> = (props) => {
initialValue={response}
containerClassName="!p-0 border-none"
editorClassName="!pl-0"
projectId={projectId}
workspaceSlug={workspaceSlug}
/>
<div className="mt-3 flex items-center gap-4">
<button
+34 -9
View File
@@ -14,10 +14,12 @@ import {
} from "@plane/editor";
// types
import { IUserLite } from "@plane/types";
import { EFileAssetType } from "@plane/types/src/enums";
// components
import { PageContentBrowser, PageEditorTitle, PageContentLoader } from "@/components/pages";
// helpers
import { cn, LIVE_BASE_PATH, LIVE_BASE_URL } from "@/helpers/common.helper";
import { getEditorFileHandlers, getReadOnlyEditorFileHandlers } from "@/helpers/editor.helper";
import { generateRandomColor } from "@/helpers/string.helper";
// hooks
import { useMember, useUser, useWorkspace } from "@/hooks/store";
@@ -26,6 +28,7 @@ import { usePageFilters } from "@/hooks/use-page-filters";
import { EditorAIMenu, IssueEmbedCard } from "@/plane-web/components/pages";
// plane web hooks
import { useEditorFlagging } from "@/plane-web/hooks/use-editor-flagging";
import { useFileSize } from "@/plane-web/hooks/use-file-size";
import { useWorkspaceIssueEmbed } from "@/plane-web/hooks/use-workspace-issue-embed";
import { useWorkspaceMention } from "@/plane-web/hooks/use-workspace-mention";
// store
@@ -69,7 +72,7 @@ export const WorkspacePageEditorBody: React.FC<Props> = observer((props) => {
const pageId = page?.id;
const pageTitle = page?.name ?? "";
const pageDescription = page?.description_html;
const { isContentEditable, updateTitle, setIsSubmitting } = page;
const { isContentEditable, updateTitle } = page;
const workspaceMemberDetails = workspaceMemberIds?.map((id) => getUserDetails(id) as IUserLite);
// use-mention
const { mentionHighlights, mentionSuggestions } = useWorkspaceMention({
@@ -83,6 +86,8 @@ export const WorkspacePageEditorBody: React.FC<Props> = observer((props) => {
const { fontSize, fontStyle, isFullWidth } = usePageFilters();
// issue-embed
const { fetchIssues } = useWorkspaceIssueEmbed(workspaceSlug?.toString() ?? "");
// file size
const { maxFileSize } = useFileSize();
const displayConfig: TDisplayConfig = {
fontSize,
@@ -90,8 +95,15 @@ export const WorkspacePageEditorBody: React.FC<Props> = observer((props) => {
};
const getAIMenu = useCallback(
({ isOpen, onClose }: TAIMenuProps) => <EditorAIMenu editorRef={editorRef} isOpen={isOpen} onClose={onClose} />,
[editorRef]
({ isOpen, onClose }: TAIMenuProps) => (
<EditorAIMenu
editorRef={editorRef}
isOpen={isOpen}
onClose={onClose}
workspaceSlug={workspaceSlug?.toString() ?? ""}
/>
),
[editorRef, workspaceSlug]
);
const handleServerConnect = useCallback(() => {
@@ -171,12 +183,22 @@ export const WorkspacePageEditorBody: React.FC<Props> = observer((props) => {
{isContentEditable ? (
<CollaborativeDocumentEditorWithRef
id={pageId}
fileHandler={{
cancel: fileService.cancelUpload,
delete: fileService.getDeleteImageFunction(workspaceId),
restore: fileService.getRestoreImageFunction(workspaceId),
upload: fileService.getUploadFileFunction(workspaceSlug as string, setIsSubmitting),
}}
fileHandler={getEditorFileHandlers({
maxFileSize,
uploadFile: async (file) => {
const { asset_id } = await fileService.uploadWorkspaceAsset(
workspaceSlug?.toString() ?? "",
{
entity_identifier: pageId,
entity_type: EFileAssetType.PAGE_DESCRIPTION,
},
file
);
return asset_id;
},
workspaceId,
workspaceSlug: workspaceSlug?.toString() ?? "",
})}
handleEditorReady={handleEditorReady}
ref={editorRef}
containerClassName="h-full p-0 pb-64"
@@ -237,6 +259,9 @@ export const WorkspacePageEditorBody: React.FC<Props> = observer((props) => {
containerClassName="p-0 pb-64 border-none"
displayConfig={displayConfig}
editorClassName="pl-10"
fileHandler={getReadOnlyEditorFileHandlers({
workspaceSlug: workspaceSlug?.toString() ?? "",
})}
mentionHandler={{
highlights: mentionHighlights,
}}
@@ -7,6 +7,7 @@ import { Earth, Info, Lock, Minus } from "lucide-react";
import { Avatar, FavoriteStar, TOAST_TYPE, Tooltip, setToast } from "@plane/ui";
// helpers
import { renderFormattedDate } from "@/helpers/date-time.helper";
import { getFileURL } from "@/helpers/file.helper";
// hooks
import { useMember } from "@/hooks/store";
// plane web components
@@ -53,7 +54,7 @@ export const PageListBlockItemAction: FC<Props> = observer((props) => {
{/* page details */}
<div className="cursor-default">
<Tooltip tooltipHeading="Owned by" tooltipContent={ownerDetails?.display_name}>
<Avatar src={ownerDetails?.avatar} name={ownerDetails?.display_name} />
<Avatar src={getFileURL(ownerDetails?.avatar_url ?? "")} name={ownerDetails?.display_name} />
</Tooltip>
</div>
<div className="cursor-default text-custom-text-300">
+7 -6
View File
@@ -17,6 +17,7 @@ import { Avatar, Loader, TOAST_TYPE, setToast } from "@plane/ui";
import { WorkspaceLogo } from "@/components/workspace";
// helpers
import { cn, GOD_MODE_URL } from "@/helpers/common.helper";
import { getFileURL } from "@/helpers/file.helper";
// hooks
import { useAppTheme, useUser, useUserProfile, useWorkspace } from "@/hooks/store";
@@ -107,7 +108,7 @@ export const PagesAppSidebarDropdown = observer(() => {
)}
>
<div className="flex-grow flex items-center gap-2 truncate">
<WorkspaceLogo logo={activeWorkspace?.logo} name={activeWorkspace?.name} />
<WorkspaceLogo logo={getFileURL(activeWorkspace?.logo_url ?? "")} name={activeWorkspace?.name} />
{!sidebarCollapsed && (
<h4 className="truncate text-base font-medium text-custom-text-100">
{activeWorkspace?.name ?? "Loading..."}
@@ -160,17 +161,17 @@ export const PagesAppSidebarDropdown = observer(() => {
<div className="flex items-center justify-start gap-2.5 truncate">
<span
className={`relative flex h-6 w-6 flex-shrink-0 items-center justify-center p-2 text-xs uppercase ${
!workspace?.logo && "rounded bg-custom-primary-500 text-white"
!workspace?.logo_url && "rounded bg-custom-primary-500 text-white"
}`}
>
{workspace?.logo && workspace.logo !== "" ? (
{workspace?.logo_url && workspace.logo_url !== "" ? (
<img
src={workspace.logo}
src={getFileURL(workspace.logo_url)}
className="absolute left-0 top-0 h-full w-full rounded object-cover"
alt="Workspace Logo"
/>
) : (
workspace?.name?.charAt(0) ?? "..."
(workspace?.name?.charAt(0) ?? "...")
)}
</span>
<h5
@@ -250,7 +251,7 @@ export const PagesAppSidebarDropdown = observer(() => {
<Menu.Button className="grid place-items-center outline-none" ref={setReferenceElement}>
<Avatar
name={currentUser?.display_name}
src={currentUser?.avatar || undefined}
src={getFileURL(currentUser?.avatar_url ?? "")}
size={24}
shape="square"
className="!text-base"
@@ -8,6 +8,8 @@ import { IUserLite } from "@plane/types";
import { Loader } from "@plane/ui";
// components
import { TVersionEditorProps } from "@/components/pages";
// helpers
import { getReadOnlyEditorFileHandlers } from "@/helpers/editor.helper";
// hooks
import { useMember, useUser } from "@/hooks/store";
import { usePageFilters } from "@/hooks/use-page-filters";
@@ -94,6 +96,9 @@ export const WorkspacePagesVersionEditor: React.FC<TVersionEditorProps> = observ
containerClassName="p-0 pb-64 border-none"
displayConfig={displayConfig}
editorClassName="pl-10"
fileHandler={getReadOnlyEditorFileHandlers({
workspaceSlug: workspaceSlug?.toString() ?? "",
})}
mentionHandler={{
highlights: mentionHighlights,
}}
@@ -2,8 +2,10 @@
import { observer } from "mobx-react";
import { X } from "lucide-react";
// ui
// plane ui
import { Avatar } from "@plane/ui";
// helpers
import { getFileURL } from "@/helpers/file.helper";
// types
import { useMember } from "@/hooks/store";
@@ -29,7 +31,7 @@ export const AppliedMembersFilters: React.FC<Props> = observer((props) => {
return (
<div key={memberId} className="flex items-center gap-1 rounded bg-custom-background-80 p-1 text-xs">
<Avatar name={memberDetails.display_name} src={memberDetails.avatar} showTooltip={false} />
<Avatar name={memberDetails.display_name} src={getFileURL(memberDetails.avatar_url)} showTooltip={false} />
<span className="normal-case">{memberDetails.display_name}</span>
{editable && (
<button
+13 -15
View File
@@ -5,6 +5,8 @@ import { observer } from "mobx-react";
import { useForm, FormProvider } from "react-hook-form";
// ui
import { Button, setToast, TOAST_TYPE } from "@plane/ui";
// types
import { TCreateProjectFormProps } from "@/ce/components/projects/create/root";
// constants
import ProjectCommonAttributes from "@/components/project/create/common-attributes";
import ProjectCreateHeader from "@/components/project/create/header";
@@ -21,16 +23,8 @@ import { TProject } from "@/plane-web/types/projects";
import { EWorkspaceFeatures } from "@/plane-web/types/workspace-feature";
import ProjectAttributes from "./attributes";
type Props = {
setToFavorite?: boolean;
workspaceSlug: string;
onClose: () => void;
handleNextStep: (projectId: string) => void;
data?: Partial<TProject>;
};
const defaultValues: Partial<TProject> = {
cover_image: PROJECT_UNSPLASH_COVERS[Math.floor(Math.random() * PROJECT_UNSPLASH_COVERS.length)],
cover_image_url: PROJECT_UNSPLASH_COVERS[Math.floor(Math.random() * PROJECT_UNSPLASH_COVERS.length)],
description: "",
logo_props: {
in_use: "emoji",
@@ -44,8 +38,8 @@ const defaultValues: Partial<TProject> = {
project_lead: null,
};
export const CreateProjectForm: FC<Props> = observer((props) => {
const { setToFavorite, workspaceSlug, onClose, handleNextStep, data } = props;
export const CreateProjectForm: FC<TCreateProjectFormProps> = observer((props) => {
const { setToFavorite, workspaceSlug, onClose, handleNextStep, data, updateCoverImageStatus } = props;
// store
const { captureProjectEvent } = useEventTracker();
const { addProjectToFavorites, createProject } = useProject();
@@ -97,23 +91,27 @@ export const CreateProjectForm: FC<Props> = observer((props) => {
id,
member_id: id,
role: EUserPermissions.MEMBER,
member__avatar: memberMap[id]?.avatar,
member__avatar_url: memberMap[id]?.avatar_url,
member__display_name: memberMap[id]?.display_name,
}));
formData.identifier = formData.identifier?.toUpperCase();
if (members) formData.members = members;
const coverImage = formData.cover_image_url;
return createProject(workspaceSlug.toString(), formData)
.then((res) => {
.then(async (res) => {
if (coverImage) {
await updateCoverImageStatus(res.id, coverImage);
}
const newPayload = {
...res,
state: "SUCCESS",
};
isProjectGroupingEnabled &&
members &&
if (isProjectGroupingEnabled && members) {
bulkAddMembersToProject(workspaceSlug.toString(), res.id, {
members,
});
}
captureProjectEvent({
eventName: PROJECT_CREATED,
payload: newPayload,
@@ -2,9 +2,12 @@
import { useMemo, useState } from "react";
import { observer } from "mobx-react";
// plane ui
import { Avatar } from "@plane/ui";
// components
import { FilterHeader, FilterOption } from "@/components/issues";
// helpers
import { getFileURL } from "@/helpers/file.helper";
// hooks
import { useMember } from "@/hooks/store";
@@ -86,7 +89,14 @@ export const FilterUser: React.FC<TFilterUser> = observer((props) => {
key={member.id}
isChecked={appliedFilters?.includes(member.id) ? true : false}
onClick={() => member.id && handleFilter(member.id)}
icon={<Avatar name={member.display_name} src={member.avatar} showTooltip={false} size="md" />}
icon={
<Avatar
name={member.display_name}
src={getFileURL(member.avatar_url)}
showTooltip={false}
size="md"
/>
}
title={member.display_name.charAt(0).toUpperCase() + member.display_name.slice(1)}
/>
)
@@ -6,6 +6,7 @@ import { IWorkspace } from "@plane/types";
import { Avatar, PriorityIcon, Tooltip } from "@plane/ui";
import { DateRangeDropdown, MemberDropdown } from "@/components/dropdowns";
import { renderFormattedPayloadDate, getDate } from "@/helpers/date-time.helper";
import { getFileURL } from "@/helpers/file.helper";
import { useMember, useUserPermissions } from "@/hooks/store";
import { EUserPermissions } from "@/plane-web/constants/user-permissions";
import { TProject } from "@/plane-web/types/projects";
@@ -111,7 +112,13 @@ const Attributes: React.FC<Props> = observer((props) => {
{ "cursor-not-allowed": !isEditingAllowed }
)}
>
<Avatar key={lead.id} name={lead.display_name} src={lead.avatar} size={14} className="text-[9px]" />
<Avatar
key={lead.id}
name={lead.display_name}
src={getFileURL(lead.avatar_url)}
size={14}
className="text-[9px]"
/>
<div>{lead.first_name}</div>
</div>
</Tooltip>
@@ -3,6 +3,7 @@
import smoothScrollIntoView from "smooth-scroll-into-view-if-needed";
import { IWorkspace, IWorkspaceMember } from "@plane/types";
import { Avatar, PriorityIcon } from "@plane/ui";
import { getFileURL } from "@/helpers/file.helper";
import { ProjectStateIcon } from "@/plane-web/components/workspace-project-states";
import { PROJECT_PRIORITY_MAP } from "@/plane-web/constants/project";
import { WORKSPACE_PROJECT_STATE_GROUPS } from "@/plane-web/constants/workspace-project-states";
@@ -82,7 +83,12 @@ export const groupDetails = (
return {
title: memberDetails?.display_name || "Created By",
icon: memberDetails ? (
<Avatar name={memberDetails.display_name} src={memberDetails.avatar} showTooltip={false} size="md" />
<Avatar
name={memberDetails.display_name}
src={getFileURL(memberDetails.avatar_url)}
showTooltip={false}
size="md"
/>
) : (
<></>
),
@@ -16,6 +16,7 @@ import {
import { Logo } from "@/components/common";
// constants
// helpers
import { getFileURL } from "@/helpers/file.helper";
import { copyUrlToClipboard } from "@/helpers/string.helper";
// hooks
import { useProject, useUserPermissions } from "@/hooks/store";
@@ -140,10 +141,10 @@ const Details: React.FC<Props> = observer((props) => {
<div className="relative ">
<div>
<img
src={
project.cover_image ??
"https://images.unsplash.com/photo-1672243775941-10d763d9adef?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80"
}
src={getFileURL(
project.cover_image_url ??
"https://images.unsplash.com/photo-1672243775941-10d763d9adef?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80"
)}
alt={project.name}
className="relative w-full rounded-t object-cover h-[120px]"
// ref={projectCardRef}
@@ -4,6 +4,7 @@ import Link from "next/link";
import { useParams } from "next/navigation";
// helpers
import { cn } from "@/helpers/common.helper";
import { getFileURL } from "@/helpers/file.helper";
// hooks
import { useMember } from "@/hooks/store";
import { TProject } from "@/plane-web/types/projects";
@@ -30,12 +31,12 @@ export const SpreadsheetLeadColumn: React.FC<Props> = observer((props: Props) =>
>
{lead ? (
<>
{lead.member.avatar && lead.member.avatar.trim() !== "" ? (
{lead.member.avatar_url && lead.member.avatar_url.trim() !== "" ? (
<Link href={`/${workspaceSlug}/profile/${lead.member.id}`}>
<span className="relative flex h-5 w-5 items-center justify-center rounded-full capitalize text-white ">
<img
width={20}
src={lead.member.avatar}
src={getFileURL(lead.member.avatar_url)}
className="absolute left-0 top-0 h-5 w-5 rounded-full object-cover"
alt={lead.member.display_name || lead.member.email}
/>
@@ -2,7 +2,10 @@
import { FC } from "react";
import { observer } from "mobx-react";
// plane ui
import { Avatar } from "@plane/ui";
// helpers
import { getFileURL } from "@/helpers/file.helper";
// hooks
import { useMember } from "@/hooks/store";
// plane web components
@@ -46,7 +49,7 @@ export const WorkspaceWorklogAppliedFilterUsers: FC<TWorkspaceWorklogAppliedFilt
<div className="flex items-center gap-1">
<Avatar
name={userDetails?.member?.display_name}
src={userDetails?.member?.avatar ?? undefined}
src={getFileURL(userDetails?.member?.avatar_url ?? "")}
shape="circle"
size="sm"
showTooltip={false}
@@ -2,7 +2,10 @@
import { FC } from "react";
import { observer } from "mobx-react";
// plane ui
import { Avatar, CustomSearchSelect } from "@plane/ui";
// helpers
import { getFileURL } from "@/helpers/file.helper";
// hooks
import { useMember } from "@/hooks/store";
import { useWorkspaceWorklogs } from "@/plane-web/hooks/store";
@@ -42,7 +45,7 @@ export const WorkspaceWorklogFilterUsers: FC<TWorkspaceWorklogFilterUsers> = obs
<div className="flex items-center gap-2">
<Avatar
name={userDetails?.member?.display_name}
src={userDetails?.member?.avatar ?? undefined}
src={getFileURL(userDetails?.member?.avatar_url ?? "")}
shape="circle"
size="sm"
showTooltip={false}
@@ -4,6 +4,7 @@ import { FC } from "react";
import { Avatar, Table } from "@plane/ui";
// helpers
import { convertMinutesToHoursMinutesString, renderFormattedDate } from "@/helpers/date-time.helper";
import { getFileURL } from "@/helpers/file.helper";
// hooks
import { useMember, useProject } from "@/hooks/store";
// plane web hooks
@@ -62,7 +63,7 @@ export const WorklogsPaginatedTableRoot: FC<TWorklogsPaginatedTableRoot> = (prop
<div className="flex items-center gap-2">
<Avatar
name={currentUser?.member?.display_name}
src={currentUser?.member?.avatar ?? undefined}
src={getFileURL(currentUser?.member?.avatar_url ?? "")}
shape="circle"
size="sm"
showTooltip={false}
@@ -7,6 +7,8 @@ import { cn } from "@plane/editor";
import { Button, EModalWidth, Input, ModalCore, setToast, TOAST_TYPE } from "@plane/ui";
// components
import { WorkspaceLogo } from "@/components/workspace";
// helpers
import { getFileURL } from "@/helpers/file.helper";
// hooks
import { useUserPermissions, useWorkspace } from "@/hooks/store";
// plane web constants
@@ -83,7 +85,7 @@ export const SubscriptionActivationModal: FC<TSubscriptionActivationModal> = obs
<h3 className="flex items-center whitespace-nowrap flex-wrap gap-2 text-xl font-medium">
Activate
<WorkspaceLogo
logo={currentWorkspace?.logo}
logo={getFileURL(currentWorkspace?.logo_url ?? "")}
name={currentWorkspace?.name}
classNames="text-lg font-medium h-5 w-5"
/>
+1
View File
@@ -0,0 +1 @@
export const MAX_PRO_FILE_SIZE = 100 * 1024 * 1024; // 100MB
+1 -1
View File
@@ -47,4 +47,4 @@ export const filterActivityOnSelectedFilters = (
export { EActivityFilterType };
export const ENABLE_LOCAL_DB_CACHE = true;
export const ENABLE_LOCAL_DB_CACHE = false;
+1
View File
@@ -22,6 +22,7 @@ export enum E_FEATURE_FLAGS {
PROJECT_GROUPING = "PROJECT_GROUPING",
ACTIVE_CYCLE_PRO = "ACTIVE_CYCLE_PRO",
NO_LOAD = "NO_LOAD",
FILE_SIZE_LIMIT_PRO = "FILE_SIZE_LIMIT_PRO",
// integrations
SILO_INTEGRATION = "SILO_INTEGRATION",
SILO_JIRA_INTEGRATION = "SILO_JIRA_INTEGRATION",
+33 -1
View File
@@ -1 +1,33 @@
export * from "ce/hooks/use-file-size";
import { useMemo } from "react";
import { useParams } from "next/navigation";
// constants
import { MAX_STATIC_FILE_SIZE } from "@/constants/common";
// hooks
import { useInstance } from "@/hooks/store";
// local constants
import { MAX_PRO_FILE_SIZE } from "../constants/common";
// local hooks
import { useFlag, useWorkspaceSubscription } from "./store";
type TReturnProps = {
maxFileSize: number;
};
export const useFileSize = (): TReturnProps => {
// params
const { workspaceSlug } = useParams();
// store hooks
const { config } = useInstance();
const { currentWorkspaceSubscribedPlanDetail: planDetails } = useWorkspaceSubscription();
// derived values
const isProPlanEnabled = useFlag(workspaceSlug?.toString() ?? "", "FILE_SIZE_LIMIT_PRO");
let maxFileSize: number | undefined = useMemo(() => config?.file_size_limit, [config?.file_size_limit]);
if (!planDetails?.is_self_managed && isProPlanEnabled) {
maxFileSize = MAX_PRO_FILE_SIZE;
}
return {
maxFileSize: maxFileSize ?? MAX_STATIC_FILE_SIZE,
};
};
+2 -2
View File
@@ -75,7 +75,7 @@ export const useWorkspaceMention = (props: Props) => {
type: "User",
title: `${memberDetails?.display_name}`,
subtitle: memberDetails?.email ?? "",
avatar: `${memberDetails?.avatar}`,
avatar: `${memberDetails?.avatar_url}`,
redirect_uri: `/${workspaceSlug}/profile/${memberDetails?.id}`,
}));
} else {
@@ -88,7 +88,7 @@ export const useWorkspaceMention = (props: Props) => {
type: "User",
title: `${memberDetails?.display_name}`,
subtitle: memberDetails?.email ?? "",
avatar: `${memberDetails?.avatar}`,
avatar: `${memberDetails?.avatar_url}`,
redirect_uri: `/${workspaceSlug}/profile/${memberDetails?.id}`,
}));
}
-1
View File
@@ -92,7 +92,6 @@ const nextConfig = {
destination: `${GOD_MODE_BASE_URL}/:path*`,
});
}
return rewrites;
},
};
+104 -104
View File
@@ -1749,33 +1749,33 @@
"@tanstack/react-virtual" "^3.0.0-beta.60"
client-only "^0.0.1"
"@hocuspocus/common@^2.13.6":
version "2.13.6"
resolved "https://registry.yarnpkg.com/@hocuspocus/common/-/common-2.13.6.tgz#952076654d2497a9c9de63e9a33b1b9307ccb294"
integrity sha512-jeEawHoaBckfbjMRPqjANjtQkeHgCBsk3XN7CEs/1jvUm60d86FT4y5fp3MWTEE18qkZacbZldn32za+72RBdg==
"@hocuspocus/common@^2.13.7":
version "2.13.7"
resolved "https://registry.yarnpkg.com/@hocuspocus/common/-/common-2.13.7.tgz#fe5530757f0937865e6188c633c9e52f997a1485"
integrity sha512-ROqYfW15XlAGd+qb/FVyp0zUC9Rosv7kdcck9LRMdfW3jT66wK9pDDWL2ily4Qj/zhbLCFtjAUPB4UKln/GYNQ==
dependencies:
lib0 "^0.2.87"
"@hocuspocus/extension-database@^2.11.3":
version "2.13.6"
resolved "https://registry.yarnpkg.com/@hocuspocus/extension-database/-/extension-database-2.13.6.tgz#8d30b66348e58851bad691a8548d750ac0b50715"
integrity sha512-lFt9yKzQ8VeErPyaRvqJsoNa6rBFISq5FehqjblsfrfIZvOvBiVwsyc+3d5gQnnQmJJ0rShGCIuLRGJi+MmUaA==
version "2.13.7"
resolved "https://registry.yarnpkg.com/@hocuspocus/extension-database/-/extension-database-2.13.7.tgz#d71aee885a91a050efacf85c2fec763c8dae65db"
integrity sha512-GMSnluhmfpy3V+P8uCyR/dwh7nNqIERSAf+Jpkg0GVSeOuGdDuoWTJr+gkQWTAVDVMwNAqlp+ZLpzc0Y/L34mg==
dependencies:
"@hocuspocus/server" "^2.13.6"
"@hocuspocus/server" "^2.13.7"
"@hocuspocus/extension-logger@^2.11.3":
version "2.13.6"
resolved "https://registry.yarnpkg.com/@hocuspocus/extension-logger/-/extension-logger-2.13.6.tgz#32ac413ba2d44d433235c1d7a8516953f341111e"
integrity sha512-DQ1zBGFdRBCEmGfo3bcR2W3P/6SQmMmSYq4iqKB98U54901fKJz7cI+vrp6Xfr447Z1j2sfdlN9YTPaVMjv4rQ==
version "2.13.7"
resolved "https://registry.yarnpkg.com/@hocuspocus/extension-logger/-/extension-logger-2.13.7.tgz#22443cc4df445b923416e168633636ef5978943a"
integrity sha512-mjlY0RjocWg4Qe1uVVL5lYXQs9yy80/5vrSuHMh9oFaXGGBOiVM7sOoM2IWl9k3ehBvlCid1xgNnNkNIJKDOPw==
dependencies:
"@hocuspocus/server" "^2.13.6"
"@hocuspocus/server" "^2.13.7"
"@hocuspocus/extension-redis@^2.13.5":
version "2.13.6"
resolved "https://registry.yarnpkg.com/@hocuspocus/extension-redis/-/extension-redis-2.13.6.tgz#b1410b63b197ef863bee24c86565a215e000ed7b"
integrity sha512-9H2MpXsSbHEUPvRTkm7kxsD7Ia0G4JbM5L5klN9+RqUecOAnQknx7GUfvjr7/6PLGVEymXK2e+NJVCvrx6N9Vg==
version "2.13.7"
resolved "https://registry.yarnpkg.com/@hocuspocus/extension-redis/-/extension-redis-2.13.7.tgz#eaee70944b9446d1fd17c4b313b0f7624e0ba50e"
integrity sha512-th6fo7LfTQKgOenJHbW55PWPZTv95bGgiDh7zOr+WSIiyKPHKXv4dXYUN5e2lcKr2MV76FJYheaW5uNE1hnkDQ==
dependencies:
"@hocuspocus/server" "^2.13.6"
"@hocuspocus/server" "^2.13.7"
ioredis "^4.28.2"
kleur "^4.1.4"
lodash.debounce "^4.0.8"
@@ -1783,21 +1783,21 @@
uuid "^10.0.0"
"@hocuspocus/provider@^2.13.5":
version "2.13.6"
resolved "https://registry.yarnpkg.com/@hocuspocus/provider/-/provider-2.13.6.tgz#feef3a3732897a4e70262ce71299e8a0b42ccc68"
integrity sha512-84tBdGU8275SXQirRQ5FbBGwsQ6iLNuIbmV2SV6/f361phBoAVUSobJ+CYAzdIJPlfIYSL2BwGJSRbbDhqJdJw==
version "2.13.7"
resolved "https://registry.yarnpkg.com/@hocuspocus/provider/-/provider-2.13.7.tgz#2595a85b78318bf6f927247d9d76f18ee6bbcec1"
integrity sha512-BjZIIV8tWf/MD/8IcEMSFA+sW4wtR/M9MmhN+XSssYJOZxnszw44Gdwda23TmhsXvCV+qggS8lGEs+SfZSzEag==
dependencies:
"@hocuspocus/common" "^2.13.6"
"@hocuspocus/common" "^2.13.7"
"@lifeomic/attempt" "^3.0.2"
lib0 "^0.2.87"
ws "^8.17.1"
"@hocuspocus/server@^2.11.3", "@hocuspocus/server@^2.13.6":
version "2.13.6"
resolved "https://registry.yarnpkg.com/@hocuspocus/server/-/server-2.13.6.tgz#a39b0eef7cdb4cf23aaf3abb032d330fdd90e273"
integrity sha512-VqiHkkQlfa2A5mFTe+rdePLt3kHJrk9ZzqDqWJfqQDlYHdyAXpW53cddsXYYDWQ/tZjYj3zQgZAT+78AHrnb/A==
"@hocuspocus/server@^2.11.3", "@hocuspocus/server@^2.13.7":
version "2.13.7"
resolved "https://registry.yarnpkg.com/@hocuspocus/server/-/server-2.13.7.tgz#e794382952337110c3283ee31bbf2db610b33596"
integrity sha512-D9juGX9NZoKT9/Ty/HGhaimHJe71DyKbYssC831oetYF33x3WSYV6GY82RhHo9xjKZE6r0Le7jgxgQb+u08slw==
dependencies:
"@hocuspocus/common" "^2.13.6"
"@hocuspocus/common" "^2.13.7"
async-lock "^1.3.1"
kleur "^4.1.4"
lib0 "^0.2.47"
@@ -2136,62 +2136,62 @@
prop-types "^15.8.1"
react-is "^18.3.1"
"@next/[email protected]4":
version "14.2.14"
resolved "https://registry.yarnpkg.com/@next/env/-/env-14.2.14.tgz#08f5175dab727102da02301ba61f7239773670fa"
integrity sha512-/0hWQfiaD5//LvGNgc8PjvyqV50vGK0cADYzaoOOGN8fxzBn3iAiaq3S0tCRnFBldq0LVveLcxCTi41ZoYgAgg==
"@next/[email protected]5":
version "14.2.15"
resolved "https://registry.yarnpkg.com/@next/env/-/env-14.2.15.tgz#06d984e37e670d93ddd6790af1844aeb935f332f"
integrity sha512-S1qaj25Wru2dUpcIZMjxeMVSwkt8BK4dmWHHiBuRstcIyOsMapqT4A4jSB6onvqeygkSSmOkyny9VVx8JIGamQ==
"@next/[email protected]4":
version "14.2.14"
resolved "https://registry.yarnpkg.com/@next/eslint-plugin-next/-/eslint-plugin-next-14.2.14.tgz#091581faecd7f2c434b2ba85dbe935d743d542a2"
integrity sha512-kV+OsZ56xhj0rnTn6HegyTGkoa16Mxjrpk7pjWumyB2P8JVQb8S9qtkjy/ye0GnTr4JWtWG4x/2qN40lKZ3iVQ==
"@next/[email protected]5":
version "14.2.15"
resolved "https://registry.yarnpkg.com/@next/eslint-plugin-next/-/eslint-plugin-next-14.2.15.tgz#796ae942a95b859e1add58e5b7ae78cfd55d59bb"
integrity sha512-pKU0iqKRBlFB/ocOI1Ip2CkKePZpYpnw5bEItEkuZ/Nr9FQP1+p7VDWr4VfOdff4i9bFmrOaeaU1bFEyAcxiMQ==
dependencies:
glob "10.3.10"
"@next/[email protected]4":
version "14.2.14"
resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.14.tgz#6dde2dac699dfe948b527385f2b350b3151989f4"
integrity sha512-bsxbSAUodM1cjYeA4o6y7sp9wslvwjSkWw57t8DtC8Zig8aG8V6r+Yc05/9mDzLKcybb6EN85k1rJDnMKBd9Gw==
"@next/[email protected]5":
version "14.2.15"
resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.15.tgz#6386d585f39a1c490c60b72b1f76612ba4434347"
integrity sha512-Rvh7KU9hOUBnZ9TJ28n2Oa7dD9cvDBKua9IKx7cfQQ0GoYUwg9ig31O2oMwH3wm+pE3IkAQ67ZobPfEgurPZIA==
"@next/[email protected]4":
version "14.2.14"
resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.14.tgz#25800213c4dc0f8cd765c88073d28a3144698e31"
integrity sha512-cC9/I+0+SK5L1k9J8CInahduTVWGMXhQoXFeNvF0uNs3Bt1Ub0Azb8JzTU9vNCr0hnaMqiWu/Z0S1hfKc3+dww==
"@next/[email protected]5":
version "14.2.15"
resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.15.tgz#b7baeedc6a28f7545ad2bc55adbab25f7b45cb89"
integrity sha512-5TGyjFcf8ampZP3e+FyCax5zFVHi+Oe7sZyaKOngsqyaNEpOgkKB3sqmymkZfowy3ufGA/tUgDPPxpQx931lHg==
"@next/[email protected]4":
version "14.2.14"
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.14.tgz#9c66bd1287d0c3633e7bf354f9c01e1b79747615"
integrity sha512-RMLOdA2NU4O7w1PQ3Z9ft3PxD6Htl4uB2TJpocm+4jcllHySPkFaUIFacQ3Jekcg6w+LBaFvjSPthZHiPmiAUg==
"@next/[email protected]5":
version "14.2.15"
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.15.tgz#fa13c59d3222f70fb4cb3544ac750db2c6e34d02"
integrity sha512-3Bwv4oc08ONiQ3FiOLKT72Q+ndEMyLNsc/D3qnLMbtUYTQAmkx9E/JRu0DBpHxNddBmNT5hxz1mYBphJ3mfrrw==
"@next/[email protected]4":
version "14.2.14"
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.14.tgz#da2ae16a24bb2b2a46447154e95da85c557ab09a"
integrity sha512-WgLOA4hT9EIP7jhlkPnvz49iSOMdZgDJVvbpb8WWzJv5wBD07M2wdJXLkDYIpZmCFfo/wPqFsFR4JS4V9KkQ2A==
"@next/[email protected]5":
version "14.2.15"
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.15.tgz#30e45b71831d9a6d6d18d7ac7d611a8d646a17f9"
integrity sha512-k5xf/tg1FBv/M4CMd8S+JL3uV9BnnRmoe7F+GWC3DxkTCD9aewFRH1s5rJ1zkzDa+Do4zyN8qD0N8c84Hu96FQ==
"@next/[email protected]4":
version "14.2.14"
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.14.tgz#635c62109b9cf0464e6322955a36931ebb9ed3e2"
integrity sha512-lbn7svjUps1kmCettV/R9oAvEW+eUI0lo0LJNFOXoQM5NGNxloAyFRNByYeZKL3+1bF5YE0h0irIJfzXBq9Y6w==
"@next/[email protected]5":
version "14.2.15"
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.15.tgz#5065db17fc86f935ad117483f21f812dc1b39254"
integrity sha512-kE6q38hbrRbKEkkVn62reLXhThLRh6/TvgSP56GkFNhU22TbIrQDEMrO7j0IcQHcew2wfykq8lZyHFabz0oBrA==
"@next/[email protected]4":
version "14.2.14"
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.14.tgz#1565caf6fa77c3280d8b05ffc8c542ff144a4855"
integrity sha512-7TcQCvLQ/hKfQRgjxMN4TZ2BRB0P7HwrGAYL+p+m3u3XcKTraUFerVbV3jkNZNwDeQDa8zdxkKkw2els/S5onQ==
"@next/[email protected]5":
version "14.2.15"
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.15.tgz#3c4a4568d8be7373a820f7576cf33388b5dab47e"
integrity sha512-PZ5YE9ouy/IdO7QVJeIcyLn/Rc4ml9M2G4y3kCM9MNf1YKvFY4heg3pVa/jQbMro+tP6yc4G2o9LjAz1zxD7tQ==
"@next/[email protected]4":
version "14.2.14"
resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.14.tgz#8df4feb3c9280155e9299f3cdfa32f3cface336a"
integrity sha512-8i0Ou5XjTLEje0oj0JiI0Xo9L/93ghFtAUYZ24jARSeTMXLUx8yFIdhS55mTExq5Tj4/dC2fJuaT4e3ySvXU1A==
"@next/[email protected]5":
version "14.2.15"
resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.15.tgz#fb812cc4ca0042868e32a6a021da91943bb08b98"
integrity sha512-2raR16703kBvYEQD9HNLyb0/394yfqzmIeyp2nDzcPV4yPjqNUG3ohX6jX00WryXz6s1FXpVhsCo3i+g4RUX+g==
"@next/[email protected]4":
version "14.2.14"
resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.14.tgz#1f0a2bafbb63147c8db102ca1524db9ffa959d0c"
integrity sha512-2u2XcSaDEOj+96eXpyjHjtVPLhkAFw2nlaz83EPeuK4obF+HmtDJHqgR1dZB7Gb6V/d55FL26/lYVd0TwMgcOQ==
"@next/[email protected]5":
version "14.2.15"
resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.15.tgz#ec26e6169354f8ced240c1427be7fd485c5df898"
integrity sha512-fyTE8cklgkyR1p03kJa5zXEaZ9El+kDNM5A+66+8evQS5e/6v0Gk28LqA0Jet8gKSOyP+OTm/tJHzMlGdQerdQ==
"@next/[email protected]4":
version "14.2.14"
resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.14.tgz#9d6446b3a8d5e67e199049d59ce7c0b8bd33ab51"
integrity sha512-MZom+OvZ1NZxuRovKt1ApevjiUJTcU2PmdJKL66xUPaJeRywnbGGRWUlaAOwunD6dX+pm83vj979NTC8QXjGWg==
"@next/[email protected]5":
version "14.2.15"
resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.15.tgz#18d68697002b282006771f8d92d79ade9efd35c4"
integrity sha512-SzqGbsLsP9OwKNUG9nekShTwhj6JSB9ZLMWQ8g1gG6hdE5gQLncbnbymrwy2yVmH9nikSLYRYxYMFu78Ggp7/g==
"@nicolo-ribaudo/[email protected]":
version "2.1.8-no-fsevents.3"
@@ -6498,10 +6498,10 @@ [email protected]:
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==
cookie@0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051"
integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==
cookie@0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.1.tgz#2f73c42142d5d5cf71310a74fc4ae61670e5dbc9"
integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==
core-js-compat@^3.38.0, core-js-compat@^3.38.1:
version "3.38.1"
@@ -7404,9 +7404,9 @@ es-get-iterator@^1.1.3:
stop-iteration-iterator "^1.0.0"
es-iterator-helpers@^1.0.19:
version "1.0.19"
resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz#117003d0e5fec237b4b5c08aded722e0c6d50ca8"
integrity sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==
version "1.1.0"
resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.1.0.tgz#f6d745d342aea214fe09497e7152170dc333a7a6"
integrity sha512-/SurEfycdyssORP/E+bj4sEu1CWw4EmLDsHynHwSXQ7utgbrMRWW195pTrCjFgFCddf/UkYm3oqKPRq5i8bJbw==
dependencies:
call-bind "^1.0.7"
define-properties "^1.2.1"
@@ -7415,12 +7415,12 @@ es-iterator-helpers@^1.0.19:
es-set-tostringtag "^2.0.3"
function-bind "^1.1.2"
get-intrinsic "^1.2.4"
globalthis "^1.0.3"
globalthis "^1.0.4"
has-property-descriptors "^1.0.2"
has-proto "^1.0.3"
has-symbols "^1.0.3"
internal-slot "^1.0.7"
iterator.prototype "^1.1.2"
iterator.prototype "^1.1.3"
safe-array-concat "^1.1.2"
es-module-lexer@^1.2.1, es-module-lexer@^1.5.0:
@@ -7586,11 +7586,11 @@ escodegen@^2.1.0:
source-map "~0.6.1"
eslint-config-next@^14.1.0:
version "14.2.14"
resolved "https://registry.yarnpkg.com/eslint-config-next/-/eslint-config-next-14.2.14.tgz#b2b5dedadd4afe20e2103b0ec44eb2f1d211fc63"
integrity sha512-TXwyjGICAlWC9O0OufS3koTsBKQH8l1xt3SY/aDuvtKHIwjTHplJKWVb1WOEX0OsDaxGbFXmfD2EY1sNfG0Y/w==
version "14.2.15"
resolved "https://registry.yarnpkg.com/eslint-config-next/-/eslint-config-next-14.2.15.tgz#ff9661835eaf9f2ef1717ace55073a8f71037fab"
integrity sha512-mKg+NC/8a4JKLZRIOBplxXNdStgxy7lzWuedUaCc8tev+Al9mwDUTujQH6W6qXDH9kycWiVo28tADWGvpBsZcQ==
dependencies:
"@next/eslint-plugin-next" "14.2.14"
"@next/eslint-plugin-next" "14.2.15"
"@rushstack/eslint-patch" "^1.3.3"
"@typescript-eslint/eslint-plugin" "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0"
"@typescript-eslint/parser" "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0"
@@ -7957,16 +7957,16 @@ express-ws@^5.0.2:
ws "^7.4.6"
express@^4.19.2, express@^4.20.0:
version "4.21.0"
resolved "https://registry.yarnpkg.com/express/-/express-4.21.0.tgz#d57cb706d49623d4ac27833f1cbc466b668eb915"
integrity sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==
version "4.21.1"
resolved "https://registry.yarnpkg.com/express/-/express-4.21.1.tgz#9dae5dda832f16b4eec941a4e44aa89ec481b281"
integrity sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==
dependencies:
accepts "~1.3.8"
array-flatten "1.1.1"
body-parser "1.20.3"
content-disposition "0.5.4"
content-type "~1.0.4"
cookie "0.6.0"
cookie "0.7.1"
cookie-signature "1.0.6"
debug "2.6.9"
depd "2.0.0"
@@ -8534,7 +8534,7 @@ globals@^14.0.0:
resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e"
integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==
globalthis@^1.0.3:
globalthis@^1.0.3, globalthis@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.4.tgz#7430ed3a975d97bfb59bcce41f5cabbafa651236"
integrity sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==
@@ -9319,7 +9319,7 @@ isomorphic.js@^0.2.4:
resolved "https://registry.yarnpkg.com/isomorphic.js/-/isomorphic.js-0.2.5.tgz#13eecf36f2dba53e85d355e11bf9d4208c6f7f88"
integrity sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==
iterator.prototype@^1.1.2:
iterator.prototype@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/iterator.prototype/-/iterator.prototype-1.1.3.tgz#016c2abe0be3bbdb8319852884f60908ac62bf9c"
integrity sha512-FW5iMbeQ6rBGm/oKgzq2aW4KvAGpxPzYES8N4g4xNXUKpL1mclMvOe+76AcLDTvD+Ze+sOpVhgdAQEKF4L9iGQ==
@@ -10342,11 +10342,11 @@ next-themes@^0.2.1:
integrity sha512-B+AKNfYNIzh0vqQQKqQItTS8evEouKD7H5Hj3kmuPERwddR2TxvDSFZuTj6T7Jfn1oyeUyJMydPl1Bkxkh0W7A==
next@^14.2.12:
version "14.2.14"
resolved "https://registry.yarnpkg.com/next/-/next-14.2.14.tgz#115f29443dfb96d23b4b5ab5c4547de339202ba7"
integrity sha512-Q1coZG17MW0Ly5x76shJ4dkC23woLAhhnDnw+DfTc7EpZSGuWrlsZ3bZaO8t6u1Yu8FVfhkqJE+U8GC7E0GLPQ==
version "14.2.15"
resolved "https://registry.yarnpkg.com/next/-/next-14.2.15.tgz#348e5603e22649775d19c785c09a89c9acb5189a"
integrity sha512-h9ctmOokpoDphRvMGnwOJAedT6zKhwqyZML9mDtspgf4Rh3Pn7UTYKqePNoDvhsWBAO5GoPNYshnAUGIazVGmw==
dependencies:
"@next/env" "14.2.14"
"@next/env" "14.2.15"
"@swc/helpers" "0.5.5"
busboy "1.6.0"
caniuse-lite "^1.0.30001579"
@@ -10354,15 +10354,15 @@ next@^14.2.12:
postcss "8.4.31"
styled-jsx "5.1.1"
optionalDependencies:
"@next/swc-darwin-arm64" "14.2.14"
"@next/swc-darwin-x64" "14.2.14"
"@next/swc-linux-arm64-gnu" "14.2.14"
"@next/swc-linux-arm64-musl" "14.2.14"
"@next/swc-linux-x64-gnu" "14.2.14"
"@next/swc-linux-x64-musl" "14.2.14"
"@next/swc-win32-arm64-msvc" "14.2.14"
"@next/swc-win32-ia32-msvc" "14.2.14"
"@next/swc-win32-x64-msvc" "14.2.14"
"@next/swc-darwin-arm64" "14.2.15"
"@next/swc-darwin-x64" "14.2.15"
"@next/swc-linux-arm64-gnu" "14.2.15"
"@next/swc-linux-arm64-musl" "14.2.15"
"@next/swc-linux-x64-gnu" "14.2.15"
"@next/swc-linux-x64-musl" "14.2.15"
"@next/swc-win32-arm64-msvc" "14.2.15"
"@next/swc-win32-ia32-msvc" "14.2.15"
"@next/swc-win32-x64-msvc" "14.2.15"
no-case@^3.0.4:
version "3.0.4"
@@ -13503,9 +13503,9 @@ typescript@^4.7.2:
integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
typescript@^5.2.2, typescript@^5.3.3:
version "5.6.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.2.tgz#d1de67b6bef77c41823f822df8f0b3bcff60a5a0"
integrity sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==
version "5.6.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.3.tgz#5f3449e31c9d94febb17de03cc081dd56d81db5b"
integrity sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==
uc.micro@^2.0.0, uc.micro@^2.1.0:
version "2.1.0"