diff --git a/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js b/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js index 6c1b9fa31d2..50318210031 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js @@ -60,8 +60,8 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { case "function": // when getting the latest study data, the debt information was lost if (osparc.study.Utils.isInDebt(this.__resourceData)) { - const mainStore = osparc.store.Store.getInstance(); - this.__resourceData["debt"] = mainStore.getStudyDebt(this.__resourceData["uuid"]); + const studyStore = osparc.store.Study.getInstance(); + this.__resourceData["debt"] = studyStore.getStudyDebt(this.__resourceData["uuid"]); } osparc.store.Services.getStudyServicesMetadata(latestResourceData) .finally(() => { diff --git a/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js b/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js index 01a666d2624..50f497028fa 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js @@ -742,15 +742,15 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { this.__reloadStudies(); }, this); - const store = osparc.store.Store.getInstance(); - store.addListener("studyStateChanged", e => { + const studyStore = osparc.store.Study.getInstance(); + studyStore.addListener("studyStateChanged", e => { const { studyId, state, } = e.getData(); this.__studyStateChanged(studyId, state); }); - store.addListener("studyDebtChanged", e => { + studyStore.addListener("studyDebtChanged", e => { const { studyId, debt, @@ -924,7 +924,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { }, invalidateStudies: function() { - osparc.store.Store.getInstance().invalidate("studies"); + osparc.store.Study.getInstance().invalidateStudies(); this.__resetStudiesList(); if (this._resourcesContainer.getFlatList()) { this._resourcesContainer.getFlatList().nextRequest = null; @@ -1506,7 +1506,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { // LAYOUT // __studyStateReceived: function(studyId, state, errors) { - osparc.store.Store.getInstance().setStudyState(studyId, state); + osparc.store.Study.getInstance().setStudyState(studyId, state); if (errors && errors.length) { console.error(errors); } @@ -1542,10 +1542,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { minStudyData["workspaceId"] = this.getCurrentWorkspaceId(); minStudyData["folderId"] = this.getCurrentFolderId(); this._showLoadingPage(this.tr("Creating ") + (minStudyData.name || osparc.product.Utils.getStudyAlias())); - const params = { - data: minStudyData - }; - osparc.study.Utils.createStudyAndPoll(params) + osparc.study.Utils.createStudyAndPoll(minStudyData) .then(studyData => this.__startStudyAfterCreating(studyData["uuid"])) .catch(err => { this._hideLoadingPage(); diff --git a/services/static-webserver/client/source/class/osparc/data/Resources.js b/services/static-webserver/client/source/class/osparc/data/Resources.js index c934e90380a..dffd67aaac2 100644 --- a/services/static-webserver/client/source/class/osparc/data/Resources.js +++ b/services/static-webserver/client/source/class/osparc/data/Resources.js @@ -149,10 +149,6 @@ qx.Class.define("osparc.data.Resources", { method: "GET", url: statics.API + "/projects:search?filters={%22trashed%22:%22true%22}&offset={offset}&limit={limit}&order_by={orderBy}&type=user" }, - postToTemplate: { - method: "POST", - url: statics.API + "/projects?from_study={study_id}&as_template=true©_data={copy_data}&hidden={hidden}" - }, open: { method: "POST", url: statics.API + "/projects/{studyId}:open" @@ -620,6 +616,10 @@ qx.Class.define("osparc.data.Resources", { method: "GET", url: statics.API + "/projects:search?type=template&offset={offset}&limit={limit}&order_by={orderBy}&template_type={templateType}&text={text}" }, + postToTemplate: { + method: "POST", + url: statics.API + "/projects?from_study={study_id}&as_template=true©_data={copy_data}&hidden={hidden}" + }, } }, /* diff --git a/services/static-webserver/client/source/class/osparc/data/model/Study.js b/services/static-webserver/client/source/class/osparc/data/model/Study.js index 1469e15569f..12d7b54ecec 100644 --- a/services/static-webserver/client/source/class/osparc/data/model/Study.js +++ b/services/static-webserver/client/source/class/osparc/data/model/Study.js @@ -587,21 +587,14 @@ qx.Class.define("osparc.data.model.Study", { if ("disableServiceAutoStart" in this.getDev()) { return this.getDev()["disableServiceAutoStart"]; } - return null; + return false; }, openStudy: function() { - const params = { - url: { - "studyId": this.getUuid() - }, - data: osparc.utils.Utils.getClientSessionID() - }; - if (this.getDisableServiceAutoStart() !== null) { - params["url"]["disableServiceAutoStart"] = this.getDisableServiceAutoStart(); - return osparc.data.Resources.fetch("studies", "openDisableAutoStart", params); + if (this.getDisableServiceAutoStart()) { + return osparc.store.Study.getInstance().openStudy(this.getUuid(), false); } - return osparc.data.Resources.fetch("studies", "open", params); + return osparc.store.Study.getInstance().openStudy(this.getUuid()); }, stopStudy: function() { diff --git a/services/static-webserver/client/source/class/osparc/desktop/MainPage.js b/services/static-webserver/client/source/class/osparc/desktop/MainPage.js index f969a391533..dde0e01db56 100644 --- a/services/static-webserver/client/source/class/osparc/desktop/MainPage.js +++ b/services/static-webserver/client/source/class/osparc/desktop/MainPage.js @@ -236,22 +236,13 @@ qx.Class.define("osparc.desktop.MainPage", { const studyId = data["studyData"].uuid; const studyName = data["studyData"].name; const copyData = data["copyData"]; + const hidden = false; const templateAccessRights = data["accessRights"]; const templateType = data["templateType"]; - const params = { - url: { - "study_id": studyId, - "copy_data": copyData, - "hidden": false, - }, - }; - const options = { - pollTask: true - }; - const fetchPromise = osparc.data.Resources.fetch("studies", "postToTemplate", params, options); + const pollPromise = osparc.store.Templates.createTemplate(studyId, copyData, hidden); const pollTasks = osparc.store.PollTasks.getInstance(); - pollTasks.createPollingTask(fetchPromise) + pollTasks.createPollingTask(pollPromise) .then(task => { const tutorialBrowser = this.__dashboard.getTutorialBrowser(); if (tutorialBrowser && templateType === osparc.data.model.StudyUI.TUTORIAL_TYPE) { @@ -318,7 +309,7 @@ qx.Class.define("osparc.desktop.MainPage", { const currentStudy = store.getCurrentStudy(); while (currentStudy.isLocked()) { await osparc.utils.Utils.sleep(1000); - store.getStudyState(studyId); + osparc.store.Study.getInstance().getStudyState(studyId); } this.__loadingPage.setMessages([]); this.__openSnapshot(studyId, snapshotId); @@ -364,7 +355,7 @@ qx.Class.define("osparc.desktop.MainPage", { const currentStudy = store.getCurrentStudy(); while (currentStudy.isLocked()) { await osparc.utils.Utils.sleep(1000); - store.getStudyState(studyId); + osparc.store.Study.getInstance().getStudyState(studyId); } this.__loadingPage.setMessages([]); this.__openIteration(iterationUuid); diff --git a/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js b/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js index 81c1e85b070..b49d5d9ae92 100644 --- a/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js +++ b/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js @@ -628,7 +628,7 @@ qx.Class.define("osparc.desktop.StudyEditor", { /* If no projectStateUpdated comes in 60 seconds, client must check state of pipeline and update button accordingly. */ const timer = setTimeout(() => { - osparc.store.Store.getInstance().getStudyState(pipelineId); + osparc.store.Study.getInstance().getStudyState(pipelineId); }, 60000); const socket = osparc.wrapper.WebSocket.getInstance(); socket.getSocket().once("projectStateUpdated", ({ "project_uuid": projectUuid }) => { @@ -928,13 +928,7 @@ qx.Class.define("osparc.desktop.StudyEditor", { }, __closeStudy: function() { - const params = { - url: { - "studyId": this.getStudy().getUuid() - }, - data: osparc.utils.Utils.getClientSessionID() - }; - osparc.data.Resources.fetch("studies", "close", params) + osparc.store.Study.getInstance().closeStudy(this.getStudy().getUuid()) .catch(err => console.error(err)); }, diff --git a/services/static-webserver/client/source/class/osparc/store/Store.js b/services/static-webserver/client/source/class/osparc/store/Store.js index f614c470822..a020653ed19 100644 --- a/services/static-webserver/client/source/class/osparc/store/Store.js +++ b/services/static-webserver/client/source/class/osparc/store/Store.js @@ -249,14 +249,7 @@ qx.Class.define("osparc.store.Store", { }, }, - events: { - "studyStateChanged": "qx.event.type.Data", - "studyDebtChanged": "qx.event.type.Data", - }, - members: { - __studiesInDebt: null, - // fetch resources that do not require log in preloadCalls: async function() { await osparc.data.Resources.get("config"); @@ -436,73 +429,6 @@ qx.Class.define("osparc.store.Store", { return null; }, - getStudyState: function(studyId) { - osparc.data.Resources.fetch("studies", "state", { - url: { - "studyId": studyId - } - }) - .then(({state}) => { - this.setStudyState(studyId, state); - }); - }, - - setStudyState: function(studyId, state) { - const studiesWStateCache = this.getStudies(); - const idx = studiesWStateCache.findIndex(studyWStateCache => studyWStateCache["uuid"] === studyId); - if (idx !== -1) { - studiesWStateCache[idx]["state"] = state; - } - - const currentStudy = this.getCurrentStudy(); - if (currentStudy && currentStudy.getUuid() === studyId) { - currentStudy.setState(state); - } - - this.fireDataEvent("studyStateChanged", { - studyId, - state, - }); - }, - - setStudyDebt: function(studyId, debt) { - // init object if it does not exist - if (this.__studiesInDebt === null) { - this.__studiesInDebt = {}; - } - if (debt) { - this.__studiesInDebt[studyId] = debt; - } else { - delete this.__studiesInDebt[studyId]; - } - - const studiesWStateCache = this.getStudies(); - const idx = studiesWStateCache.findIndex(studyWStateCache => studyWStateCache["uuid"] === studyId); - if (idx !== -1) { - if (debt) { - studiesWStateCache[idx]["debt"] = debt; - } else { - delete studiesWStateCache[idx]["debt"]; - } - } - - this.fireDataEvent("studyDebtChanged", { - studyId, - debt, - }); - }, - - getStudyDebt: function(studyId) { - if (this.__studiesInDebt && studyId in this.__studiesInDebt) { - return this.__studiesInDebt[studyId]; - } - return null; - }, - - isStudyInDebt: function(studyId) { - return Boolean(this.getStudyDebt(studyId)); - }, - reloadCreditPrice: function() { const store = osparc.store.Store.getInstance(); store.setCreditPrice(null); diff --git a/services/static-webserver/client/source/class/osparc/store/Study.js b/services/static-webserver/client/source/class/osparc/store/Study.js index bf656ad2b36..8e565ebf7df 100644 --- a/services/static-webserver/client/source/class/osparc/store/Study.js +++ b/services/static-webserver/client/source/class/osparc/store/Study.js @@ -19,9 +19,19 @@ qx.Class.define("osparc.store.Study", { extend: qx.core.Object, type: "singleton", + events: { + "studyStateChanged": "qx.event.type.Data", + "studyDebtChanged": "qx.event.type.Data", + }, + members: { __nodeResources: null, __nodePricingUnit: null, + __studiesInDebt: null, + + invalidateStudies: function() { + osparc.store.Store.getInstance().invalidate("studies"); + }, getPage: function(params, options) { return osparc.data.Resources.fetch("studies", "getPage", params, options) @@ -53,6 +63,65 @@ qx.Class.define("osparc.store.Study", { return osparc.data.Resources.fetch("studies", "getOne", params) }, + openStudy: function(studyId, autoStart = true) { + const params = { + url: { + studyId, + }, + data: osparc.utils.Utils.getClientSessionID() + }; + if (autoStart) { + return osparc.data.Resources.fetch("studies", "open", params); + } + params["url"]["disableServiceAutoStart"] = true; + return osparc.data.Resources.fetch("studies", "openDisableAutoStart", params); + }, + + closeStudy: function(studyId) { + const params = { + url: { + studyId, + }, + data: osparc.utils.Utils.getClientSessionID() + }; + return osparc.data.Resources.fetch("studies", "close", params); + }, + + createStudy: function(studyData) { + const params = { + data: studyData + }; + const options = { + pollTask: true, + }; + return osparc.data.Resources.fetch("studies", "postNewStudy", params, options); + }, + + createStudyFromTemplate: function(templateId, studyData) { + const params = { + url: { + templateId, + }, + data: studyData + }; + const options = { + pollTask: true, + }; + return osparc.data.Resources.fetch("studies", "postNewStudyFromTemplate", params, options); + }, + + duplicateStudy: function(studyId) { + const params = { + url: { + studyId, + } + }; + const options = { + pollTask: true + }; + return osparc.data.Resources.fetch("studies", "duplicate", params, options); + }, + deleteStudy: function(studyId) { const params = { url: { @@ -96,10 +165,7 @@ qx.Class.define("osparc.store.Study", { }, patchTemplateType: function(templateId, templateType) { - const patchData = { - "templateType": templateType, - }; - return this.patchStudy(templateId, patchData); + return this.patchStudyData(templateId, "templateType", templateType); }, updateMetadata: function(studyId, metadata) { @@ -112,6 +178,86 @@ qx.Class.define("osparc.store.Study", { return osparc.data.Resources.fetch("studies", "updateMetadata", params); }, + getStudyState: function(studyId) { + osparc.data.Resources.fetch("studies", "state", { + url: { + "studyId": studyId + } + }) + .then(({state}) => { + this.setStudyState(studyId, state); + }); + }, + + setStudyState: function(studyId, state) { + const studiesWStateCache = osparc.store.Store.getInstance().getStudies(); + const idx = studiesWStateCache.findIndex(studyWStateCache => studyWStateCache["uuid"] === studyId); + if (idx !== -1) { + studiesWStateCache[idx]["state"] = state; + } + + const currentStudy = osparc.store.Store.getInstance().getCurrentStudy(); + if (currentStudy && currentStudy.getUuid() === studyId) { + currentStudy.setState(state); + } + + this.fireDataEvent("studyStateChanged", { + studyId, + state, + }); + }, + + setStudyDebt: function(studyId, debt) { + // init object if it does not exist + if (this.__studiesInDebt === null) { + this.__studiesInDebt = {}; + } + if (debt) { + this.__studiesInDebt[studyId] = debt; + } else { + delete this.__studiesInDebt[studyId]; + } + + const studiesWStateCache = osparc.store.Store.getInstance().getStudies(); + const idx = studiesWStateCache.findIndex(studyWStateCache => studyWStateCache["uuid"] === studyId); + if (idx !== -1) { + if (debt) { + studiesWStateCache[idx]["debt"] = debt; + } else { + delete studiesWStateCache[idx]["debt"]; + } + } + + this.fireDataEvent("studyDebtChanged", { + studyId, + debt, + }); + }, + + getStudyDebt: function(studyId) { + if (this.__studiesInDebt && studyId in this.__studiesInDebt) { + return this.__studiesInDebt[studyId]; + } + return null; + }, + + isStudyInDebt: function(studyId) { + return Boolean(this.getStudyDebt(studyId)); + }, + + payDebt: function(studyId, walletId, amount) { + const params = { + url: { + studyId, + walletId, + }, + data: { + amount, + } + }; + return osparc.data.Resources.fetch("studies", "payDebt", params); + }, + trashStudy: function(studyId) { const params = { url: { diff --git a/services/static-webserver/client/source/class/osparc/store/Templates.js b/services/static-webserver/client/source/class/osparc/store/Templates.js index b07e916b21a..62d90bd6400 100644 --- a/services/static-webserver/client/source/class/osparc/store/Templates.js +++ b/services/static-webserver/client/source/class/osparc/store/Templates.js @@ -24,6 +24,20 @@ qx.Class.define("osparc.store.Templates", { __hypertools: null, __hypertoolsPromiseCached: null, + createTemplate: function(studyId, copyData = true, hidden = false) { + const params = { + url: { + "study_id": studyId, + "copy_data": copyData, + hidden, + }, + }; + const options = { + pollTask: true + }; + return osparc.data.Resources.fetch("templates", "postToTemplate", params, options); + }, + fetchTemplatesPaginated: function(params, options) { params["url"]["templateType"] = osparc.data.model.StudyUI.TEMPLATE_TYPE; return osparc.data.Resources.fetch("templates", "getPageFilteredSorted", params, options) diff --git a/services/static-webserver/client/source/class/osparc/study/BillingSettings.js b/services/static-webserver/client/source/class/osparc/study/BillingSettings.js index 0964bf07de4..4a8ae8fe604 100644 --- a/services/static-webserver/client/source/class/osparc/study/BillingSettings.js +++ b/services/static-webserver/client/source/class/osparc/study/BillingSettings.js @@ -238,16 +238,7 @@ qx.Class.define("osparc.study.BillingSettings", { __doTransferCredits: function() { const wallet = this.__getSelectedWallet(); - const params = { - url: { - studyId: this.__studyData["uuid"], - walletId: wallet.getWalletId(), - }, - data: { - amount: this.__studyData["debt"], - } - }; - osparc.data.Resources.fetch("studies", "payDebt", params) + osparc.store.Study.getInstance().payDebt(this.__studyData["uuid"], wallet.getWalletId(), this.__studyData["debt"]) .then(() => { // at this point we can assume that the study got unblocked this.__debtPayed(); @@ -259,7 +250,7 @@ qx.Class.define("osparc.study.BillingSettings", { __debtPayed: function() { delete this.__studyData["debt"]; - osparc.store.Store.getInstance().setStudyDebt(this.__studyData["uuid"], 0); + osparc.store.Study.getInstance().setStudyDebt(this.__studyData["uuid"], 0); this.fireEvent("debtPayed"); if (this.__debtMessage) { this._remove(this.__debtMessage); diff --git a/services/static-webserver/client/source/class/osparc/study/CreateFunction.js b/services/static-webserver/client/source/class/osparc/study/CreateFunction.js index 7dee8e3593f..0c409af43d2 100644 --- a/services/static-webserver/client/source/class/osparc/study/CreateFunction.js +++ b/services/static-webserver/client/source/class/osparc/study/CreateFunction.js @@ -303,19 +303,11 @@ qx.Class.define("osparc.study.CreateFunction", { this.__createFunctionBtn.setFetching(true); // first publish it as a hidden template - const params = { - url: { - "study_id": this.__studyData["uuid"], - "copy_data": true, - "hidden": true, - }, - }; - const options = { - pollTask: true - }; - const fetchPromise = osparc.data.Resources.fetch("studies", "postToTemplate", params, options); + const copyData = true; + const hidden = true; + const pollPromise = osparc.store.Templates.createTemplate(this.__studyData["uuid"], copyData, hidden); const pollTasks = osparc.store.PollTasks.getInstance(); - pollTasks.createPollingTask(fetchPromise) + pollTasks.createPollingTask(pollPromise) .then(task => { task.addListener("resultReceived", e => { const templateData = e.getData(); diff --git a/services/static-webserver/client/source/class/osparc/study/Utils.js b/services/static-webserver/client/source/class/osparc/study/Utils.js index cea7487aa43..7b6fae32fbf 100644 --- a/services/static-webserver/client/source/class/osparc/study/Utils.js +++ b/services/static-webserver/client/source/class/osparc/study/Utils.js @@ -71,10 +71,7 @@ qx.Class.define("osparc.study.Utils", { }); return; } - const params = { - data: minStudyData - }; - osparc.study.Utils.createStudyAndPoll(params) + osparc.study.Utils.createStudyAndPoll(minStudyData) .then(studyData => resolve(studyData["uuid"])) .catch(err => reject(err)); }) @@ -82,15 +79,12 @@ qx.Class.define("osparc.study.Utils", { }); }, - createStudyAndPoll: function(params) { + createStudyAndPoll: function(studyData) { return new Promise((resolve, reject) => { - const options = { - pollTask: true - }; - const fetchPromise = osparc.data.Resources.fetch("studies", "postNewStudy", params, options); + const pollPromise = osparc.store.Study.getInstance().createStudy(studyData); const pollTasks = osparc.store.PollTasks.getInstance(); const interval = 1000; - pollTasks.createPollingTask(fetchPromise, interval) + pollTasks.createPollingTask(pollPromise, interval) .then(task => { task.addListener("resultReceived", e => { const resultData = e.getData(); @@ -122,19 +116,10 @@ qx.Class.define("osparc.study.Utils", { minStudyData["name"] = templateData["name"]; minStudyData["description"] = templateData["description"]; minStudyData["thumbnail"] = templateData["thumbnail"]; - const params = { - url: { - templateId: templateData["uuid"] - }, - data: minStudyData - }; - const options = { - pollTask: true - }; - const fetchPromise = osparc.data.Resources.fetch("studies", "postNewStudyFromTemplate", params, options); + const pollPromise = osparc.store.Study.getInstance().createStudyFromTemplate(templateData["uuid"], minStudyData); const pollTasks = osparc.store.PollTasks.getInstance(); const interval = 1000; - pollTasks.createPollingTask(fetchPromise, interval) + pollTasks.createPollingTask(pollPromise, interval) .then(task => { const title = qx.locale.Manager.tr("CREATING ") + osparc.product.Utils.getStudyAlias({allUpperCase: true}) + " ..."; const progressSequence = new osparc.widget.ProgressSequence(title).set({ @@ -191,17 +176,9 @@ qx.Class.define("osparc.study.Utils", { const text = qx.locale.Manager.tr("Duplicate process started and added to the background tasks"); osparc.FlashMessenger.logAs(text, "INFO"); - const params = { - url: { - "studyId": studyData["uuid"] - } - }; - const options = { - pollTask: true - }; - const fetchPromise = osparc.data.Resources.fetch("studies", "duplicate", params, options); + const pollPromise = osparc.store.Study.getInstance().duplicateStudy(studyData["uuid"]); const pollTasks = osparc.store.PollTasks.getInstance(); - return pollTasks.createPollingTask(fetchPromise) + return pollTasks.createPollingTask(pollPromise) }, createTemplateTypeSB: function() { @@ -368,7 +345,7 @@ qx.Class.define("osparc.study.Utils", { }, isInDebt: function(studyData) { - return osparc.store.Store.getInstance().isStudyInDebt(studyData["uuid"]); + return osparc.store.Study.getInstance().isStudyInDebt(studyData["uuid"]); }, extractDebtFromError: function(studyId, err) { @@ -385,7 +362,7 @@ qx.Class.define("osparc.study.Utils", { } if (debt) { // if get here, it means that the 402 was thrown due to the debt - osparc.store.Store.getInstance().setStudyDebt(studyId, debt); + osparc.store.Study.getInstance().setStudyDebt(studyId, debt); } return debt; }, diff --git a/services/static-webserver/client/source/class/osparc/viewer/NodeViewer.js b/services/static-webserver/client/source/class/osparc/viewer/NodeViewer.js index 2596b4b1dbc..19cae15dd0f 100644 --- a/services/static-webserver/client/source/class/osparc/viewer/NodeViewer.js +++ b/services/static-webserver/client/source/class/osparc/viewer/NodeViewer.js @@ -25,13 +25,7 @@ qx.Class.define("osparc.viewer.NodeViewer", { this._setLayout(new qx.ui.layout.VBox()); - const params = { - url: { - studyId - }, - data: osparc.utils.Utils.getClientSessionID() - }; - osparc.data.Resources.fetch("studies", "open", params) + osparc.store.Study.getInstance().openStudy(studyId) .then(studyData => { // create study const study = new osparc.data.model.Study(studyData);