mirror of
https://github.com/makeplane/plane.git
synced 2026-02-24 04:00:14 +01:00
Merge pull request #206 from makeplane/sync/ce-ee
sync: merge conflicts need to be resolved
This commit is contained in:
15
apiserver/plane/bgtasks/api_logs_task.py
Normal file
15
apiserver/plane/bgtasks/api_logs_task.py
Normal file
@@ -0,0 +1,15 @@
|
||||
from django.utils import timezone
|
||||
from datetime import timedelta
|
||||
from plane.db.models import APIActivityLog
|
||||
from celery import shared_task
|
||||
|
||||
|
||||
@shared_task
|
||||
def delete_api_logs():
|
||||
# Get the logs older than 30 days to delete
|
||||
logs_to_delete = APIActivityLog.objects.filter(
|
||||
created_at__lte=timezone.now() - timedelta(days=30)
|
||||
)
|
||||
|
||||
# Delete the logs
|
||||
logs_to_delete._raw_delete(logs_to_delete.db)
|
||||
@@ -152,7 +152,7 @@ def process_mention(mention_component):
|
||||
soup = BeautifulSoup(mention_component, "html.parser")
|
||||
mentions = soup.find_all("mention-component")
|
||||
for mention in mentions:
|
||||
user_id = mention["id"]
|
||||
user_id = mention["entity_identifier"]
|
||||
user = User.objects.get(pk=user_id)
|
||||
user_name = user.display_name
|
||||
highlighted_name = f"@{user_name}"
|
||||
|
||||
@@ -128,7 +128,7 @@ def extract_mentions(issue_instance):
|
||||
"mention-component", attrs={"target": "users"}
|
||||
)
|
||||
|
||||
mentions = [mention_tag["id"] for mention_tag in mention_tags]
|
||||
mentions = [mention_tag["entity_identifier"] for mention_tag in mention_tags]
|
||||
|
||||
return list(set(mentions))
|
||||
except Exception:
|
||||
@@ -144,7 +144,7 @@ def extract_comment_mentions(comment_value):
|
||||
"mention-component", attrs={"target": "users"}
|
||||
)
|
||||
for mention_tag in mentions_tags:
|
||||
mentions.append(mention_tag["id"])
|
||||
mentions.append(mention_tag["entity_identifier"])
|
||||
return list(set(mentions))
|
||||
except Exception:
|
||||
return []
|
||||
@@ -663,9 +663,7 @@ def notifications(
|
||||
"old_value": str(
|
||||
last_activity.old_value
|
||||
),
|
||||
"activity_time": issue_activity.get(
|
||||
"created_at"
|
||||
),
|
||||
"activity_time": str(last_activity.created_at),
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
@@ -32,6 +32,10 @@ app.conf.beat_schedule = {
|
||||
"task": "plane.bgtasks.email_notification_task.stack_email_notification",
|
||||
"schedule": crontab(minute="*/5"),
|
||||
},
|
||||
"check-every-day-to-delete-api-logs": {
|
||||
"task": "plane.bgtasks.api_logs_task.delete_api_logs",
|
||||
"schedule": crontab(hour=0, minute=0),
|
||||
},
|
||||
}
|
||||
|
||||
# Load task modules from all registered Django app configs.
|
||||
|
||||
@@ -293,6 +293,7 @@ CELERY_IMPORTS = (
|
||||
"plane.bgtasks.exporter_expired_task",
|
||||
"plane.bgtasks.file_asset_task",
|
||||
"plane.bgtasks.email_notification_task",
|
||||
"plane.bgtasks.api_logs_task",
|
||||
# management tasks
|
||||
"plane.bgtasks.dummy_data_task",
|
||||
)
|
||||
|
||||
@@ -724,6 +724,7 @@ const activityDetails: {
|
||||
<IssueLink activity={activity} />
|
||||
</>
|
||||
)}
|
||||
{activity.verb === "2" && ` from inbox by marking a duplicate issue.`}
|
||||
</>
|
||||
),
|
||||
icon: <Inbox size={12} color="#6b7280" aria-hidden="true" />,
|
||||
|
||||
@@ -111,8 +111,8 @@ export const HeaderGroupByCard: FC<IHeaderGroupByCard> = observer((props) => {
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={`relative flex items-center gap-1 overflow-hidden ${
|
||||
verticalAlignPosition ? `flex-col` : `w-full flex-row`
|
||||
className={`relative flex items-center gap-1 ${
|
||||
verticalAlignPosition ? `flex-col` : `w-full flex-row overflow-hidden`
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
|
||||
@@ -106,7 +106,7 @@ export const IssueLabelSelect: React.FC<Props> = observer((props) => {
|
||||
{label ? (
|
||||
label
|
||||
) : value && value.length > 0 ? (
|
||||
<span className="flex items-center justify-center gap-2 text-xs">
|
||||
<span className="flex items-center justify-center gap-2 text-xs h-full">
|
||||
<IssueLabelsList
|
||||
labels={value.map((v) => projectLabels?.find((l) => l.id === v)) ?? []}
|
||||
length={3}
|
||||
|
||||
@@ -25,7 +25,7 @@ export const IssueLabelsList: FC<IssueLabelsListProps> = (props) => {
|
||||
tooltipContent={labels.map((l) => l?.name).join(", ")}
|
||||
isMobile={isMobile}
|
||||
>
|
||||
<div className="flex items-center gap-1 rounded border-[0.5px] border-custom-border-300 px-2 py-1 text-xs text-custom-text-200">
|
||||
<div className="h-full flex items-center gap-1 rounded border-[0.5px] border-custom-border-300 px-2 py-1 text-xs text-custom-text-200">
|
||||
<span className="h-2 w-2 flex-shrink-0 rounded-full bg-custom-primary" />
|
||||
{`${labels.length} Labels`}
|
||||
</div>
|
||||
|
||||
@@ -1,25 +1,32 @@
|
||||
import React, { ReactElement, useEffect } from "react";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { useRouter } from "next/router";
|
||||
import { useTheme } from "next-themes";
|
||||
import useSWR from "swr";
|
||||
// layouts
|
||||
// ui
|
||||
import { Loader } from "@plane/ui";
|
||||
import { PageHead } from "@/components/core";
|
||||
// components
|
||||
import { EmptyState } from "@/components/common";
|
||||
import { PageHead } from "@/components/core";
|
||||
import { ProjectIssueDetailsHeader } from "@/components/headers";
|
||||
import { IssueDetailRoot } from "@/components/issues";
|
||||
// ui
|
||||
// types
|
||||
// store hooks
|
||||
// hooks
|
||||
import { useApplication, useIssueDetail, useProject } from "@/hooks/store";
|
||||
// layouts
|
||||
import { AppLayout } from "@/layouts/app-layout";
|
||||
// types
|
||||
import { NextPageWithLayout } from "@/lib/types";
|
||||
// assets
|
||||
import emptyIssueDark from "public/empty-state/search/issue-dark.webp";
|
||||
import emptyIssueLight from "public/empty-state/search/issues-light.webp";
|
||||
|
||||
const IssueDetailsPage: NextPageWithLayout = observer(() => {
|
||||
// router
|
||||
const router = useRouter();
|
||||
const { workspaceSlug, projectId, issueId } = router.query;
|
||||
// hooks
|
||||
const { resolvedTheme } = useTheme();
|
||||
// store hooks
|
||||
const {
|
||||
fetchIssue,
|
||||
issue: { getIssueById },
|
||||
@@ -27,7 +34,11 @@ const IssueDetailsPage: NextPageWithLayout = observer(() => {
|
||||
const { getProjectById } = useProject();
|
||||
const { theme: themeStore } = useApplication();
|
||||
// fetching issue details
|
||||
const { isLoading, data: swrIssueDetails } = useSWR(
|
||||
const {
|
||||
isLoading,
|
||||
data: swrIssueDetails,
|
||||
error,
|
||||
} = useSWR(
|
||||
workspaceSlug && projectId && issueId ? `ISSUE_DETAIL_${workspaceSlug}_${projectId}_${issueId}` : null,
|
||||
workspaceSlug && projectId && issueId
|
||||
? () => fetchIssue(workspaceSlug.toString(), projectId.toString(), issueId.toString())
|
||||
@@ -57,7 +68,17 @@ const IssueDetailsPage: NextPageWithLayout = observer(() => {
|
||||
return (
|
||||
<>
|
||||
<PageHead title={pageTitle} />
|
||||
{issueLoader ? (
|
||||
{error ? (
|
||||
<EmptyState
|
||||
image={resolvedTheme === "dark" ? emptyIssueDark : emptyIssueLight}
|
||||
title="Issue does not exist"
|
||||
description="The issue you are looking for does not exist or has been deleted."
|
||||
primaryButton={{
|
||||
text: "View other issues",
|
||||
onClick: () => router.push(`/${workspaceSlug}/projects/${projectId}/issues`),
|
||||
}}
|
||||
/>
|
||||
) : issueLoader ? (
|
||||
<Loader className="flex h-full gap-5 p-5">
|
||||
<div className="basis-2/3 space-y-2">
|
||||
<Loader.Item height="30px" width="40%" />
|
||||
|
||||
Reference in New Issue
Block a user