Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -141,13 +141,29 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
__classifiersPage: null,
__qualityPage: null,

__addOpenButton: function(page) {
__addToolbarButtons: function(page) {
const resourceData = this.__resourceData;

const toolbar = this.self().createToolbar();
page.addToHeader(toolbar);

if (["study", "template"].includes(this.__resourceData["resourceType"])) {
if (["study", "template", "tutorial"].includes(resourceData["resourceType"])) {
const cantReadServices = osparc.study.Utils.getCantReadServices(resourceData["services"]);
if (cantReadServices.length) {
const requestAccessButton = new qx.ui.form.Button(this.tr("Request Apps Access"));
osparc.dashboard.resources.pages.BasePage.decorateHeaderButton(requestAccessButton);
requestAccessButton.set({
minWidth: 170,
maxWidth: 170,
});
requestAccessButton.addListener("execute", () => {
osparc.share.RequestServiceAccess.openRequestAccess(cantReadServices);
});
toolbar.add(requestAccessButton);
}
}

if (this.__resourceData["resourceType"] === "study") {
const payDebtButton = new qx.ui.form.Button(this.tr("Credits required"));
page.payDebtButton = payDebtButton;
osparc.dashboard.resources.pages.BasePage.decorateHeaderButton(payDebtButton);
Expand Down Expand Up @@ -405,7 +421,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
const title = this.tr("Overview");
const iconSrc = "@FontAwesome5Solid/info/22";
const page = this.__infoPage = new osparc.dashboard.resources.pages.BasePage(title, iconSrc, id);
this.__addOpenButton(page);
this.__addToolbarButtons(page);

const lazyLoadContent = () => {
const resourceData = this.__resourceData;
Expand Down Expand Up @@ -446,7 +462,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
const title = this.tr("Billing Settings");
const iconSrc = "@FontAwesome5Solid/cogs/22";
const page = this.__billingSettings = new osparc.dashboard.resources.pages.BasePage(title, iconSrc, id);
this.__addOpenButton(page);
this.__addToolbarButtons(page);

if (resourceData["resourceType"] === "study") {
const canBeOpened = osparc.study.Utils.canShowBillingOptions(resourceData);
Expand All @@ -473,7 +489,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
const title = this.tr("Tiers");
const iconSrc = "@FontAwesome5Solid/server/22";
const page = new osparc.dashboard.resources.pages.BasePage(title, iconSrc, id);
this.__addOpenButton(page);
this.__addToolbarButtons(page);

const lazyLoadContent = () => {
const pricingUnitsList = new osparc.service.PricingUnitsList(resourceData);
Expand Down Expand Up @@ -502,7 +518,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
const title = this.tr("Pipeline View");
const iconSrc = "@FontAwesome5Solid/eye/22";
const page = new osparc.dashboard.resources.pages.BasePage(title, iconSrc, id);
this.__addOpenButton(page);
this.__addToolbarButtons(page);

const studyData = this.__resourceData;
const enabled = osparc.study.Utils.canShowPreview(studyData);
Expand All @@ -528,7 +544,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
const title = this.tr("Conversations");
const iconSrc = "@FontAwesome5Solid/comments/22";
const page = new osparc.dashboard.resources.pages.BasePage(title, iconSrc, id);
this.__addOpenButton(page);
this.__addToolbarButtons(page);

const lazyLoadContent = () => {
const conversations = new osparc.study.Conversations(resourceData);
Expand All @@ -544,7 +560,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
const title = this.tr("Sharing");
const iconSrc = "@FontAwesome5Solid/share-alt/22";
const page = this.__permissionsPage = new osparc.dashboard.resources.pages.BasePage(title, iconSrc, id);
this.__addOpenButton(page);
this.__addToolbarButtons(page);

const lazyLoadContent = () => {
const resourceData = this.__resourceData;
Expand Down Expand Up @@ -587,7 +603,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
const title = this.tr("Classifiers");
const iconSrc = "@FontAwesome5Solid/search/22";
const page = this.__classifiersPage = new osparc.dashboard.resources.pages.BasePage(title, iconSrc, id);
this.__addOpenButton(page);
this.__addToolbarButtons(page);

const lazyLoadContent = () => {
const resourceData = this.__resourceData;
Expand Down Expand Up @@ -625,7 +641,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
const title = this.tr("Quality");
const iconSrc = "@FontAwesome5Solid/star-half/22";
const page = this.__qualityPage = new osparc.dashboard.resources.pages.BasePage(title, iconSrc, id);
this.__addOpenButton(page);
this.__addToolbarButtons(page);

const lazyLoadContent = () => {
const qualityEditor = new osparc.metadata.QualityEditor(resourceData);
Expand Down Expand Up @@ -655,7 +671,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
const title = this.tr("Tags");
const iconSrc = "@FontAwesome5Solid/tags/22";
const page = this.__tagsPage = new osparc.dashboard.resources.pages.BasePage(title, iconSrc, id);
this.__addOpenButton(page);
this.__addToolbarButtons(page);

const lazyLoadContent = () => {
const tagManager = new osparc.form.tag.TagManager(resourceData);
Expand All @@ -681,7 +697,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
const title = this.tr("Services Updates");
const iconSrc = "@MaterialIcons/update/24";
const page = this.__servicesUpdatePage = new osparc.dashboard.resources.pages.BasePage(title, iconSrc, id);
this.__addOpenButton(page);
this.__addToolbarButtons(page);

const studyData = this.__resourceData;
const enabled = osparc.study.Utils.canShowServiceUpdates(studyData);
Expand Down Expand Up @@ -713,7 +729,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
const title = this.tr("Boot Options");
const iconSrc = "@FontAwesome5Solid/play-circle/22";
const page = new osparc.dashboard.resources.pages.BasePage(title, iconSrc, id);
this.__addOpenButton(page);
this.__addToolbarButtons(page);

const studyData = this.__resourceData;
const enabled = osparc.study.Utils.canShowServiceBootOptions(studyData);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,32 +235,7 @@ qx.Class.define("osparc.share.CollaboratorsStudy", {
if (gids.length === 0) {
return;
}

const promises = [];
gids.forEach(gid => {
const params = {
url: {
"studyId": this._serializedDataCopy["uuid"],
"gid": gid
}
};
promises.push(osparc.data.Resources.fetch("studies", "checkShareePermissions", params));
});
Promise.all(promises)
.then(values => {
const noAccessible = values.filter(value => value["accessible"] === false);
if (noAccessible.length) {
const shareePermissions = new osparc.share.ShareePermissions(noAccessible);
const win = osparc.ui.window.Window.popUpInWindow(shareePermissions, this.tr("Sharee permissions"), 500, 500, "@FontAwesome5Solid/exclamation-triangle/14").set({
clickAwayClose: false,
resizable: true,
showClose: true
});
win.getChildControl("icon").set({
textColor: "warning-yellow"
});
}
});
osparc.share.ShareePermissions.checkShareePermissions(this._serializedDataCopy["uuid"], gids);
}
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* oSPARC - The SIMCORE frontend - https://osparc.io
* Copyright: 2025 IT'IS Foundation - https://itis.swiss
* License: MIT - https://opensource.org/licenses/MIT
* Authors: Odei Maiz (odeimaiz)
*/

qx.Class.define("osparc.share.RequestServiceAccess", {
extend: qx.ui.core.Widget,

construct: function(cantReadServicesData) {
this.base(arguments);

this._setLayout(new qx.ui.layout.VBox(25));

this.__populateLayout(cantReadServicesData);
},

statics: {
openRequestAccess: function(cantReadServicesData) {
const requestServiceAccess = new osparc.share.RequestServiceAccess(cantReadServicesData);
const caption = qx.locale.Manager.tr("Request Apps Access");
osparc.ui.window.Window.popUpInWindow(requestServiceAccess, caption, 600, 400).set({
clickAwayClose: false,
resizable: true,
showClose: true
});
}
},

members: {
__populateLayout: function(cantReadServicesData) {
const text = this.tr("In order to open the project, the following users/groups need to give you access to some apps. Please contact the app owner:");
this._add(new qx.ui.basic.Label().set({
value: text,
font: "text-14",
rich: true,
wrap: true
}));

const grid = new qx.ui.layout.Grid(20, 10);
const layout = new qx.ui.container.Composite(grid);
this._add(layout);

// Header
layout.add(new qx.ui.basic.Label(this.tr("Owner")), {
row: 0,
column: 0
});
layout.add(new qx.ui.basic.Label(this.tr("Email")), {
row: 0,
column: 1
});
layout.add(new qx.ui.basic.Label(this.tr("App")), {
row: 0,
column: 2
});

// Populate the grid with the cantReadServicesData
cantReadServicesData.forEach((cantReadServiceData, idx) => {
const group = osparc.store.Groups.getInstance().getGroup(cantReadServiceData["owner"]);
if (group) {
const username = new qx.ui.basic.Label(group.getLabel()).set({
rich: true,
selectable: true,
});
layout.add(username, {
row: idx+1,
column: 0
});
const email = new qx.ui.basic.Label(group.getEmail()).set({
rich: true,
selectable: true,
});
layout.add(email, {
row: idx+1,
column: 1
});
const appLabel = new qx.ui.basic.Label().set({
value: `${cantReadServiceData["key"]}:${osparc.service.Utils.extractVersionDisplay(cantReadServiceData["release"])}`,
rich: true,
selectable: true,
});
layout.add(appLabel, {
row: idx+1,
column: 2
});
}
});
}
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
* Authors: Odei Maiz (odeimaiz)
*/

/**
* Data structure for showing sharee permissions. Array of objects with the following keys
* - accessible: boolean
* - gid: string // sharee group id
* - inaccessible_services: Array of objects with keys "key" and "version"
*/
qx.Class.define("osparc.share.ShareePermissions", {
extend: qx.ui.core.Widget,

Expand All @@ -16,6 +22,37 @@ qx.Class.define("osparc.share.ShareePermissions", {
this.__populateLayout(shareesData);
},

statics: {
checkShareePermissions: function(studyId, gids) {
const promises = [];
gids.forEach(gid => {
const params = {
url: {
studyId,
gid,
}
};
promises.push(osparc.data.Resources.fetch("studies", "checkShareePermissions", params));
});
Promise.all(promises)
.then(shareesData => {
const inaccessibleShareesData = shareesData.filter(value => value["accessible"] === false);
if (inaccessibleShareesData.length) {
const shareePermissions = new osparc.share.ShareePermissions(inaccessibleShareesData);
const caption = qx.locale.Manager.tr("Sharee permissions");
const win = osparc.ui.window.Window.popUpInWindow(shareePermissions, caption, 500, 500, "@FontAwesome5Solid/exclamation-triangle/14").set({
clickAwayClose: false,
resizable: true,
showClose: true
});
win.getChildControl("icon").set({
textColor: "warning-yellow"
});
}
});
},
},

members: {
__populateLayout: function(shareesData) {
const text = this.tr("The following users/groups will not be able to open the shared study, because they don't have access to some services. Please contact the service owner(s) to give permission.");
Expand All @@ -33,7 +70,7 @@ qx.Class.define("osparc.share.ShareePermissions", {
this._add(layout);
for (let i=0; i<shareesData.length; i++) {
const shareeData = shareesData[i];
const group = osparc.store.Groups.getInstance().getGroup(shareeData.gid);
const group = osparc.store.Groups.getInstance().getGroup(shareeData["gid"]);
if (group) {
layout.add(new qx.ui.basic.Label(group.getLabel()), {
row: i,
Expand All @@ -47,7 +84,9 @@ qx.Class.define("osparc.share.ShareePermissions", {
});
const infoButton = new qx.ui.form.Button(null, "@MaterialIcons/info_outline/14");
infoButton.setAppearance("strong-button");
const label = new qx.ui.basic.Label();
const label = new qx.ui.basic.Label().set({
alignY: "middle",
});
hBox.add(infoButton);
hBox.add(label);
osparc.store.Services.getService(inaccessibleService.key, inaccessibleService.version)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -442,8 +442,7 @@ qx.Class.define("osparc.study.Utils", {
if (studyData["ui"]["mode"] === "pipeline") {
resolve(osparc.data.model.StudyUI.PIPELINE_ICON);
} else {
const defaultIcon = osparc.dashboard.CardBase.PRODUCT_ICON;
// the was to guess the TI type is to check the boot mode of the ti-postpro in the pipeline
const productIcon = osparc.dashboard.CardBase.PRODUCT_ICON;
const wbServices = this.self().getNonFrontendNodes(studyData);
if (wbServices.length === 1) {
const wbService = wbServices[0];
Expand All @@ -452,8 +451,9 @@ qx.Class.define("osparc.study.Utils", {
if (serviceMetadata && serviceMetadata["icon"]) {
resolve(serviceMetadata["icon"]);
}
resolve(defaultIcon);
});
resolve(productIcon);
})
.catch(() => resolve(productIcon));
} else {
resolve(osparc.data.model.StudyUI.PIPELINE_ICON);
}
Expand Down
Loading