From e945aa9b71f029837599bf1ae96d9e5c659ffa26 Mon Sep 17 00:00:00 2001
From: "onFire(Abhi)" <40654066+AbhiShake1@users.noreply.github.com>
Date: Mon, 20 Nov 2023 09:06:46 +0000
Subject: [PATCH 1/3] fix: newly added cycle doesnt appear unlelss the page is
manually reloaded (#2673)
* fix: newly added cycle doesnt appear unlelss the page is manually reloaded
* Delete \
* Delete web/layouts/profile-layout/profile-sidebar.tsx
* Update cycles.store.ts
* fix: remove duplicate type declaration
---------
Co-authored-by: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com>
---
.../[workspaceSlug]/projects/[projectId]/cycles/index.tsx | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/cycles/index.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/cycles/index.tsx
index c1314b414..9df2357b8 100644
--- a/web/pages/[workspaceSlug]/projects/[projectId]/cycles/index.tsx
+++ b/web/pages/[workspaceSlug]/projects/[projectId]/cycles/index.tsx
@@ -28,7 +28,7 @@ const ProjectCyclesPage: NextPageWithLayout = observer(() => {
const [createModal, setCreateModal] = useState(false);
// store
const { project: projectStore, cycle: cycleStore } = useMobxStore();
- const { currentProjectDetails } = projectStore;
+ const { projectCycles } = cycleStore
// router
const router = useRouter();
const { workspaceSlug, projectId, peekCycle } = router.query;
@@ -73,6 +73,7 @@ const ProjectCyclesPage: NextPageWithLayout = observer(() => {
const cycleView = cycleStore?.cycleView;
const cycleLayout = cycleStore?.cycleLayout;
+ const totalCycles = projectCycles?.length ?? 0
if (!workspaceSlug || !projectId) return null;
@@ -84,7 +85,7 @@ const ProjectCyclesPage: NextPageWithLayout = observer(() => {
isOpen={createModal}
handleClose={() => setCreateModal(false)}
/>
- {currentProjectDetails?.total_cycles === 0 ? (
+ {totalCycles === 0 ? (
Date: Mon, 20 Nov 2023 14:53:06 +0530
Subject: [PATCH 2/3] fix: file asset delete (#2804)
---
apiserver/plane/app/views/asset.py | 40 +++++++++----------
apiserver/plane/bgtasks/file_asset_task.py | 29 ++++++++++++++
apiserver/plane/celery.py | 4 ++
.../migrations/0051_fileasset_is_deleted.py | 18 +++++++++
apiserver/plane/db/models/asset.py | 1 +
apiserver/plane/settings/common.py | 1 +
6 files changed, 72 insertions(+), 21 deletions(-)
create mode 100644 apiserver/plane/bgtasks/file_asset_task.py
create mode 100644 apiserver/plane/db/migrations/0051_fileasset_is_deleted.py
diff --git a/apiserver/plane/app/views/asset.py b/apiserver/plane/app/views/asset.py
index eddbb4505..31e002e15 100644
--- a/apiserver/plane/app/views/asset.py
+++ b/apiserver/plane/app/views/asset.py
@@ -39,10 +39,8 @@ class FileAssetEndpoint(BaseAPIView):
def delete(self, request, workspace_id, asset_key):
asset_key = str(workspace_id) + "/" + asset_key
file_asset = FileAsset.objects.get(asset=asset_key)
- # Delete the file from storage
- file_asset.asset.delete(save=False)
- # Delete the file object
- file_asset.delete()
+ file_asset.is_deleted = True
+ file_asset.save()
return Response(status=status.HTTP_204_NO_CONTENT)
@@ -50,25 +48,25 @@ class UserAssetsEndpoint(BaseAPIView):
parser_classes = (MultiPartParser, FormParser)
def get(self, request, asset_key):
- files = FileAsset.objects.filter(asset=asset_key, created_by=request.user)
- if files.exists():
- serializer = FileAssetSerializer(files, context={"request": request})
- return Response({"data": serializer.data, "status": True}, status=status.HTTP_200_OK)
- else:
- return Response({"error": "Asset key does not exist", "status": False}, status=status.HTTP_200_OK)
+ files = FileAsset.objects.filter(asset=asset_key, created_by=request.user)
+ if files.exists():
+ serializer = FileAssetSerializer(files, context={"request": request})
+ return Response({"data": serializer.data, "status": True}, status=status.HTTP_200_OK)
+ else:
+ return Response({"error": "Asset key does not exist", "status": False}, status=status.HTTP_200_OK)
def post(self, request):
- serializer = FileAssetSerializer(data=request.data)
- if serializer.is_valid():
- serializer.save()
- return Response(serializer.data, status=status.HTTP_201_CREATED)
- return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
+ serializer = FileAssetSerializer(data=request.data)
+ if serializer.is_valid():
+ serializer.save()
+ return Response(serializer.data, status=status.HTTP_201_CREATED)
+ return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, asset_key):
- file_asset = FileAsset.objects.get(asset=asset_key, created_by=request.user)
- # Delete the file from storage
- file_asset.asset.delete(save=False)
- # Delete the file object
- file_asset.delete()
- return Response(status=status.HTTP_204_NO_CONTENT)
+ file_asset = FileAsset.objects.get(asset=asset_key, created_by=request.user)
+ # Delete the file from storage
+ file_asset.asset.delete(save=False)
+ # Delete the file object
+ file_asset.delete()
+ return Response(status=status.HTTP_204_NO_CONTENT)
diff --git a/apiserver/plane/bgtasks/file_asset_task.py b/apiserver/plane/bgtasks/file_asset_task.py
new file mode 100644
index 000000000..339d24583
--- /dev/null
+++ b/apiserver/plane/bgtasks/file_asset_task.py
@@ -0,0 +1,29 @@
+# Python imports
+from datetime import timedelta
+
+# Django imports
+from django.utils import timezone
+from django.db.models import Q
+
+# Third party imports
+from celery import shared_task
+
+# Module imports
+from plane.db.models import FileAsset
+
+
+@shared_task
+def delete_file_asset():
+
+ # file assets to delete
+ file_assets_to_delete = FileAsset.objects.filter(
+ Q(is_deleted=True) & Q(updated_at__lte=timezone.now() - timedelta(days=7))
+ )
+
+ # Delete the file from storage and the file object from the database
+ for file_asset in file_assets_to_delete:
+ # Delete the file from storage
+ file_asset.asset.delete(save=False)
+ # Delete the file object
+ file_asset.delete()
+
diff --git a/apiserver/plane/celery.py b/apiserver/plane/celery.py
index dfb094339..4d4e3475b 100644
--- a/apiserver/plane/celery.py
+++ b/apiserver/plane/celery.py
@@ -24,6 +24,10 @@ app.conf.beat_schedule = {
"task": "plane.bgtasks.exporter_expired_task.delete_old_s3_link",
"schedule": crontab(hour=0, minute=0),
},
+ "check-every-day-to-delete-file-asset": {
+ "task": "plane.bgtasks.file_asset_task.delete_file_asset",
+ "schedule": crontab(hour=0, minute=0),
+ },
}
# Load task modules from all registered Django app configs.
diff --git a/apiserver/plane/db/migrations/0051_fileasset_is_deleted.py b/apiserver/plane/db/migrations/0051_fileasset_is_deleted.py
new file mode 100644
index 000000000..914852bfd
--- /dev/null
+++ b/apiserver/plane/db/migrations/0051_fileasset_is_deleted.py
@@ -0,0 +1,18 @@
+# Generated by Django 4.2.7 on 2023-11-20 08:26
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('db', '0050_user_use_case_alter_workspace_organization_size'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='fileasset',
+ name='is_deleted',
+ field=models.BooleanField(default=False),
+ ),
+ ]
diff --git a/apiserver/plane/db/models/asset.py b/apiserver/plane/db/models/asset.py
index 01ef1d9d8..ab3c38d9c 100644
--- a/apiserver/plane/db/models/asset.py
+++ b/apiserver/plane/db/models/asset.py
@@ -36,6 +36,7 @@ class FileAsset(BaseModel):
workspace = models.ForeignKey(
"db.Workspace", on_delete=models.CASCADE, null=True, related_name="assets"
)
+ is_deleted = models.BooleanField(default=False)
class Meta:
verbose_name = "File Asset"
diff --git a/apiserver/plane/settings/common.py b/apiserver/plane/settings/common.py
index 2cf94a68c..8b81102fe 100644
--- a/apiserver/plane/settings/common.py
+++ b/apiserver/plane/settings/common.py
@@ -285,6 +285,7 @@ else:
CELERY_IMPORTS = (
"plane.bgtasks.issue_automation_task",
"plane.bgtasks.exporter_expired_task",
+ "plane.bgtasks.file_asset_task",
)
# Sentry Settings
From 668dfd2e380d8d2cfeec57c9a7fedee906e6d6c1 Mon Sep 17 00:00:00 2001
From: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com>
Date: Mon, 20 Nov 2023 15:00:36 +0530
Subject: [PATCH 3/3] chore: update exception detected screen action button
(#2805)
---
web/pages/_error.tsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/web/pages/_error.tsx b/web/pages/_error.tsx
index e131c4e01..c24f6514b 100644
--- a/web/pages/_error.tsx
+++ b/web/pages/_error.tsx
@@ -57,8 +57,8 @@ const CustomErrorComponent = () => {
-