Skip to content
Merged
Show file tree
Hide file tree
Changes from 84 commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
19bea51
feat: add readFunctions when getting permissions
giancarloromeo Jul 16, 2025
298bdd9
fix: update openapi-spec
giancarloromeo Jul 16, 2025
fa40d71
feat: add update endpoint
giancarloromeo Jul 17, 2025
9af987e
feat: add update functions endpoint
giancarloromeo Jul 17, 2025
27814d5
Merge branch 'master' into is1905/add-new-fuctions-rest-api-endpoints
giancarloromeo Jul 17, 2025
ee89ede
fix: update openapi-spec
giancarloromeo Jul 17, 2025
80535cc
fix: path
giancarloromeo Jul 17, 2025
a5f7066
feat: add batch get projects
giancarloromeo Jul 17, 2025
2d87133
fix: use new models
giancarloromeo Jul 17, 2025
14be903
feat: add list endpoint
giancarloromeo Jul 17, 2025
305b188
Merge branch 'master' into is1905/add-new-fuctions-rest-api-endpoints
giancarloromeo Jul 17, 2025
6043c7d
feat: get function
giancarloromeo Jul 17, 2025
7e67484
fix: minor
giancarloromeo Jul 17, 2025
2dc7497
Merge branch 'is1905/add-new-fuctions-rest-api-endpoints' of github.c…
giancarloromeo Jul 17, 2025
bcd0ff7
feat: add function list
giancarloromeo Jul 18, 2025
44ad1ce
fix: function listing
giancarloromeo Jul 18, 2025
4ce8271
fix: project id missing
giancarloromeo Jul 18, 2025
a65a99b
fix: list functions pagination
giancarloromeo Jul 18, 2025
e21a10b
fix: enable frontend
giancarloromeo Jul 18, 2025
e70e67e
fix: openapi spec
giancarloromeo Jul 18, 2025
3c46233
fix: add function ID
giancarloromeo Jul 18, 2025
d286654
fix: remap keys
giancarloromeo Jul 18, 2025
a29729b
fix: id key name
giancarloromeo Jul 18, 2025
fcedfc0
fix: remove unused uuid
giancarloromeo Jul 18, 2025
0c506ad
fix: template ID
giancarloromeo Jul 18, 2025
8cbf75e
fix: use template ID
giancarloromeo Jul 18, 2025
f06b3bf
feat: retrieve modified
giancarloromeo Jul 18, 2025
48f19af
feat: expose modified at
giancarloromeo Jul 18, 2025
0a969b5
fix: return proper templateId
giancarloromeo Jul 18, 2025
e8ca8bf
fix: typecheck
giancarloromeo Jul 18, 2025
4840afd
tests: add list functions
giancarloromeo Jul 21, 2025
a727158
tests: add function update
giancarloromeo Jul 21, 2025
edc8c2d
fix: typecheck
giancarloromeo Jul 21, 2025
b2a1898
fix: add modified_at field
giancarloromeo Jul 21, 2025
b57a590
fix: deprecated pydantic
giancarloromeo Jul 21, 2025
57010e5
fix: make openapi-spec
giancarloromeo Jul 21, 2025
f393d7c
Merge branch 'master' into is1905/add-new-fuctions-rest-api-endpoints
giancarloromeo Jul 21, 2025
606f2f7
fix: make openapi-spec
giancarloromeo Jul 21, 2025
a90ed58
Merge branch 'is1905/add-new-fuctions-rest-api-endpoints' of github.c…
giancarloromeo Jul 21, 2025
89571eb
fix: rename
giancarloromeo Jul 21, 2025
3c4e367
Merge branch 'master' into is1905/add-new-fuctions-rest-api-endpoints
giancarloromeo Jul 22, 2025
ebed70d
fix: use common create_json_response_from_page
giancarloromeo Jul 22, 2025
9d7fdbc
Merge branch 'is1905/add-new-fuctions-rest-api-endpoints' of github.c…
giancarloromeo Jul 22, 2025
d03ac59
fix: update field
giancarloromeo Jul 22, 2025
e03f861
Merge branch 'is1905/add-new-fuctions-rest-api-endpoints' of github.c…
odeimaiz Jul 22, 2025
2bf2924
Merge branch 'master' into is1905/add-new-fuctions-rest-api-endpoints
giancarloromeo Jul 22, 2025
86e692e
remove dummy response
odeimaiz Jul 22, 2025
a8b2387
readFunctions from backend
odeimaiz Jul 22, 2025
945f231
feat: add accessRights
giancarloromeo Jul 22, 2025
c6d9948
users pending dates
odeimaiz Jul 22, 2025
0485913
support also title
odeimaiz Jul 22, 2025
6c4d59c
Merge branch 'is1905/add-new-fuctions-rest-api-endpoints' of github.c…
odeimaiz Jul 22, 2025
5e3f9f6
fix: rename field
giancarloromeo Jul 22, 2025
7ac8a77
Merge branch 'is1905/add-new-fuctions-rest-api-endpoints' of github.c…
odeimaiz Jul 22, 2025
740c551
fix: make openapi-spec
giancarloromeo Jul 22, 2025
b900510
fix: order
giancarloromeo Jul 22, 2025
d440ad0
fix: access_rights not required
giancarloromeo Jul 22, 2025
92b7c1a
minor
odeimaiz Jul 22, 2025
dcb1dfc
add pagination args
odeimaiz Jul 22, 2025
714405f
Merge branch 'is1905/add-new-fuctions-rest-api-endpoints' of github.c…
odeimaiz Jul 22, 2025
66c3a89
template as property
odeimaiz Jul 22, 2025
5cb81d6
Merge branch 'master' into enh/connect-functions-browser
odeimaiz Jul 22, 2025
4d3398d
setTemplate in constructor
odeimaiz Jul 22, 2025
ab4acb5
add Preview Page
odeimaiz Jul 22, 2025
6f7451a
Merge branch 'enh/connect-functions-browser' of github.com:odeimaiz/o…
odeimaiz Jul 22, 2025
d5ec202
support all three functionClasses
odeimaiz Jul 22, 2025
0ea2c68
minor
odeimaiz Jul 22, 2025
8a1dfe1
accessRights -> myAccessRights
odeimaiz Jul 22, 2025
37878f6
fix: add accessRights when getting single function
giancarloromeo Jul 22, 2025
fc80afa
refactor
odeimaiz Jul 22, 2025
e79d068
Merge branch 'enh/connect-functions-browser' of github.com:odeimaiz/o…
odeimaiz Jul 22, 2025
df12a5f
show "owner"
odeimaiz Jul 22, 2025
3839c4f
patchFunction
odeimaiz Jul 22, 2025
b59acb9
back to accessRights
odeimaiz Jul 22, 2025
3b98ab4
keep templateId
odeimaiz Jul 22, 2025
d6488ae
_add_extras_to_project_function
odeimaiz Jul 22, 2025
aba75de
patchFunction
odeimaiz Jul 23, 2025
3f2f3f1
minor
odeimaiz Jul 23, 2025
b8e5989
no magic strings
odeimaiz Jul 23, 2025
9086b3b
shared-icon
odeimaiz Jul 23, 2025
07b68e6
robot is right
odeimaiz Jul 23, 2025
4f01370
better practices
odeimaiz Jul 23, 2025
686a459
Merge branch 'master' into enh/connect-functions-browser
odeimaiz Jul 23, 2025
965edb0
fix: enrich when add extras is requested
giancarloromeo Jul 23, 2025
f8ad103
fix: add include_extras query param
giancarloromeo Jul 23, 2025
fc947e9
Merge branch 'master' into enh/connect-functions-browser
mergify[bot] Jul 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,14 @@ qx.Class.define("osparc.dashboard.CardBase", {
this.addHintFromGids(shareIcon, gids);
},

populateMyAccessRightsIcon: function(shareIcon, myAccessRights) {
const canIWrite = Boolean(myAccessRights["write"]);
shareIcon.set({
source: canIWrite ? osparc.dashboard.CardBase.SHARE_ICON : osparc.dashboard.CardBase.SHARED_USER,
toolTipText: canIWrite ? "" : qx.locale.Manager.tr("Shared"),
});
},

addHintFromGids: function(icon, gids) {
const groupsStore = osparc.store.Groups.getInstance();
const groupEveryone = groupsStore.getEveryoneGroup();
Expand Down Expand Up @@ -524,6 +532,7 @@ qx.Class.define("osparc.dashboard.CardBase", {

__applyResourceData: function(resourceData) {
let uuid = null;
let title = "";
let owner = null;
let workbench = null;
let defaultHits = null;
Expand All @@ -534,16 +543,19 @@ qx.Class.define("osparc.dashboard.CardBase", {
case "tutorial":
case "hypertool":
uuid = resourceData.uuid ? resourceData.uuid : null;
title = resourceData.name,
owner = resourceData.prjOwner ? resourceData.prjOwner : "";
workbench = resourceData.workbench ? resourceData.workbench : {};
break;
case "function":
uuid = resourceData.uuid ? resourceData.uuid : null;
title = resourceData.title,
owner = "";
workbench = resourceData.workbench ? resourceData.workbench : {};
break;
case "service":
uuid = resourceData.key ? resourceData.key : null;
title = resourceData.name,
owner = resourceData.owner ? resourceData.owner : resourceData.contact;
icon = resourceData["icon"] || osparc.dashboard.CardBase.PRODUCT_ICON;
defaultHits = 0;
Expand All @@ -553,7 +565,7 @@ qx.Class.define("osparc.dashboard.CardBase", {
this.set({
resourceType: resourceData.resourceType,
uuid,
title: resourceData.name,
title,
description: resourceData.description,
owner,
accessRights: resourceData.accessRights ? resourceData.accessRights : {},
Expand Down Expand Up @@ -593,7 +605,11 @@ qx.Class.define("osparc.dashboard.CardBase", {
break;
}
case "function":
this.setIcon(osparc.data.model.StudyUI.PIPELINE_ICON);
if (resourceData["functionClass"] === osparc.data.model.Function.FUNCTION_CLASS.PROJECT) {
this.setIcon(osparc.data.model.StudyUI.PIPELINE_ICON);
} else {
this.setIcon(osparc.dashboard.CardBase.PRODUCT_ICON);
}
break;
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,23 +249,33 @@ qx.Class.define("osparc.dashboard.GridButtonItem", {
// overridden
_applyOwner: function(value, old) {
const label = this.getChildControl("subtitle-text");
const user = this.__createOwner(value);
label.setValue(user);
label.setVisibility(value ? "visible" : "excluded");
if (osparc.utils.Resources.isFunction(this.getResourceData())) {
const canIWrite = Boolean(this.getResourceData()["accessRights"]["write"]);
label.setValue(canIWrite ? "My Function" : "Read Only");
} else {
const user = this.__createOwner(value);
label.setValue(user);
label.setVisibility(value ? "visible" : "excluded");
}
},

_applyAccessRights: function(value) {
if (value && Object.keys(value).length) {
const shareIcon = this.getChildControl("subtitle-icon");
shareIcon.addListener("tap", e => {
e.stopPropagation();
this.openAccessRights();
}, this);
shareIcon.addListener("pointerdown", e => e.stopPropagation());
osparc.dashboard.CardBase.populateShareIcon(shareIcon, value);
if (this.isResourceType("function")) {
// in case of functions, the access rights are actually myAccessRights
osparc.dashboard.CardBase.populateMyAccessRightsIcon(shareIcon, value);
} else {
shareIcon.addListener("tap", e => {
e.stopPropagation();
this.openAccessRights();
}, this);
shareIcon.addListener("pointerdown", e => e.stopPropagation());
osparc.dashboard.CardBase.populateShareIcon(shareIcon, value);

if (this.isResourceType("study")) {
this._setStudyPermissions(value);
if (this.isResourceType("study")) {
this._setStudyPermissions(value);
}
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,24 +243,34 @@ qx.Class.define("osparc.dashboard.ListButtonItem", {

_applyOwner: function(value, old) {
const label = this.getChildControl("owner");
const user = this.__createOwner(value);
label.setValue(user);
if (osparc.utils.Resources.isFunction(this.getResourceData())) {
const canIWrite = Boolean(this.getResourceData()["accessRights"]["write"]);
label.setValue(canIWrite ? "My Function" : "Read Only");
} else {
const user = this.__createOwner(value);
label.setValue(user);
}

this.__makeItemResponsive(label);
},

_applyAccessRights: function(value) {
if (value && Object.keys(value).length) {
const shareIcon = this.getChildControl("shared-icon");
shareIcon.addListener("tap", e => {
e.stopPropagation();
this.openAccessRights();
}, this);
shareIcon.addListener("pointerdown", e => e.stopPropagation());
osparc.dashboard.CardBase.populateShareIcon(shareIcon, value);
if (this.isResourceType("function")) {
// in case of functions, the access rights are actually myAccessRights
osparc.dashboard.CardBase.populateMyAccessRightsIcon(shareIcon, value);
} else {
shareIcon.addListener("tap", e => {
e.stopPropagation();
this.openAccessRights();
}, this);
shareIcon.addListener("pointerdown", e => e.stopPropagation());
osparc.dashboard.CardBase.populateShareIcon(shareIcon, value);

if (this.isResourceType("study")) {
this._setStudyPermissions(value);
if (this.isResourceType("study")) {
this._setStudyPermissions(value);
}
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
const studyStore = osparc.store.Study.getInstance();
this.__resourceData["debt"] = studyStore.getStudyDebt(this.__resourceData["uuid"]);
}
// prefetch project's services metadata
osparc.store.Services.getStudyServicesMetadata(latestResourceData)
.finally(() => {
this.__resourceModel = new osparc.data.model.Study(latestResourceData);
Expand All @@ -75,15 +76,25 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
});
break;
case "function": {
// use function's underlying template info to fetch services metadata
// osparc.store.Templates.fetchTemplate(resourceData["uuid"]);
osparc.store.Services.getStudyServicesMetadata(latestResourceData)
.finally(() => {
this.__resourceModel = new osparc.data.model.Function(latestResourceData);
this.__resourceModel["resourceType"] = resourceData["resourceType"];
this.__resourceData["services"] = resourceData["services"];
this.__addPages();
});
addPages = (functionData, templateData = null) => {
this.__resourceModel = new osparc.data.model.Function(functionData, templateData);
this.__resourceModel["resourceType"] = resourceData["resourceType"];
this.__addPages();
}
if (resourceData["functionClass"] === osparc.data.model.Function.FUNCTION_CLASS.PROJECT) {
// this is only required for functions that have a template linked
osparc.store.Templates.fetchTemplate(resourceData["templateId"])
.then(templateData => {
// prefetch function's underlying template's services metadata
osparc.store.Services.getStudyServicesMetadata(templateData)
.finally(() => {
this.__resourceData["services"] = resourceData["services"];
addPages(latestResourceData, templateData);
});
});
} else {
addPages(latestResourceData);
}
break;
}
case "service": {
Expand Down Expand Up @@ -121,7 +132,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {

popUpInWindow: function(resourceData) {
const resourceDetails = new osparc.dashboard.ResourceDetails(resourceData);
const title = resourceData.name;
const title = resourceData.name || resourceData.title; // title is used by functions
const window = osparc.ui.window.Window.popUpInWindow(resourceDetails, title, this.WIDTH, this.HEIGHT).set({
layout: new qx.ui.layout.Grow(),
...osparc.ui.window.TabbedWindow.DEFAULT_PROPS,
Expand Down Expand Up @@ -173,7 +184,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
__addToolbarButtons: function(page) {
const resourceData = this.__resourceData;

if (this.__resourceData["resourceType"] === "function") {
if (osparc.utils.Resources.isFunction(this.__resourceData)) {
return; // no toolbar buttons for functions
}

Expand Down Expand Up @@ -395,10 +406,11 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
this.__addPreviewPage();
this.fireEvent("pagesAdded");
return;
} else if (this.__resourceData["resourceType"] === "function") {
} else if (osparc.utils.Resources.isFunction(this.__resourceData)) {
this.__addInfoPage();
// to build the preview page we need the underlying template data
// this.__addPreviewPage();
if (this.__resourceModel.getFunctionClass() === osparc.data.model.Function.FUNCTION_CLASS.PROJECT) {
this.__addPreviewPage();
}
this.fireEvent("pagesAdded");
return;
}
Expand Down Expand Up @@ -575,12 +587,12 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
const page = new osparc.dashboard.resources.pages.BasePage(title, iconSrc, id);
this.__addToolbarButtons(page);

const studyData = this.__resourceData;
const studyData = osparc.utils.Resources.isFunction(this.__resourceData) ? this.__resourceModel.getTemplate().serialize() : this.__resourceData;
const enabled = osparc.study.Utils.canShowPreview(studyData);
page.setEnabled(enabled);

const lazyLoadContent = () => {
const resourceModel = this.__resourceModel;
const resourceModel = osparc.utils.Resources.isFunction(this.__resourceData) ? this.__resourceModel.getTemplate() : this.__resourceData;
const preview = new osparc.study.StudyPreview(resourceModel);
page.addToContent(preview);
this.__widgets.push(preview);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,11 +310,6 @@ qx.Class.define("osparc.data.Permissions", {
return false;
}

// This needs to be provided by the backend
if (action === "readFunctions") {
return osparc.utils.Utils.isDevelopmentPlatform();
}

if (
this.__functionPermissions &&
action in this.__functionPermissions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -628,18 +628,22 @@ qx.Class.define("osparc.data.Resources", {
"functions": {
useCache: false,
endpoints: {
create: {
method: "POST",
url: statics.API + "/functions"
},
getOne: {
method: "GET",
url: statics.API + "/functions/{functionId}?include_extras=true"
},
getPage: {
method: "GET",
url: statics.API + "/functions?include_extras=true"
}
url: statics.API + "/functions?include_extras=true&offset={offset}&limit={limit}"
},
create: {
method: "POST",
url: statics.API + "/functions"
},
patch: {
method: "PATCH",
url: statics.API + "/functions/{functionId}"
},
}
},
/*
Expand Down
Loading
Loading