diff --git a/Platform/UI/Canvas.js b/Platform/UI/Canvas.js index 7a2d09b74..459e3e675 100644 --- a/Platform/UI/Canvas.js +++ b/Platform/UI/Canvas.js @@ -56,6 +56,7 @@ function newCanvas() { UI.projects.foundations.spaces.sideSpace.finalize() UI.projects.foundations.spaces.chartingSpace.finalize() UI.projects.foundations.spaces.floatingSpace.finalize() + UI.projects.foundations.spaces.codeEditorSpace.finalize() thisObject.shorcutNumbers = undefined if (browserCanvas.removeEventListener) { @@ -385,6 +386,11 @@ function newCanvas() { if (UI.projects.education !== undefined && UI.projects.education.spaces.docsSpace.isVisible === true) { return } + /* When the Code Editor is Visible, we do not process key down events of the Designer Space. */ + if (UI.projects.foundations.spaces.codeEditorSpace.isVisible === true) { + return + } + thisObject.mouse.event = event thisObject.mouse.action = 'key down' diff --git a/Platform/WebServer/index.html b/Platform/WebServer/index.html index 0925c901c..8eeeb113a 100644 --- a/Platform/WebServer/index.html +++ b/Platform/WebServer/index.html @@ -140,7 +140,7 @@
-
+
diff --git a/Projects/Foundations/Schemas/Docs-Nodes/J/Javascript/Javascript-Code/javascript-code.json b/Projects/Foundations/Schemas/Docs-Nodes/J/Javascript/Javascript-Code/javascript-code.json index 7fc0bd214..ee231c69c 100644 --- a/Projects/Foundations/Schemas/Docs-Nodes/J/Javascript/Javascript-Code/javascript-code.json +++ b/Projects/Foundations/Schemas/Docs-Nodes/J/Javascript/Javascript-Code/javascript-code.json @@ -11,10 +11,6 @@ { "style": "Text", "text": "The system allows developers great flexibility as all valid JavaScript code is allowed." - }, - { - "style": "Important", - "text": "Until a robust JavaScript editor is implemented on the UI, it is recommended to write code on an external editor and paste it in the UI code bubble to ensure consistency." } ] } \ No newline at end of file diff --git a/Projects/Foundations/Schemas/Docs-Nodes/P/Procedure/Procedure-Javascript-Code/procedure-javascript-code.json b/Projects/Foundations/Schemas/Docs-Nodes/P/Procedure/Procedure-Javascript-Code/procedure-javascript-code.json index 1c76c451b..f1f72fe92 100644 --- a/Projects/Foundations/Schemas/Docs-Nodes/P/Procedure/Procedure-Javascript-Code/procedure-javascript-code.json +++ b/Projects/Foundations/Schemas/Docs-Nodes/P/Procedure/Procedure-Javascript-Code/procedure-javascript-code.json @@ -9,11 +9,6 @@ "style": "Text", "text": "The system allows developers great flexibility as all valid JavaScript code is allowed.", "updated": 1609789473533 - }, - { - "style": "Important", - "text": "Until a robust JavaScript editor is implemented on the UI, it is recommended to write code on an external editor and paste it in the UI code bubble to ensure consistency.", - "updated": 1609789526505 } ] } \ No newline at end of file diff --git a/Projects/Foundations/UI/Spaces/CodeEditor-Space/CodeEditorSpace.js b/Projects/Foundations/UI/Spaces/CodeEditor-Space/CodeEditorSpace.js index 71362e847..88e678a51 100644 --- a/Projects/Foundations/UI/Spaces/CodeEditor-Space/CodeEditorSpace.js +++ b/Projects/Foundations/UI/Spaces/CodeEditor-Space/CodeEditorSpace.js @@ -5,6 +5,8 @@ function newFoundationsCodeEditorSpace() { sidePanelTab: undefined, container: undefined, editorPage: undefined, + isVisible: undefined, + reset: reset, openSpaceArea: openSpaceArea, physics: physics, draw: draw, @@ -23,15 +25,24 @@ function newFoundationsCodeEditorSpace() { return thisObject function finalize() { - thisObject.sidePanelTab = undefined + if (isInitialized === false) { return } + + thisObject.container.finalize() + thisObject.container = undefined + canvas.eventHandler.stopListening(browserResizedEventSubscriptionId) thisObject.sidePanelTab.container.eventHandler.stopListening(openingEventSubscriptionId) thisObject.sidePanelTab.container.eventHandler.stopListening(closingEventSubscriptionId) + UI.projects.foundations.spaces.sideSpace.deleteSidePanelTab('Foundations', 'javascript-code', 'Code', 'right') + + thisObject.editorPage.finalize() + thisObject.editorPage = undefined + + isInitialized = false } function initialize() { - thisObject.container = newContainer() thisObject.container.name = MODULE_NAME thisObject.container.initialize() @@ -43,10 +54,7 @@ function newFoundationsCodeEditorSpace() { resize() thisObject.editorPage = newFoundationsCodeEditorEditorPage() - thisObject.footer = newGovernanceReportsFooter() // Reuse simple footer - thisObject.editorPage.initialize() - thisObject.footer.initialize() thisObject.sidePanelTab = UI.projects.foundations.spaces.sideSpace.createSidePanelTab(thisObject.container, 'Foundations', 'javascript-code', 'Code', 'right') @@ -66,6 +74,11 @@ function newFoundationsCodeEditorSpace() { thisObject.editorPage.render(originatingNode, codeEditorType) } + function reset() { + finalize() + initialize() + } + function physics() { if (isInitialized === false) { return @@ -92,11 +105,11 @@ function newFoundationsCodeEditorSpace() { } function onOpening() { - + thisObject.isVisible = true } function onClosing() { - + thisObject.isVisible = false } function draw() { diff --git a/Projects/Foundations/UI/Spaces/CodeEditor-Space/EditorPage.js b/Projects/Foundations/UI/Spaces/CodeEditor-Space/EditorPage.js index 4198e3782..4408e4ed2 100644 --- a/Projects/Foundations/UI/Spaces/CodeEditor-Space/EditorPage.js +++ b/Projects/Foundations/UI/Spaces/CodeEditor-Space/EditorPage.js @@ -3,6 +3,7 @@ function newFoundationsCodeEditorEditorPage() { originatingNode: undefined, editorType: undefined, render: render, + reset:reset, initialize: initialize, finalize: finalize } @@ -10,9 +11,10 @@ function newFoundationsCodeEditorEditorPage() { let monacoInitialized = false let monacoEditor = undefined let codeString = '' + let stringObjects = [] let tradingEngineObj = undefined let recordFormulasObj = {} - let chartObj = {} + let chartMarketExchangeObj = {} return thisObject @@ -27,13 +29,19 @@ function newFoundationsCodeEditorEditorPage() { monacoInitialized = false monacoEditor = undefined codeString = '' + stringObjects = [] tradingEngineObj = undefined recordFormulasObj = {} + chartMarketExchangeObj = {} thisObject.originatingNode = undefined thisObject.editorType = undefined } + function reset() { + finalize() + initialize() + } function render(originatingNode, editorType) { @@ -56,7 +64,7 @@ function newFoundationsCodeEditorEditorPage() { function initMonacoEditor() { if (monacoEditor === undefined) { document.getElementById('no-content').remove() - document.getElementById('code-path').insertAdjacentHTML('afterend',`
Notes: Changes are saved automatically
`) + document.getElementById('code-path').insertAdjacentHTML('afterend', `
Notes: Changes are saved automatically
`) monacoEditor = monaco.editor.create(document.querySelector('#editor'), { model: null, theme: 'vs-dark', @@ -67,7 +75,7 @@ function newFoundationsCodeEditorEditorPage() { monaco.editor.createModel(codeString, "javascript") createAutocompletionFor(tradingEngineObj) createAutocompletionFor(recordFormulasObj) - createAutocompletionFor(chartObj) + createAutocompletionFor(chartMarketExchangeObj) monaco.languages.typescript.javascriptDefaults.setEagerModelSync(true) monaco.languages.typescript.javascriptDefaults.setCompilerOptions({ @@ -116,7 +124,7 @@ function newFoundationsCodeEditorEditorPage() { return (isMember) ? monaco.languages.CompletionItemKind.Method : monaco.languages.CompletionItemKind.Function; default: - return (isMember) ? monaco.languages.CompletionItemKind.Property : monaco.languages.CompletionItemKind.Variable; + return monaco.languages.CompletionItemKind.Variable; } } @@ -167,7 +175,6 @@ function newFoundationsCodeEditorEditorPage() { return result[0] = ''; } } - prefix += '.'; } // Get all the child properties of the last token @@ -212,13 +219,19 @@ function newFoundationsCodeEditorEditorPage() { /** * The autocomplete models will be based on: * 1. Existing code in the data mines -> we will create models for each code node (it's like opening multiple files in vscode) - * 2. Formulas from data mines by creating an object representation of all formulas see implementation below than passing it to the monaco registerCompletionItemProvider + * 2. Formulas from data mines by creating an object representation of all formulas see implementation below then passing it to the monaco registerCompletionItemProvider * 2. Trading engine loaded into the workspace - we create an obj. representation using getProtocolNode and we are using monaco registerCompletionItemProvider * */ function buildIntelliSenseModels() { + let chartObjectPrefix = 'chart.' + let marketPrefix = 'market.' + let exchangePrefix = 'exchange.' + let dot = '.' + let numberOfPreviousSuffixes = 5 + UI.projects.foundations.spaces.designSpace.workspace.workspaceNode.rootNodes.forEach(node => { if (node.type === 'Data Mine') { // Getting all the Javascript code nodes into one single model @@ -266,19 +279,13 @@ function newFoundationsCodeEditorEditorPage() { let validTimeFrames = UI.projects.visualScripting.utilities.nodeConfig.loadConfigProperty(dataset.payload, 'validTimeFrames') if (validTimeFrames !== undefined) { validTimeFrames.forEach(tf => { - let prop = 'chart.at' + tf.replace('-', '') + '.' + productName + '.' + propertyName - // This will let us to enhance the autocomplete logic to add as many previous kids as we want to - let propWithPrevious = 'chart.at' + tf.replace('-', '') + '.previous.' + productName + '.' + propertyName - let propWithTwoPrevious = 'chart.at' + tf.replace('-', '') + '.previous.previous.' + productName + '.' + propertyName - let propWithThreePrevious = 'chart.at' + tf.replace('-', '') + '.previous.previous.previous.' + productName + '.' + propertyName - let propWithFourPrevious = 'chart.at' + tf.replace('-', '') + '.previous.previous.previous.previous.' + productName + '.' + propertyName - let propWithFivePrevious = 'chart.at' + tf.replace('-', '') + '.previous.previous.previous.previous.previous.' + productName + '.' + propertyName - objectMerge(chartObj, prop.split('.').reduceRight((o, x) => ({[x]: o}), "")) - objectMerge(chartObj, propWithPrevious.split('.').reduceRight((o, x) => ({[x]: o}), "")) - objectMerge(chartObj, propWithTwoPrevious.split('.').reduceRight((o, x) => ({[x]: o}), "")) - objectMerge(chartObj, propWithThreePrevious.split('.').reduceRight((o, x) => ({[x]: o}), "")) - objectMerge(chartObj, propWithFourPrevious.split('.').reduceRight((o, x) => ({[x]: o}), "")) - objectMerge(chartObj, propWithFivePrevious.split('.').reduceRight((o, x) => ({[x]: o}), "")) + let timeFrame = 'at' + tf.replace('-', '') + + stringObjects.push(chartObjectPrefix + timeFrame + '.' + productName + '.' + propertyName) + for (let i = 1; i <= numberOfPreviousSuffixes; i++) { + stringObjects.push(chartObjectPrefix + timeFrame + getPreviousSuffixTimes(i) + productName + dot + propertyName) + } + }) } }) @@ -318,6 +325,36 @@ function newFoundationsCodeEditorEditorPage() { } }) + // Enrich chart data with market and exchange structure + UI.projects.foundations.spaces.designSpace.workspace.workspaceNode.rootNodes.forEach(node => { + if (node.type === 'Crypto Ecosystem') { + node.cryptoExchanges.forEach(cxs => { + cxs.exchanges.forEach(exchange => { + let exchangeName = UI.projects.visualScripting.utilities.nodeConfig.loadConfigProperty(exchange.payload, 'codeName') + exchange.exchangeMarkets.markets.forEach(market => { + let marketPair = UI.projects.visualScripting.utilities.nodeConfig.loadConfigProperty(market.payload, 'codeName') + let baseAsset = marketPair.split('/')[0] + let quotedAsset = marketPair.split('/')[1] + stringObjects.forEach(chartObj => { + /** + * We will provide auto-complete only for assets pair found in Markets + * Doing so we will avoid providing completion for assets that are not used in a market + */ + let market = marketPrefix + baseAsset + dot + quotedAsset + dot + chartObj + stringObjects.push(market) + stringObjects.push(exchangePrefix + exchangeName + dot + market) + }) + }) + }) + }) + } + }) + + //Actually building the objects for chart, market and exchange, no need for multiple objects, as one is enough for the autocomplete to work + stringObjects.forEach(stringRepresentation => { + objectMerge(chartMarketExchangeObj, stringRepresentation.split('.').reduceRight((o, x) => ({[x]: o}), "")) + }) + function objectMerge(target, source) { for (const key of Object.keys(source)) { @@ -340,6 +377,20 @@ function newFoundationsCodeEditorEditorPage() { return target; } + function getPreviousSuffixTimes(number) { + let result = '' + let previousString = 'previous.' + let dotString = '.' + for (let i = 0; i < number; i++) { + if (i === 0) { + result += dotString + } + result += previousString + } + + return result + } + } function buildEditorHTML() { @@ -363,7 +414,7 @@ function newFoundationsCodeEditorEditorPage() { function footer() { let HTML = '' - HTML += HTML + '