Skip to content

Commit d1603bb

Browse files
authored
Merge branch 'master' into bugs/02-12
2 parents 35bca8a + f9f2148 commit d1603bb

File tree

37 files changed

+1039
-258
lines changed

37 files changed

+1039
-258
lines changed

api/specs/web-server/_folders.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
FoldersListQueryParams,
2626
FoldersPathParams,
2727
)
28+
from simcore_service_webserver.folders._workspaces_handlers import (
29+
_FolderWorkspacesPathParams,
30+
)
2831

2932
router = APIRouter(
3033
prefix=f"/{API_VTAG}",
@@ -97,3 +100,15 @@ async def delete_folder(
97100
_path: Annotated[FoldersPathParams, Depends()],
98101
):
99102
...
103+
104+
105+
@router.post(
106+
"/folders/{folder_id}/workspaces/{workspace_id}:move",
107+
status_code=status.HTTP_204_NO_CONTENT,
108+
summary="Move folder to the workspace",
109+
tags=["workspaces"],
110+
)
111+
async def move_folder_to_workspace(
112+
_path: Annotated[_FolderWorkspacesPathParams, Depends()],
113+
):
114+
...

api/specs/web-server/_projects_workspaces.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@
2323
)
2424

2525

26-
@router.put(
27-
"/projects/{project_id}/workspaces/{workspace_id}",
26+
@router.post(
27+
"/projects/{project_id}/workspaces/{workspace_id}:move",
2828
status_code=status.HTTP_204_NO_CONTENT,
2929
summary="Move project to the workspace",
3030
)
31-
async def replace_project_workspace(
31+
async def move_project_to_workspace(
3232
_path: Annotated[_ProjectWorkspacesPathParams, Depends()],
3333
):
3434
...

packages/models-library/src/models_library/api_schemas_webserver/projects.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,16 @@
99
from typing import Annotated, Any, Literal, TypeAlias
1010

1111
from models_library.folders import FolderID
12+
from models_library.utils._original_fastapi_encoders import jsonable_encoder
1213
from models_library.workspaces import WorkspaceID
13-
from pydantic import BeforeValidator, ConfigDict, Field, HttpUrl, field_validator
14+
from pydantic import (
15+
BeforeValidator,
16+
ConfigDict,
17+
Field,
18+
HttpUrl,
19+
PlainSerializer,
20+
field_validator,
21+
)
1422

1523
from ..api_schemas_long_running_tasks.tasks import TaskGet
1624
from ..basic_types import LongTruncatedStr, ShortTruncatedStr
@@ -130,12 +138,22 @@ class ProjectPatch(InputSchema):
130138
name: ShortTruncatedStr | None = Field(default=None)
131139
description: LongTruncatedStr | None = Field(default=None)
132140
thumbnail: Annotated[
133-
HttpUrl | None, BeforeValidator(empty_str_to_none_pre_validator)
141+
HttpUrl | None,
142+
BeforeValidator(empty_str_to_none_pre_validator),
143+
PlainSerializer(lambda x: str(x) if x is not None else None),
134144
] = Field(default=None)
135145
access_rights: dict[GroupIDStr, AccessRights] | None = Field(default=None)
136146
classifiers: list[ClassifierID] | None = Field(default=None)
137147
dev: dict | None = Field(default=None)
138-
ui: StudyUI | None = Field(default=None)
148+
ui: Annotated[
149+
StudyUI | None,
150+
BeforeValidator(empty_str_to_none_pre_validator),
151+
PlainSerializer(
152+
lambda obj: jsonable_encoder(
153+
obj, exclude_unset=True, by_alias=False
154+
) # For the sake of backward compatibility
155+
),
156+
] = Field(default=None)
139157
quality: dict[str, Any] | None = Field(default=None)
140158

141159

packages/pytest-simcore/src/pytest_simcore/helpers/webserver_projects.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ async def create_project(
9595
for group_id, permissions in _access_rights.items():
9696
await update_or_insert_project_group(
9797
app,
98-
new_project["uuid"],
98+
project_id=new_project["uuid"],
9999
group_id=int(group_id),
100100
read=permissions["read"],
101101
write=permissions["write"],

services/director-v2/src/simcore_service_director_v2/modules/db/repositories/comp_tasks/_utils.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import aiopg.sa
77
import arrow
88
from dask_task_models_library.container_tasks.protocol import ContainerEnvsDict
9+
from models_library.api_schemas_catalog.services import ServiceGet
910
from models_library.api_schemas_clusters_keeper.ec2_instances import EC2InstanceTypeGet
1011
from models_library.api_schemas_directorv2.services import (
1112
NodeRequirements,
@@ -89,7 +90,7 @@ async def _get_service_details(
8990
node.version,
9091
product_name,
9192
)
92-
obj: ServiceMetaDataPublished = ServiceMetaDataPublished(**service_details)
93+
obj: ServiceMetaDataPublished = ServiceGet(**service_details)
9394
return obj
9495

9596

services/director-v2/tests/unit/with_dbs/comp_scheduler/test_api_route_computations.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -186,15 +186,29 @@ def _mocked_service_resources(request) -> httpx.Response:
186186
def _mocked_services_details(
187187
request, service_key: str, service_version: str
188188
) -> httpx.Response:
189+
assert "json_schema_extra" in ServiceGet.model_config
190+
assert isinstance(ServiceGet.model_config["json_schema_extra"], dict)
191+
assert isinstance(
192+
ServiceGet.model_config["json_schema_extra"]["examples"], list
193+
)
194+
assert isinstance(
195+
ServiceGet.model_config["json_schema_extra"]["examples"][0], dict
196+
)
197+
data_published = fake_service_details.model_copy(
198+
update={
199+
"key": urllib.parse.unquote(service_key),
200+
"version": service_version,
201+
}
202+
).model_dump(by_alias=True)
203+
data = {
204+
**ServiceGet.model_config["json_schema_extra"]["examples"][0],
205+
**data_published,
206+
}
207+
payload = ServiceGet.model_validate(data)
189208
return httpx.Response(
190209
200,
191210
json=jsonable_encoder(
192-
fake_service_details.model_copy(
193-
update={
194-
"key": urllib.parse.unquote(service_key),
195-
"version": service_version,
196-
}
197-
),
211+
payload,
198212
by_alias=True,
199213
),
200214
)

services/static-webserver/client/source/class/osparc/CookiePolicy.js

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -154,17 +154,15 @@ qx.Class.define("osparc.CookiePolicy", {
154154
control = new qx.ui.basic.Label(text).set({
155155
rich : true
156156
});
157-
osparc.store.Support.getLicenseURL()
158-
.then(licenseLink => {
159-
const lbl = control.getValue();
160-
if (licenseLink) {
161-
const color = qx.theme.manager.Color.getInstance().resolve("text");
162-
const textLink = `<a href=${licenseLink} style='color: ${color}' target='_blank'>Licensing.</a>`;
163-
control.setValue(lbl + textLink);
164-
} else {
165-
control.setValue(lbl + this.tr("Licensing."));
166-
}
167-
});
157+
const licenseLink = osparc.store.Support.getLicenseURL();
158+
const lbl = control.getValue();
159+
if (licenseLink) {
160+
const color = qx.theme.manager.Color.getInstance().resolve("text");
161+
const textLink = `<a href=${licenseLink} style='color: ${color}' target='_blank'>Licensing.</a>`;
162+
control.setValue(lbl + textLink);
163+
} else {
164+
control.setValue(lbl + this.tr("Licensing."));
165+
}
168166
this._add(control, {
169167
column: 0,
170168
row: 2

services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -576,11 +576,6 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
576576
const data = e.getData();
577577
const destWorkspaceId = data["workspaceId"];
578578
const destFolderId = data["folderId"];
579-
if (destWorkspaceId !== currentWorkspaceId) {
580-
const msg = this.tr("Moving folders to Shared Workspaces are coming soon");
581-
osparc.FlashMessenger.getInstance().logAs(msg, "WARNING");
582-
return;
583-
}
584579
const moveFolder = () => {
585580
Promise.all([
586581
this.__moveFolderToWorkspace(folderId, destWorkspaceId),

services/static-webserver/client/source/class/osparc/data/Resources.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,8 @@ qx.Class.define("osparc.data.Resources", {
288288
url: statics.API + "/projects/{studyId}/folders/{folderId}"
289289
},
290290
moveToWorkspace: {
291-
method: "PUT",
292-
url: statics.API + "/projects/{studyId}/workspaces/{workspaceId}"
291+
method: "POST",
292+
url: statics.API + "/projects/{studyId}/workspaces/{workspaceId}:move"
293293
},
294294
}
295295
},
@@ -342,8 +342,8 @@ qx.Class.define("osparc.data.Resources", {
342342
url: statics.API + "/folders/{folderId}"
343343
},
344344
moveToWorkspace: {
345-
method: "PUT",
346-
url: statics.API + "/folders/{folderId}/folders/{workspaceId}"
345+
method: "POST",
346+
url: statics.API + "/folders/{folderId}/folders/{workspaceId}:move"
347347
},
348348
trash: {
349349
method: "POST",

services/static-webserver/client/source/class/osparc/navigation/UserMenu.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ qx.Class.define("osparc.navigation.UserMenu", {
127127
case "license":
128128
control = new qx.ui.menu.Button(this.tr("License"));
129129
osparc.utils.Utils.setIdToWidget(control, "userMenuLicenseBtn");
130-
osparc.store.Support.getLicenseURL()
131-
.then(licenseURL => control.addListener("execute", () => window.open(licenseURL)));
130+
const licenseURL = osparc.store.Support.getLicenseURL();
131+
control.addListener("execute", () => window.open(licenseURL));
132132
this.add(control);
133133
break;
134134
case "tip-lite-button":
@@ -257,7 +257,7 @@ qx.Class.define("osparc.navigation.UserMenu", {
257257
}
258258

259259
this.getChildControl("about");
260-
if (!osparc.product.Utils.isProduct("osparc")) {
260+
if (osparc.product.Utils.showAboutProduct()) {
261261
this.getChildControl("about-product");
262262
}
263263
this.getChildControl("license");

0 commit comments

Comments
 (0)