Skip to content

Commit

Permalink
✨ Trash folders (#6642)
Browse files Browse the repository at this point in the history
  • Loading branch information
pcrespov authored Nov 8, 2024
1 parent 72766b4 commit 299c1ac
Show file tree
Hide file tree
Showing 39 changed files with 1,421 additions and 364 deletions.
8 changes: 5 additions & 3 deletions api/specs/web-server/_folders.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from models_library.workspaces import WorkspaceID
from pydantic import Json
from simcore_service_webserver._meta import API_VTAG
from simcore_service_webserver.folders._folders_handlers import FoldersPathParams
from simcore_service_webserver.folders._models import FolderFilters, FoldersPathParams

router = APIRouter(
prefix=f"/{API_VTAG}",
Expand All @@ -30,8 +30,6 @@
],
)

### Folders


@router.post(
"/folders",
Expand All @@ -57,6 +55,10 @@ async def list_folders(
example='{"field": "name", "direction": "desc"}',
),
] = '{"field": "modified_at", "direction": "desc"}',
filters: Annotated[
Json | None,
Query(description=FolderFilters.schema_json(indent=1)),
] = None,
):
...

Expand Down
6 changes: 5 additions & 1 deletion api/specs/web-server/_projects_crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
from simcore_service_webserver.projects._common_models import ProjectPathParams
from simcore_service_webserver.projects._crud_handlers import ProjectCreateParams
from simcore_service_webserver.projects._crud_handlers_models import (
ProjectFilters,
ProjectListFullSearchParams,
ProjectListParams,
)
Expand Down Expand Up @@ -83,7 +84,10 @@ async def list_projects(
example='{"field": "last_change_date", "direction": "desc"}',
),
] = '{"field": "last_change_date", "direction": "desc"}',
filters: Annotated[Json | None, Query()] = None,
filters: Annotated[
Json | None,
Query(description=ProjectFilters.schema_json(indent=1)),
] = None,
):
...

Expand Down
41 changes: 39 additions & 2 deletions api/specs/web-server/_trash.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,14 @@

from fastapi import APIRouter, Depends, status
from simcore_service_webserver._meta import API_VTAG
from simcore_service_webserver.projects._trash_handlers import (
ProjectPathParams,
from simcore_service_webserver.folders._models import (
FoldersPathParams,
RemoveQueryParams,
)
from simcore_service_webserver.projects._trash_handlers import ProjectPathParams
from simcore_service_webserver.projects._trash_handlers import (
RemoveQueryParams as RemoveQueryParams_duplicated,
)

router = APIRouter(
prefix=f"/{API_VTAG}",
Expand Down Expand Up @@ -59,3 +63,36 @@ def untrash_project(
_p: Annotated[ProjectPathParams, Depends()],
):
...


_extra_tags = ["folders"]


@router.post(
"/folders/{folder_id}:trash",
tags=_extra_tags,
status_code=status.HTTP_204_NO_CONTENT,
responses={
status.HTTP_404_NOT_FOUND: {"description": "Not such a folder"},
status.HTTP_409_CONFLICT: {
"description": "One or more projects is in use and cannot be trashed"
},
status.HTTP_503_SERVICE_UNAVAILABLE: {"description": "Trash service error"},
},
)
def trash_folder(
_p: Annotated[FoldersPathParams, Depends()],
_q: Annotated[RemoveQueryParams_duplicated, Depends()],
):
...


@router.post(
"/folders/{folder_id}:untrash",
tags=_extra_tags,
status_code=status.HTTP_204_NO_CONTENT,
)
def untrash_folder(
_p: Annotated[FoldersPathParams, Depends()],
):
...
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class FolderGet(OutputSchema):
description: str
created_at: datetime
modified_at: datetime
trashed_at: datetime | None
owner: GroupID
my_access_rights: AccessRights
access_rights: dict[GroupID, AccessRights]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class FolderGet(OutputSchema):
name: str
created_at: datetime
modified_at: datetime
trashed_at: datetime | None
owner: GroupID
workspace_id: WorkspaceID | None
my_access_rights: AccessRights
Expand Down
4 changes: 4 additions & 0 deletions packages/models-library/src/models_library/folders.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ class FolderDB(BaseModel):
...,
description="Timestamp of last modification",
)
trashed_at: datetime | None = Field(
...,
)

user_id: UserID | None
workspace_id: WorkspaceID | None

Expand Down
1 change: 1 addition & 0 deletions packages/models-library/src/models_library/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ class Project(BaseProjectModel):
default=None,
alias="trashedAt",
)
trashed_explicitly: bool = Field(default=False, alias="trashedExplicitly")

class Config:
description = "Document that stores metadata, pipeline and UI setup of a study"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
"""project and folder trash columns
Revision ID: 5ad02358751a
Revises: fce5d231e16d
Create Date: 2024-11-07 17:14:01.094583+00:00
"""
import sqlalchemy as sa
from alembic import op
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision = "5ad02358751a"
down_revision = "fce5d231e16d"
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column(
"folders_v2",
sa.Column(
"trashed_at",
sa.DateTime(timezone=True),
nullable=True,
comment="The date and time when the folder was marked as trashed.Null if the folder has not been trashed [default].",
),
)
op.add_column(
"folders_v2",
sa.Column(
"trashed_explicitly",
sa.Boolean(),
server_default=sa.text("false"),
nullable=False,
comment="Indicates whether the folder was explicitly trashed by the user (true) or inherited its trashed status from a parent (false) [default].",
),
)
op.add_column(
"projects",
sa.Column(
"trashed_explicitly",
sa.Boolean(),
server_default=sa.text("false"),
nullable=False,
comment="Indicates whether the project was explicitly trashed by the user (true) or inherited its trashed status from a parent (false) [default].",
),
)
op.alter_column(
"projects",
"trashed_at",
existing_type=postgresql.TIMESTAMP(timezone=True),
comment="The date and time when the project was marked as trashed. Null if the project has not been trashed [default].",
existing_nullable=True,
)
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column(
"projects",
"trashed_at",
existing_type=postgresql.TIMESTAMP(timezone=True),
comment=None,
existing_comment="The date and time when the project was marked as trashed. Null if the project has not been trashed [default].",
existing_nullable=True,
)
op.drop_column("projects", "trashed_explicitly")
op.drop_column("folders_v2", "trashed_explicitly")
op.drop_column("folders_v2", "trashed_at")
# ### end Alembic commands ###
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import sqlalchemy as sa
from sqlalchemy.sql import expression

from ._common import column_created_datetime, column_modified_datetime
from .base import metadata
Expand Down Expand Up @@ -74,4 +75,19 @@
),
column_created_datetime(timezone=True),
column_modified_datetime(timezone=True),
sa.Column(
"trashed_at",
sa.DateTime(timezone=True),
nullable=True,
comment="The date and time when the folder was marked as trashed."
"Null if the folder has not been trashed [default].",
),
sa.Column(
"trashed_explicitly",
sa.Boolean,
nullable=False,
server_default=expression.false(),
comment="Indicates whether the folder was explicitly trashed by the user (true)"
" or inherited its trashed status from a parent (false) [default].",
),
)
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import sqlalchemy as sa
from sqlalchemy.dialects.postgresql import ARRAY, JSONB
from sqlalchemy.sql import func
from sqlalchemy.sql import expression, func

from .base import metadata

Expand Down Expand Up @@ -145,7 +145,16 @@ class ProjectType(enum.Enum):
"trashed_at",
sa.DateTime(timezone=True),
nullable=True,
doc="Timestamp indicating when the project was marked as trashed, or null otherwise.",
comment="The date and time when the project was marked as trashed. "
"Null if the project has not been trashed [default].",
),
sa.Column(
"trashed_explicitly",
sa.Boolean,
nullable=False,
server_default=expression.false(),
comment="Indicates whether the project was explicitly trashed by the user (true)"
" or inherited its trashed status from a parent (false) [default].",
),
sa.Column(
"workspace_id",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,5 +186,5 @@ async def assert_get_same_project(
data, error = await assert_status(resp, expected)

if not error:
assert data == project
assert data == {k: project[k] for k in data}
return data
2 changes: 1 addition & 1 deletion services/web/server/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.44.0
0.45.0
2 changes: 1 addition & 1 deletion services/web/server/setup.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.44.0
current_version = 0.45.0
commit = True
message = services/webserver api version: {current_version} → {new_version}
tag = False
Expand Down
Loading

0 comments on commit 299c1ac

Please sign in to comment.