Skip to content

Commit 9314fc9

Browse files
authored
Merge branch 'master' into mai/remove-rpc-logs
2 parents e527840 + f772080 commit 9314fc9

File tree

15 files changed

+258
-21
lines changed

15 files changed

+258
-21
lines changed

api/specs/web-server/_functions.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
FunctionGroupPathParams,
2424
)
2525
from simcore_service_webserver.functions._controller._functions_rest_schemas import (
26+
FunctionDeleteQueryParams,
2627
FunctionGetQueryParams,
2728
FunctionPathParams,
2829
FunctionsListQueryParams,
@@ -80,6 +81,7 @@ async def update_function(
8081
)
8182
async def delete_function(
8283
_path: Annotated[FunctionPathParams, Depends()],
84+
_query: Annotated[as_query(FunctionDeleteQueryParams), Depends()],
8385
): ...
8486

8587

packages/models-library/src/models_library/functions_errors.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ class FunctionIDNotFoundError(FunctionBaseError):
1717
status_code: int = 404 # Not Found
1818

1919

20+
class FunctionHasJobsCannotDeleteError(FunctionBaseError):
21+
msg_template: str = (
22+
"Cannot delete function {function_id} because it has {jobs_count} associated job(s)."
23+
)
24+
status_code: int = 409 # Conflict
25+
26+
2027
class FunctionJobIDNotFoundError(FunctionBaseError):
2128
msg_template: str = "Function job {function_job_id} not found"
2229
status_code: int = 404 # Not Found

services/docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1466,7 +1466,7 @@ services:
14661466
retries: 50
14671467

14681468
traefik:
1469-
image: "traefik:v3.4.0@sha256:4cf907247939b5d20bf4eff73abd21cb413c339600dde76dbc94a874b2578a27"
1469+
image: "traefik:v3.5.2@sha256:07ff0c6c2114233b82e1de8e9f4fee9974470cd8d42c22e4e158538d950e19ae"
14701470
init: true
14711471
hostname: "{{.Node.Hostname}}-{{.Task.Slot}}"
14721472
command:

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

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1640,8 +1640,6 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
16401640
return deleteButton;
16411641
},
16421642

1643-
1644-
16451643
__createSelectButton: function() {
16461644
const selectButton = new qx.ui.form.ToggleButton().set({
16471645
appearance: "form-button-outlined",
@@ -1794,12 +1792,12 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
17941792
this._reloadCards();
17951793
},
17961794

1797-
__removeFromStudyList: function(studyId) {
1798-
const idx = this._resourcesList.findIndex(study => study["uuid"] === studyId);
1795+
__removeFromList: function(resourceUuid) {
1796+
const idx = this._resourcesList.findIndex(resource => resource["uuid"] === resourceUuid);
17991797
if (idx > -1) {
18001798
this._resourcesList.splice(idx, 1);
18011799
}
1802-
this._resourcesContainer.removeCard(studyId);
1800+
this._resourcesContainer.removeCard(resourceUuid);
18031801
},
18041802

18051803
_populateCardMenu: function(card) {
@@ -1812,7 +1810,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
18121810
this._populateTemplateCardMenu(card);
18131811
break;
18141812
case "function":
1815-
card.getChildControl("menu-selection-stack").exclude();
1813+
this.__populateFunctionCardMenu(card);
18161814
break;
18171815
}
18181816
},
@@ -1919,6 +1917,14 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
19191917
card.evaluateMenuButtons();
19201918
},
19211919

1920+
__populateFunctionCardMenu: function(card) {
1921+
const menu = card.getMenu();
1922+
const functionData = card.getResourceData();
1923+
1924+
const deleteButton = this.__getDeleteFunctionMenuButton(functionData);
1925+
menu.add(deleteButton);
1926+
},
1927+
19221928
__getOpenLocationMenuButton: function(studyData) {
19231929
const openLocationButton = new qx.ui.menu.Button(this.tr("Open location"), "@FontAwesome5Solid/external-link-alt/12");
19241930
openLocationButton.addListener("execute", () => {
@@ -1994,7 +2000,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
19942000
__doMoveStudy: function(studyData, destWorkspaceId, destFolderId) {
19952001
this.__moveStudyToWorkspace(studyData, destWorkspaceId) // first move to workspace
19962002
.then(() => this.__moveStudyToFolder(studyData, destFolderId)) // then move to folder
1997-
.then(() => this.__removeFromStudyList(studyData["uuid"]))
2003+
.then(() => this.__removeFromList(studyData["uuid"]))
19982004
.catch(err => osparc.FlashMessenger.logError(err));
19992005
},
20002006

@@ -2192,6 +2198,54 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
21922198
return deleteButton;
21932199
},
21942200

2201+
__getDeleteFunctionMenuButton: function(functionData) {
2202+
const deleteButton = new qx.ui.menu.Button(this.tr("Delete"), "@FontAwesome5Solid/trash/12");
2203+
deleteButton.set({
2204+
appearance: "menu-button"
2205+
});
2206+
osparc.utils.Utils.setIdToWidget(deleteButton, "functionItemMenuDelete");
2207+
deleteButton.addListener("execute", () => {
2208+
this.__popUpDeleteFunctionWindow(functionData, false);
2209+
}, this);
2210+
return deleteButton;
2211+
},
2212+
2213+
__popUpDeleteFunctionWindow: function(functionData, force, message) {
2214+
const win = this.__createConfirmDeleteWindow([functionData.title]);
2215+
win.setCaption(this.tr("Delete function"));
2216+
if (force) {
2217+
if (message) {
2218+
win.setMessage(message);
2219+
} else {
2220+
const msg = this.tr("The function has associated jobs. Are you sure you want to delete it?");
2221+
win.setMessage(msg);
2222+
}
2223+
}
2224+
win.center();
2225+
win.open();
2226+
win.addListener("close", () => {
2227+
if (win.getConfirmed()) {
2228+
this.__doDeleteFunction(functionData, force);
2229+
}
2230+
}, this);
2231+
},
2232+
2233+
__doDeleteFunction: function(functionData, force = false) {
2234+
osparc.store.Functions.deleteFunction(functionData.uuid, force)
2235+
.then(() => {
2236+
this.__removeFromList(functionData.uuid);
2237+
const msg = this.tr("Successfully deleted");
2238+
osparc.FlashMessenger.logAs(msg, "INFO");
2239+
})
2240+
.catch(err => {
2241+
if (err && err.status && err.status === 409) {
2242+
this.__popUpDeleteFunctionWindow(functionData, true, err.message);
2243+
} else {
2244+
osparc.FlashMessenger.logError(err);
2245+
}
2246+
});
2247+
},
2248+
21952249
__getStudyData: function(id) {
21962250
return this._resourcesList.find(study => study.uuid === id);
21972251
},
@@ -2303,7 +2357,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
23032357
__untrashStudy: function(studyData) {
23042358
osparc.store.Study.getInstance().untrashStudy(studyData.uuid)
23052359
.then(() => {
2306-
this.__removeFromStudyList(studyData.uuid);
2360+
this.__removeFromList(studyData.uuid);
23072361
const msg = this.tr("Successfully restored");
23082362
osparc.FlashMessenger.logAs(msg, "INFO");
23092363
this._resourceFilter.evaluateTrashEmpty();
@@ -2315,7 +2369,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
23152369
__trashStudy: function(studyData) {
23162370
osparc.store.Study.getInstance().trashStudy(studyData.uuid)
23172371
.then(() => {
2318-
this.__removeFromStudyList(studyData.uuid);
2372+
this.__removeFromList(studyData.uuid);
23192373
const msg = this.tr("Successfully deleted");
23202374
osparc.FlashMessenger.logAs(msg, "INFO");
23212375
this._resourceFilter.setTrashEmpty(false);
@@ -2353,7 +2407,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
23532407
operationPromise = osparc.store.Study.getInstance().deleteStudy(studyData.uuid);
23542408
}
23552409
operationPromise
2356-
.then(() => this.__removeFromStudyList(studyData.uuid))
2410+
.then(() => this.__removeFromList(studyData.uuid))
23572411
.catch(err => osparc.FlashMessenger.logError(err))
23582412
.finally(() => this.resetSelection());
23592413
},

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,10 @@ qx.Class.define("osparc.data.Resources", {
644644
method: "POST",
645645
url: statics.API + "/functions"
646646
},
647+
delete: {
648+
method: "DELETE",
649+
url: statics.API + "/functions/{functionId}?force={force}"
650+
},
647651
patch: {
648652
method: "PATCH",
649653
url: statics.API + "/functions/{functionId}?include_extras=true"

services/static-webserver/client/source/class/osparc/store/Functions.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,20 @@ qx.Class.define("osparc.store.Functions", {
165165
});
166166
},
167167

168+
deleteFunction: function(functionId, force = false) {
169+
const params = {
170+
url: {
171+
functionId,
172+
force,
173+
}
174+
};
175+
return osparc.data.Resources.fetch("functions", "delete", params)
176+
.catch(error => {
177+
console.error("Error deleting function:", error);
178+
throw error; // Rethrow the error to propagate it to the caller
179+
});
180+
},
181+
168182
__putCollaborator: function(functionData, gid, newPermissions) {
169183
const params = {
170184
url: {

services/web/server/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.77.2
1+
0.78.0

services/web/server/setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 0.77.2
2+
current_version = 0.78.0
33
commit = True
44
message = services/webserver api version: {current_version} → {new_version}
55
tag = False

services/web/server/src/simcore_service_webserver/api/v0/openapi.yaml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ openapi: 3.1.0
22
info:
33
title: simcore-service-webserver
44
description: Main service with an interface (http-API & websockets) to the web front-end
5-
version: 0.77.2
5+
version: 0.78.0
66
servers:
77
- url: ''
88
description: webserver
@@ -3788,6 +3788,13 @@ paths:
37883788
type: string
37893789
format: uuid
37903790
title: Function Id
3791+
- name: force
3792+
in: query
3793+
required: false
3794+
schema:
3795+
type: boolean
3796+
default: false
3797+
title: Force
37913798
responses:
37923799
'204':
37933800
description: Successful Response

services/web/server/src/simcore_service_webserver/functions/_controller/_functions_rest.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
from .._services_metadata.proxy import ServiceMetadata
4545
from ._functions_rest_exceptions import handle_rest_requests_exceptions
4646
from ._functions_rest_schemas import (
47+
FunctionDeleteQueryParams,
4748
FunctionFilters,
4849
FunctionGetQueryParams,
4950
FunctionGroupPathParams,
@@ -370,12 +371,18 @@ async def update_function(request: web.Request) -> web.Response:
370371
async def delete_function(request: web.Request) -> web.Response:
371372
path_params = parse_request_path_parameters_as(FunctionPathParams, request)
372373
function_id = path_params.function_id
374+
375+
query_params: FunctionDeleteQueryParams = parse_request_query_parameters_as(
376+
FunctionDeleteQueryParams, request
377+
)
378+
373379
req_ctx = AuthenticatedRequestContext.model_validate(request)
374380
await _functions_service.delete_function(
375381
app=request.app,
376-
function_id=function_id,
377382
user_id=req_ctx.user_id,
378383
product_name=req_ctx.product_name,
384+
function_id=function_id,
385+
force=query_params.force,
379386
)
380387

381388
return web.json_response(status=status.HTTP_204_NO_CONTENT)

0 commit comments

Comments
 (0)