diff --git a/qfieldcloud_sdk/cli.py b/qfieldcloud_sdk/cli.py index d546670..e5c5cd3 100755 --- a/qfieldcloud_sdk/cli.py +++ b/qfieldcloud_sdk/cli.py @@ -419,6 +419,18 @@ def list_files(ctx: Context, project_id): @click.option( "--is-public/--is-private", "is_public", help="Mark the project as public." ) +@click.option( + "--public-collaborator-role", + "public_collaborator_role", + type=click.Choice( + [ + sdk.ProjectCollaboratorRole.READER.value, + sdk.ProjectCollaboratorRole.REPORTER.value, + sdk.ProjectCollaboratorRole.EDITOR.value, + ] + ), + help="Role granted to every user while the project is public. Defaults to `reader`.", +) @click.option( "--project-type", "project_type", @@ -442,6 +454,7 @@ def create_project( owner: Optional[str], description: str, is_public: bool, + public_collaborator_role: Optional[str], project_type: Optional[str], clone_from_project: Optional[str], ): @@ -450,11 +463,15 @@ def create_project( if project_type is not None: project_type = sdk.ProjectType(project_type) + if public_collaborator_role is not None: + public_collaborator_role = sdk.ProjectCollaboratorRole(public_collaborator_role) + project = ctx.obj["client"].create_project( name, owner, description=description, is_public=is_public, + public_collaborator_role=public_collaborator_role, project_type=project_type, clone_from_project=clone_from_project, ) @@ -630,6 +647,18 @@ def download_files( is_flag=True, help="Whether the project shall be public", ) +@click.option( + "--public-collaborator-role", + "public_collaborator_role", + type=click.Choice( + [ + sdk.ProjectCollaboratorRole.READER.value, + sdk.ProjectCollaboratorRole.REPORTER.value, + sdk.ProjectCollaboratorRole.EDITOR.value, + ] + ), + help="New role granted to every user while the project is public", +) @click.option( "--project-type", "project_type", @@ -649,6 +678,7 @@ def patch_project( description: Optional[str] = None, owner: Optional[str] = None, is_public: Optional[bool] = None, + public_collaborator_role: Optional[str] = None, project_type: Optional[str] = None, ) -> None: """Patch the project with new data. Pass only the parameters that shall be changed.""" @@ -656,12 +686,16 @@ def patch_project( if project_type is not None: project_type = sdk.ProjectType(project_type) + if public_collaborator_role is not None: + public_collaborator_role = sdk.ProjectCollaboratorRole(public_collaborator_role) + project = ctx.obj["client"].patch_project( project_id, name=name, owner=owner, description=description, is_public=is_public, + public_collaborator_role=public_collaborator_role, project_type=project_type, ) diff --git a/qfieldcloud_sdk/sdk.py b/qfieldcloud_sdk/sdk.py index 26eab6e..d95520f 100644 --- a/qfieldcloud_sdk/sdk.py +++ b/qfieldcloud_sdk/sdk.py @@ -695,6 +695,7 @@ def create_project( owner: Optional[str] = None, description: str = "", is_public: bool = False, + public_collaborator_role: Optional[ProjectCollaboratorRole] = None, project_type: Optional[ProjectType] = None, clone_from_project: Optional[str] = None, ) -> Dict[str, Any]: @@ -705,6 +706,7 @@ def create_project( owner: The owner of the project. When None, the project will be owned by the currently logged-in user. Defaults to None. description: A description of the project. Defaults to an empty string. is_public: Whether the project should be public. Defaults to False. + public_collaborator_role: The role granted to every user while the project is public. Only `ProjectCollaboratorRole.READER`, `ProjectCollaboratorRole.REPORTER` and `ProjectCollaboratorRole.EDITOR` are accepted by the server. When omitted the server defaults to `ProjectCollaboratorRole.READER`. project_type: The type of the project. Only `ProjectType.REGULAR` and `ProjectType.TEMPLATE` are accepted by the server. When omitted the server defaults to `ProjectType.REGULAR`. clone_from_project: The ID of an existing project to clone into this new project. When None, the project is created empty. Defaults to None. @@ -731,6 +733,9 @@ def create_project( if clone_from_project is not None: data["clone_from_project"] = clone_from_project + if public_collaborator_role is not None: + data["public_collaborator_role"] = public_collaborator_role.value + resp = self._request( "POST", "projects", @@ -764,6 +769,7 @@ def patch_project( owner: Optional[str] = None, description: Optional[str] = None, is_public: Optional[bool] = None, + public_collaborator_role: Optional[ProjectCollaboratorRole] = None, project_type: Optional[ProjectType] = None, ) -> Dict[str, Any]: """Update a project. @@ -774,6 +780,7 @@ def patch_project( owner (str | None, optional): if passed, the new owner. Defaults to None. description (str, optional): if passed, the new description. Defaults to None. is_public (bool, optional): if passed, the new public setting. Defaults to None. + public_collaborator_role (ProjectCollaboratorRole | None, optional): if passed, the new role granted to every user while the project is public. Only `READER`, `REPORTER` and `EDITOR` are accepted by the server. project_type (ProjectType | None, optional): if passed, the new project type. Returns: @@ -801,6 +808,9 @@ def patch_project( if is_public: project_data["is_public"] = is_public + if public_collaborator_role is not None: + project_data["public_collaborator_role"] = public_collaborator_role.value + resp = self._request( "PATCH", f"projects/{project_id}", diff --git a/qfieldcloud_sdk/utils.py b/qfieldcloud_sdk/utils.py index f46c37c..a1c5453 100644 --- a/qfieldcloud_sdk/utils.py +++ b/qfieldcloud_sdk/utils.py @@ -102,18 +102,30 @@ def format_project_table(projects: List) -> str: data = [] for project in projects: + public_role = "" + if project["is_public"]: + public_role = project.get("public_collaborator_role", "") + data.append( [ project["id"], project["owner"] + "/" + project["name"], project["is_public"], + public_role, project["project_type"], project["description"], ] ) return format_table( - headers=["ID", "OWNER/NAME", "IS PUBLIC", "PROJECT TYPE", "DESCRIPTION"], + headers=[ + "ID", + "OWNER/NAME", + "IS PUBLIC", + "PUBLIC ROLE", + "PROJECT TYPE", + "DESCRIPTION", + ], data=data, )