Skip to content

Commit 301f34c

Browse files
authored
✨ [Frontend] Convert To Pipeline (#7522)
1 parent 7b642fc commit 301f34c

File tree

13 files changed

+207
-142
lines changed

13 files changed

+207
-142
lines changed

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,12 @@ qx.Class.define("osparc.dashboard.CardBase", {
384384
},
385385

386386
uiMode: {
387-
check: ["workbench", "guided", "app", "standalone"], // "guided" is no longer used
387+
check: [
388+
"workbench", // =auto, the frontend decides the icon and default view
389+
"app", "guided", // "guided" is no longer used
390+
"standalone",
391+
"pipeline",
392+
],
388393
nullable: true,
389394
apply: "__applyUiMode"
390395
},

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", {
481481
if (
482482
osparc.utils.Resources.isService(resourceData) ||
483483
!osparc.product.Utils.showStudyPreview() ||
484-
!(osparc.study.Utils.getUiMode(resourceData) === "workbench")
484+
["app", "guided", "standalone"].includes(osparc.study.Utils.getUiMode(resourceData))
485485
) {
486486
// there is no pipelining or don't show it
487487
return null;

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

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1789,17 +1789,52 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
17891789
convertToPipelineButton["convertToPipelineButton"] = true;
17901790
const uiMode = osparc.study.Utils.getUiMode(studyData);
17911791
convertToPipelineButton.setVisibility(uiMode === "standalone" ? "visible" : "excluded");
1792-
convertToPipelineButton.addListener("execute", () => {
1793-
this.__updateUIMode(studyData, "workbench")
1794-
.catch(err => osparc.FlashMessenger.logError(err, this.tr("Something went wrong while converting to pipeline")));
1795-
}, this);
1792+
convertToPipelineButton.addListener("execute", () => this.__convertToPipelineClicked(studyData), this);
17961793
return convertToPipelineButton;
17971794
},
17981795

1796+
__convertToPipelineClicked: function(studyData) {
1797+
let message = this.tr("Would you like to convert this project to a pipeline?");
1798+
message += "<br>" + this.tr("Alternatively, you can create a copy of the project and convert the copy instead.");
1799+
const confirmationWin = new osparc.ui.window.Confirmation();
1800+
confirmationWin.set({
1801+
caption: this.tr("Convert to Pipeline"),
1802+
confirmText: this.tr("Convert"),
1803+
confirmAction: "create",
1804+
message,
1805+
});
1806+
confirmationWin.getChildControl("cancel-button").exclude();
1807+
const copyOptionButton = new qx.ui.form.Button().set({
1808+
appearance: "form-button-text",
1809+
label: this.tr("Create a copy and convert it"),
1810+
});
1811+
confirmationWin.getChildControl("buttons-layout").addAt(copyOptionButton, 0);
1812+
confirmationWin.addListener("close", () => {
1813+
if (confirmationWin.getConfirmed()) {
1814+
this.__updateUIMode(studyData, "pipeline")
1815+
.then(() => osparc.FlashMessenger.logAs(this.tr("Project converted to pipeline"), "INFO"))
1816+
.catch(err => osparc.FlashMessenger.logError(err, this.tr("Something went wrong while converting to pipeline")));
1817+
}
1818+
});
1819+
copyOptionButton.addListener("execute", () => {
1820+
confirmationWin.close();
1821+
this.__duplicateStudy(studyData)
1822+
.then(task => {
1823+
task.addListener("resultReceived", e => {
1824+
const copiedStudy = e.getData();
1825+
this.__updateUIMode(copiedStudy, "pipeline")
1826+
.then(() => osparc.FlashMessenger.logAs(this.tr("Project's copy converted to pipeline"), "INFO"))
1827+
.catch(err => osparc.FlashMessenger.logError(err, this.tr("Something went wrong while converting the copy to pipeline")));
1828+
}, this);
1829+
});
1830+
}, this);
1831+
confirmationWin.open();
1832+
},
1833+
17991834
__updateUIMode: function(studyData, uiMode) {
18001835
const studyUI = osparc.utils.Utils.deepCloneObject(studyData["ui"]);
18011836
studyUI["mode"] = uiMode;
1802-
return osparc.info.StudyUtils.patchStudyData(studyData, "ui", studyUI)
1837+
return osparc.store.Study.patchStudyData(studyData, "ui", studyUI)
18031838
.then(() => this._updateStudyData(studyData))
18041839
},
18051840

@@ -1889,21 +1924,11 @@ qx.Class.define("osparc.dashboard.StudyBrowser", {
18891924
},
18901925

18911926
__duplicateStudy: function(studyData) {
1892-
const text = this.tr("Duplicate process started and added to the background tasks");
1893-
osparc.FlashMessenger.logAs(text, "INFO");
1894-
1895-
const params = {
1896-
url: {
1897-
"studyId": studyData["uuid"]
1898-
}
1899-
};
1900-
const options = {
1901-
pollTask: true
1902-
};
1903-
const fetchPromise = osparc.data.Resources.fetch("studies", "duplicate", params, options);
1904-
const pollTasks = osparc.store.PollTasks.getInstance();
1905-
pollTasks.createPollingTask(fetchPromise)
1906-
.then(task => this.__taskDuplicateReceived(task, studyData["name"]))
1927+
osparc.study.Utils.duplicateStudy(studyData)
1928+
.then(task => {
1929+
this.__taskDuplicateReceived(task, studyData["name"]);
1930+
return task;
1931+
})
19071932
.catch(err => osparc.FlashMessenger.logError(err, this.tr("Something went wrong while duplicating")));
19081933
},
19091934

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,13 @@ qx.Class.define("osparc.data.PollTask", {
102102
},
103103

104104
extractProgress: function(updateData) {
105+
const toNumberWithMaxTwoDecimals = value => {
106+
return Math.round(Number(value) * 100) / 100;
107+
};
108+
105109
if ("task_progress" in updateData) {
106110
const taskProgress = updateData["task_progress"];
107-
const percent = taskProgress["percent"] ? parseFloat(taskProgress["percent"].toFixed(3)) : taskProgress["percent"];
111+
const percent = taskProgress["percent"] ? toNumberWithMaxTwoDecimals(taskProgress["percent"]) : taskProgress["percent"];
108112
return percent;
109113
}
110114
return 0;

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,12 @@ qx.Class.define("osparc.data.model.StudyUI", {
6363
},
6464

6565
mode: {
66-
check: ["workbench", "guided", "app", "standalone"], // "guided" is no longer used
66+
check: [
67+
"workbench", // =auto, the frontend decides the icon and default view
68+
"app", "guided", // "guided" is no longer used
69+
"standalone",
70+
"pipeline",
71+
],
6772
init: "workbench",
6873
nullable: true,
6974
event: "changeMode",

services/static-webserver/client/source/class/osparc/desktop/SlideshowView.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ qx.Class.define("osparc.desktop.SlideshowView", {
7272
const nodeId = e.getData();
7373
this.__hideNode(nodeId);
7474
}, this);
75-
slideshowToolbar.addListener("slidesStop", () => this.getStudy().getUi().setMode("workbench"), this);
75+
slideshowToolbar.addListener("slidesStop", () => this.getStudy().getUi().setMode("pipeline"), this);
7676
this._add(slideshowToolbar);
7777

7878
const mainView = this.__mainView = new qx.ui.container.Composite(new qx.ui.layout.HBox().set({

services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -707,14 +707,19 @@ qx.Class.define("osparc.desktop.StudyEditor", {
707707
this.__viewsStack.setSelection([this.__slideshowView]);
708708
this.__slideshowView.startSlides();
709709
break;
710-
case "standalone": {
710+
case "standalone":
711711
this.__viewsStack.setSelection([this.__workbenchView]);
712712
this.__workbenchView.openFirstNode();
713713
break;
714-
}
714+
case "pipeline":
715+
this.__viewsStack.setSelection([this.__workbenchView]);
716+
this.__workbenchView.setMaximized(false);
717+
this.__workbenchView.showPipeline();
718+
break;
715719
case "workbench":
716720
default: {
717721
this.__viewsStack.setSelection([this.__workbenchView]);
722+
// OM: Is this needed?
718723
if (oldUIMode === "standalone") {
719724
// in this transition, show workbenchUI
720725
this.__workbenchView.setMaximized(false);

services/static-webserver/client/source/class/osparc/jobs/JobsButton.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ qx.Class.define("osparc.jobs.JobsButton", {
7272
},
7373

7474
__updateJobsButton: function() {
75-
this._createChildControlImpl("icon");
75+
this.getChildControl("icon");
7676
const number = this.getChildControl("number");
7777

7878
const jobsStore = osparc.store.Jobs.getInstance();

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

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -80,18 +80,7 @@ qx.Class.define("osparc.navigation.StudyTitleWOptions", {
8080
label: this.tr("Convert to Pipeline"),
8181
icon: null,
8282
});
83-
control.addListener("execute", () => {
84-
this.getStudy().getUi().setMode("workbench");
85-
});
86-
break;
87-
case "study-menu-convert-to-standalone":
88-
control = new qx.ui.menu.Button().set({
89-
label: this.tr("Convert to Standalone"),
90-
icon: null,
91-
});
92-
control.addListener("execute", () => {
93-
this.getStudy().getUi().setMode("standalone");
94-
});
83+
control.addListener("execute", () => this.__convertToPipelineClicked(), this);
9584
break;
9685
case "study-menu-restore":
9786
control = new qx.ui.menu.Button().set({
@@ -114,8 +103,9 @@ qx.Class.define("osparc.navigation.StudyTitleWOptions", {
114103
optionsMenu.setAppearance("menu-wider");
115104
optionsMenu.add(this.getChildControl("study-menu-info"));
116105
optionsMenu.add(this.getChildControl("study-menu-reload"));
117-
optionsMenu.add(this.getChildControl("study-menu-convert-to-pipeline"));
118-
optionsMenu.add(this.getChildControl("study-menu-convert-to-standalone"));
106+
if (osparc.product.Utils.hasConvertToPipelineEnabled()) {
107+
optionsMenu.add(this.getChildControl("study-menu-convert-to-pipeline"));
108+
}
119109
optionsMenu.add(this.getChildControl("study-menu-restore"));
120110
optionsMenu.add(this.getChildControl("study-menu-open-logger"));
121111
control = new qx.ui.form.MenuButton().set({
@@ -161,22 +151,11 @@ qx.Class.define("osparc.navigation.StudyTitleWOptions", {
161151
converter: mode => mode === "standalone" ? "visible" : "excluded"
162152
});
163153

164-
const convertToPipelineButton = this.getChildControl("study-menu-convert-to-pipeline");
165-
const convertToStandaloneButton = this.getChildControl("study-menu-convert-to-standalone");
166154
if (osparc.product.Utils.hasConvertToPipelineEnabled()) {
155+
const convertToPipelineButton = this.getChildControl("study-menu-convert-to-pipeline");
167156
study.getUi().bind("mode", convertToPipelineButton, "visibility", {
168157
converter: mode => mode === "standalone" ? "visible" : "excluded"
169158
});
170-
171-
const evaluateConvertToStandaloneButton = () => {
172-
// exclude until we have the export to standalone backend functionality
173-
convertToStandaloneButton.exclude();
174-
};
175-
study.getWorkbench().addListener("pipelineChanged", () => evaluateConvertToStandaloneButton());
176-
study.getUi().addListener("changeMode", () => evaluateConvertToStandaloneButton());
177-
} else {
178-
convertToPipelineButton.exclude();
179-
convertToStandaloneButton.exclude();
180159
}
181160

182161
const restoreButton = this.getChildControl("study-menu-restore");
@@ -191,6 +170,25 @@ qx.Class.define("osparc.navigation.StudyTitleWOptions", {
191170
} else {
192171
this.exclude();
193172
}
194-
}
173+
},
174+
175+
__convertToPipelineClicked: function() {
176+
let message = this.tr("Would you like to convert this project to a pipeline?");
177+
message += "<br>" + this.tr("If you want to create a copy of the project and convert the copy instead, please close the project first.");
178+
const confirmationWin = new osparc.ui.window.Confirmation();
179+
confirmationWin.set({
180+
caption: this.tr("Convert to Pipeline"),
181+
confirmText: this.tr("Convert"),
182+
confirmAction: "create",
183+
message,
184+
});
185+
confirmationWin.addListener("close", () => {
186+
if (confirmationWin.getConfirmed()) {
187+
this.getStudy().getUi().setMode("pipeline");
188+
osparc.FlashMessenger.logAs(this.tr("Project converted to pipeline"), "INFO");
189+
}
190+
});
191+
confirmationWin.open();
192+
},
195193
}
196194
});

services/static-webserver/client/source/class/osparc/product/Utils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ qx.Class.define("osparc.product.Utils", {
189189
},
190190

191191
hasConvertToPipelineEnabled: function() {
192-
return false;
192+
return osparc.store.StaticInfo.getInstance().isDevFeaturesEnabled();
193193
},
194194

195195
// oSPARC only

0 commit comments

Comments
 (0)