Merge branch 'develop' of github.com:makeplane/plane into develop-deploy

This commit is contained in:
pablohashescobar 2023-11-20 15:26:34 +05:30
commit 4042da89e3
8 changed files with 77 additions and 25 deletions

View File

@ -39,10 +39,8 @@ class FileAssetEndpoint(BaseAPIView):
def delete(self, request, workspace_id, asset_key): def delete(self, request, workspace_id, asset_key):
asset_key = str(workspace_id) + "/" + asset_key asset_key = str(workspace_id) + "/" + asset_key
file_asset = FileAsset.objects.get(asset=asset_key) file_asset = FileAsset.objects.get(asset=asset_key)
# Delete the file from storage file_asset.is_deleted = True
file_asset.asset.delete(save=False) file_asset.save()
# Delete the file object
file_asset.delete()
return Response(status=status.HTTP_204_NO_CONTENT) return Response(status=status.HTTP_204_NO_CONTENT)

View File

@ -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()

View File

@ -24,6 +24,10 @@ app.conf.beat_schedule = {
"task": "plane.bgtasks.exporter_expired_task.delete_old_s3_link", "task": "plane.bgtasks.exporter_expired_task.delete_old_s3_link",
"schedule": crontab(hour=0, minute=0), "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. # Load task modules from all registered Django app configs.

View File

@ -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),
),
]

View File

@ -36,6 +36,7 @@ class FileAsset(BaseModel):
workspace = models.ForeignKey( workspace = models.ForeignKey(
"db.Workspace", on_delete=models.CASCADE, null=True, related_name="assets" "db.Workspace", on_delete=models.CASCADE, null=True, related_name="assets"
) )
is_deleted = models.BooleanField(default=False)
class Meta: class Meta:
verbose_name = "File Asset" verbose_name = "File Asset"

View File

@ -285,6 +285,7 @@ else:
CELERY_IMPORTS = ( CELERY_IMPORTS = (
"plane.bgtasks.issue_automation_task", "plane.bgtasks.issue_automation_task",
"plane.bgtasks.exporter_expired_task", "plane.bgtasks.exporter_expired_task",
"plane.bgtasks.file_asset_task",
) )
# Sentry Settings # Sentry Settings

View File

@ -28,7 +28,7 @@ const ProjectCyclesPage: NextPageWithLayout = observer(() => {
const [createModal, setCreateModal] = useState(false); const [createModal, setCreateModal] = useState(false);
// store // store
const { project: projectStore, cycle: cycleStore } = useMobxStore(); const { project: projectStore, cycle: cycleStore } = useMobxStore();
const { currentProjectDetails } = projectStore; const { projectCycles } = cycleStore
// router // router
const router = useRouter(); const router = useRouter();
const { workspaceSlug, projectId, peekCycle } = router.query; const { workspaceSlug, projectId, peekCycle } = router.query;
@ -73,6 +73,7 @@ const ProjectCyclesPage: NextPageWithLayout = observer(() => {
const cycleView = cycleStore?.cycleView; const cycleView = cycleStore?.cycleView;
const cycleLayout = cycleStore?.cycleLayout; const cycleLayout = cycleStore?.cycleLayout;
const totalCycles = projectCycles?.length ?? 0
if (!workspaceSlug || !projectId) return null; if (!workspaceSlug || !projectId) return null;
@ -84,7 +85,7 @@ const ProjectCyclesPage: NextPageWithLayout = observer(() => {
isOpen={createModal} isOpen={createModal}
handleClose={() => setCreateModal(false)} handleClose={() => setCreateModal(false)}
/> />
{currentProjectDetails?.total_cycles === 0 ? ( {totalCycles === 0 ? (
<div className="h-full grid place-items-center"> <div className="h-full grid place-items-center">
<EmptyState <EmptyState
title="Plan your project with cycles" title="Plan your project with cycles"

View File

@ -57,8 +57,8 @@ const CustomErrorComponent = () => {
</p> </p>
</div> </div>
<div className="flex items-center gap-2 justify-center"> <div className="flex items-center gap-2 justify-center">
<Button variant="primary" size="md" onClick={() => router.back()}> <Button variant="primary" size="md" onClick={() => router.reload()}>
Go back Refresh
</Button> </Button>
<Button variant="neutral-primary" size="md" onClick={handleSignOut}> <Button variant="neutral-primary" size="md" onClick={handleSignOut}>
Sign out Sign out