diff --git a/Client/httpInterface.js b/Client/httpInterface.js index 4be06f6f9..d9bdeb903 100644 --- a/Client/httpInterface.js +++ b/Client/httpInterface.js @@ -313,34 +313,8 @@ exports.newHttpInterface = function newHttpInterface(WEB_SERVER, DATA_FILE_SERVE let project = requestParameters[3] let filePath = global.env.PATH_TO_PROJECTS + '/' + project + '/Schemas/Docs-Nodes' - const fs = require('fs') - fs.rmdir(filePath, { recursive: true }, onDirDeleted) - - function onDirDeleted(err) { - if (err && err.code === 'EBUSY') { - throw ('Can not delete the folder ' + filePath + ' because a file in it is open by some other program.') - } - try { - fs.mkdirSync(filePath) - } catch (err) { - if (err.code !== 'EEXIST') { - throw (err) - } - } - - for (let i = 0; i < docsSchema.length; i++) { - let schemaDocument = docsSchema[i] - let fileContent = JSON.stringify(schemaDocument, undefined, 4) - let fileName = schemaDocument.type.toLowerCase() - for (let j = 0; j < 10; j++) { - fileName = cleanFileName(fileName) - } - fileName = fileName + '.json' - - fs.writeFileSync(filePath + '/' + fileName, fileContent) - } - respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) - } + checkAllSchmemaDocuments(docsSchema, filePath) + respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) } catch (err) { console.log('[ERROR] httpInterface -> Docs -> Save-Node-Schema -> Method call produced an error.') @@ -366,32 +340,8 @@ exports.newHttpInterface = function newHttpInterface(WEB_SERVER, DATA_FILE_SERVE let project = requestParameters[3] let filePath = global.env.PATH_TO_PROJECTS + '/' + project + '/Schemas/Docs-Concepts' - const fs = require('fs') - fs.rmdir(filePath, { recursive: true }, onDirDeleted) - - function onDirDeleted(err) { - if (err && err.code === 'EBUSY') { - throw ('Can not delete the folder ' + filePath + ' because a file in it is open by some other program.') - } - try { - fs.mkdirSync(filePath) - } catch (err) { - if (err.code !== 'EEXIST') { - throw (err) - } - } - - for (let i = 0; i < docsSchema.length; i++) { - let schemaDocument = docsSchema[i] - let fileContent = JSON.stringify(schemaDocument, undefined, 4) - let fileName = schemaDocument.type.toLowerCase() - fileName = cleanFileName(fileName) - fileName = fileName + '.json' - - fs.writeFileSync(filePath + '/' + fileName, fileContent) - } - respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) - } + checkAllSchmemaDocuments(docsSchema, filePath) + respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) } catch (err) { console.log('[ERROR] httpInterface -> Docs -> Save-Concept-Schema -> Method call produced an error.') @@ -417,33 +367,8 @@ exports.newHttpInterface = function newHttpInterface(WEB_SERVER, DATA_FILE_SERVE let project = requestParameters[3] let filePath = global.env.PATH_TO_PROJECTS + '/' + project + '/Schemas/Docs-Topics' - const fs = require('fs') - fs.rmdir(filePath, { recursive: true }, onDirDeleted) - - function onDirDeleted(err) { - if (err && err.code === 'EBUSY') { - throw ('Can not delete the folder ' + filePath + ' because a file in it is open by some other program.') - } - try { - fs.mkdirSync(filePath) - } catch (err) { - if (err.code !== 'EEXIST') { - throw (err) - } - } - - for (let i = 0; i < docsSchema.length; i++) { - let schemaDocument = docsSchema[i] - let fileContent = JSON.stringify(schemaDocument, undefined, 4) - let pageNumber = '00' + schemaDocument.pageNumber - let fileName = schemaDocument.topic.toLowerCase() + '-' + pageNumber.substring(pageNumber.length - 3, pageNumber.length) + '-' + schemaDocument.type.toLowerCase() - fileName = cleanFileName(fileName) - fileName = fileName + '.json' - - fs.writeFileSync(filePath + '/' + fileName, fileContent) - } - respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) - } + checkAllSchmemaDocuments(docsSchema, filePath) + respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) } catch (err) { console.log('[ERROR] httpInterface -> Docs -> Save-Topic-Schema -> Method call produced an error.') @@ -469,33 +394,8 @@ exports.newHttpInterface = function newHttpInterface(WEB_SERVER, DATA_FILE_SERVE let project = requestParameters[3] let filePath = global.env.PATH_TO_PROJECTS + '/' + project + '/Schemas/Docs-Tutorials' - const fs = require('fs') - fs.rmdir(filePath, { recursive: true }, onDirDeleted) - - function onDirDeleted(err) { - if (err && err.code === 'EBUSY') { - throw ('Can not delete the folder ' + filePath + ' because a file in it is open by some other program.') - } - try { - fs.mkdirSync(filePath) - } catch (err) { - if (err.code !== 'EEXIST') { - throw (err) - } - } - - for (let i = 0; i < docsSchema.length; i++) { - let schemaDocument = docsSchema[i] - let fileContent = JSON.stringify(schemaDocument, undefined, 4) - let pageNumber = '00' + schemaDocument.pageNumber - let fileName = schemaDocument.tutorial.toLowerCase() + '-' + pageNumber.substring(pageNumber.length - 3, pageNumber.length) + '-' + schemaDocument.type.toLowerCase() - fileName = cleanFileName(fileName) - fileName = fileName + '.json' - - fs.writeFileSync(filePath + '/' + fileName, fileContent) - } - respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) - } + checkAllSchmemaDocuments(docsSchema, filePath) + respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) } catch (err) { console.log('[ERROR] httpInterface -> Docs -> Save-Tutorial-Schema -> Method call produced an error.') @@ -521,32 +421,8 @@ exports.newHttpInterface = function newHttpInterface(WEB_SERVER, DATA_FILE_SERVE let project = requestParameters[3] let filePath = global.env.PATH_TO_PROJECTS + '/' + project + '/Schemas/Docs-Books' - const fs = require('fs') - fs.rmdir(filePath, { recursive: true }, onDirDeleted) - - function onDirDeleted(err) { - if (err && err.code === 'EBUSY') { - throw ('Can not delete the folder ' + filePath + ' because a file in it is open by some other program.') - } - try { - fs.mkdirSync(filePath) - } catch (err) { - if (err.code !== 'EEXIST') { - throw (err) - } - } - - for (let i = 0; i < docsSchema.length; i++) { - let schemaDocument = docsSchema[i] - let fileContent = JSON.stringify(schemaDocument, undefined, 4) - let fileName = schemaDocument.type.toLowerCase() - fileName = cleanFileName(fileName) - fileName = fileName + '.json' - - fs.writeFileSync(filePath + '/' + fileName, fileContent) - } - respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) - } + checkAllSchmemaDocuments(docsSchema, filePath) + respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) } catch (err) { console.log('[ERROR] httpInterface -> Docs -> Save-Book-Schema -> Method call produced an error.') @@ -564,6 +440,45 @@ exports.newHttpInterface = function newHttpInterface(WEB_SERVER, DATA_FILE_SERVE break } } + + function checkAllSchmemaDocuments(docsSchema, filePath) { + const fs = require('fs') + + for (let i = 0; i < docsSchema.length; i++) { + let schemaDocument = docsSchema[i] + let fileName = schemaDocument.type.toLowerCase() + for (let j = 0; j < 10; j++) { + fileName = cleanFileName(fileName) + } + fileName = fileName + '.json' + + if (schemaDocument.deleted === true) { + try { + fs.unlinkSync(filePath + '/' + fileName) + console.log('[SUCCESS] ' + filePath + '/' + fileName + ' deleted.') + } catch (err) { + console.log('[ERROR] httpInterface -> Docs -> Save -> ' + filePath + '/' + fileName + ' could not be deleted.') + console.log('[ERROR] httpInterface -> Docs -> Save -> Resolve the issue that is preventing the Client to delete this file. Look at the error message below as a guide. At the UI you will need to delete this page again in order for the Client to retry next time you execute the docs.save command.') + console.log('[ERROR] httpInterface -> Docs -> Save -> err.stack = ' + err.stack) + } + } else { + if (schemaDocument.updated === true || schemaDocument.created === true) { + try { + schemaDocument.updated = undefined + schemaDocument.created = undefined + let fileContent = JSON.stringify(schemaDocument, undefined, 4) + fs.writeFileSync(filePath + '/' + fileName, fileContent) + console.log('[SUCCESS] ' + filePath + '/' + fileName + ' updated.') + } catch (err) { + console.log('[ERROR] httpInterface -> Docs -> Save -> ' + filePath + '/' + fileName + ' could not be created / updated.') + console.log('[ERROR] httpInterface -> Docs -> Save -> Dont worry, the changes are still at the UI, but you will need to do 2 things: 1) Resolve the issue that is preventing the Client to write this file. Look at the error message below as a guide. 2) At the UI, locate this page and edit it with some small change again, so that is flagged that contains changes, otherwise those original changes will be ignored by the Client during the next docs.save command execution.') + console.log('[ERROR] httpInterface -> Docs -> Save -> err.stack = ' + err.stack) + } + } + } + } + } + function cleanFileName(fileName) { for (let i = 0; i < 10; i++) { fileName = fileName diff --git a/Projects/Superalgos/Schemas/Docs-Topics/docs-message-deleting-succeed.json b/Projects/Superalgos/Schemas/Docs-Topics/docs-message-deleting-succeed.json new file mode 100644 index 000000000..3beb3d0cd --- /dev/null +++ b/Projects/Superalgos/Schemas/Docs-Topics/docs-message-deleting-succeed.json @@ -0,0 +1,16 @@ +{ + "topic": "Docs Commands Messages", + "pageNumber": "3", + "type": "Docs Message Deleting Succeed", + "definition": { + "text": "The docs.delete command you executed successfuly deleted the page you requested.", + "updated": 1610292270590 + }, + "paragraphs": [ + { + "style": "Important", + "text": "The page was flagged to be deleted. It will be removed from the in-memory collection of pages once you run the Docs Save Command. Even after that it will still be indexed at the Docs Search Engine Index. To remove it from the index you need to execute Docs Reindex Command. The Docs Save Command will instruct the Client to delete it from it's disk.", + "updated": 1610292163004 + } + ] +} \ No newline at end of file diff --git a/Projects/Superalgos/UI/Spaces/Docs-Space/CommandInterface.js b/Projects/Superalgos/UI/Spaces/Docs-Space/CommandInterface.js index eca1c8266..4752226e1 100644 --- a/Projects/Superalgos/UI/Spaces/Docs-Space/CommandInterface.js +++ b/Projects/Superalgos/UI/Spaces/Docs-Space/CommandInterface.js @@ -17,7 +17,7 @@ function newSuperalgosDocsCommmandInterface() { } function detectCommands() { - if (detectAppCommands() === true) {return} + if (detectAppCommands() === true) { return } detectDocsCommands() } @@ -56,12 +56,12 @@ function newSuperalgosDocsCommmandInterface() { if (config.token === undefined || config.token === "") { UI.projects.superalgos.spaces.docsSpace.navigateTo('Superalgos', 'Topic', 'App Error Github Credentials Missing', 'Anchor Github Credentials Missing') return true - } + } httpRequest(undefined, 'App/Contribute/' + message + '/' + config.username + '/' + config.token, onResponse) UI.projects.superalgos.spaces.docsSpace.navigateTo('Superalgos', 'Topic', 'App Message Creating Pull Request') - return true + return true function onResponse(err, data) { /* Lets check the result of the call through the http interface */ @@ -376,15 +376,103 @@ function newSuperalgosDocsCommmandInterface() { if (responseCount === requestsSent) { if (responseCount === okResponses) { UI.projects.superalgos.spaces.docsSpace.navigateTo('Superalgos', 'Topic', 'Docs Message Saving Succeed') + afterSaving() } else { UI.projects.superalgos.spaces.docsSpace.navigateTo('Superalgos', 'Topic', 'Docs Error Changes Not Saved', 'Anchor Changes Not Saved') } } } + + function afterSaving() { + /* + Since all the changes where saved, we need to remove the change flags at the different shcema documents. + We also need to remove from the arrays the deleted items. + */ + for (let j = 0; j < PROJECTS_ARRAY.length; j++) { + let project = PROJECTS_ARRAY[j] + let documents + + /* Nodes */ + documents = [] + for (let i = 0; i < SCHEMAS_BY_PROJECT.get(project).array.docsNodeSchema.length; i++) { + docsSchemaDocument = SCHEMAS_BY_PROJECT.get(project).array.docsNodeSchema[i] + docsSchemaDocument.updated = undefined + docsSchemaDocument.created = undefined + + if (docsSchemaDocument.deleted === true) { + SCHEMAS_BY_PROJECT.get(project).map.docsNodeSchema.delete(docsSchemaDocument.type) + } else { + documents.push(docsSchemaDocument) + } + } + SCHEMAS_BY_PROJECT.get(project).array.docsNodeSchema = documents + + /* Concepts */ + documents = [] + for (let i = 0; i < SCHEMAS_BY_PROJECT.get(project).array.docsConceptSchema.length; i++) { + docsSchemaDocument = SCHEMAS_BY_PROJECT.get(project).array.docsConceptSchema[i] + docsSchemaDocument.updated = undefined + docsSchemaDocument.created = undefined + + if (docsSchemaDocument.deleted === true) { + SCHEMAS_BY_PROJECT.get(project).map.docsConceptSchema.delete(docsSchemaDocument.type) + } else { + documents.push(docsSchemaDocument) + } + } + SCHEMAS_BY_PROJECT.get(project).array.docsConceptSchema = documents + + /* Topics */ + documents = [] + for (let i = 0; i < SCHEMAS_BY_PROJECT.get(project).array.docsTopicSchema.length; i++) { + docsSchemaDocument = SCHEMAS_BY_PROJECT.get(project).array.docsTopicSchema[i] + docsSchemaDocument.updated = undefined + docsSchemaDocument.created = undefined + + if (docsSchemaDocument.deleted === true) { + SCHEMAS_BY_PROJECT.get(project).map.docsTopicSchema.delete(docsSchemaDocument.type) + } else { + documents.push(docsSchemaDocument) + } + } + SCHEMAS_BY_PROJECT.get(project).array.docsTopicSchema = documents + + /* Tutorials */ + documents = [] + for (let i = 0; i < SCHEMAS_BY_PROJECT.get(project).array.docsTutorialSchema.length; i++) { + docsSchemaDocument = SCHEMAS_BY_PROJECT.get(project).array.docsTutorialSchema[i] + docsSchemaDocument.updated = undefined + docsSchemaDocument.created = undefined + + if (docsSchemaDocument.deleted === true) { + SCHEMAS_BY_PROJECT.get(project).map.docsTutorialSchema.delete(docsSchemaDocument.type) + } else { + documents.push(docsSchemaDocument) + } + } + SCHEMAS_BY_PROJECT.get(project).array.docsTutorialSchema = documents + + /* Books */ + documents = [] + for (let i = 0; i < SCHEMAS_BY_PROJECT.get(project).array.docsBookSchema.length; i++) { + docsSchemaDocument = SCHEMAS_BY_PROJECT.get(project).array.docsBookSchema[i] + docsSchemaDocument.updated = undefined + docsSchemaDocument.created = undefined + + if (docsSchemaDocument.deleted === true) { + SCHEMAS_BY_PROJECT.get(project).map.docsBookSchema.delete(docsSchemaDocument.type) + } else { + documents.push(docsSchemaDocument) + } + } + SCHEMAS_BY_PROJECT.get(project).array.docsBookSchema = documents + } + } } function addNode(project, type) { let template = { + created: true, type: type, definition: { text: "Write here the definition of this Node." }, paragraphs: [ @@ -411,6 +499,7 @@ function newSuperalgosDocsCommmandInterface() { function addConcept(project, type) { let template = { + created: true, type: type, definition: { text: "Write here the summary / definition of this Concept." }, paragraphs: [ @@ -438,6 +527,7 @@ function newSuperalgosDocsCommmandInterface() { function addTopic(project, topic, type, pageNumber) { let template = { + created: true, topic: topic, pageNumber: pageNumber, type: type, @@ -466,6 +556,7 @@ function newSuperalgosDocsCommmandInterface() { function addTutorial(project, tutorial, type, pageNumber) { let template = { + created: true, tutorial: tutorial, pageNumber: pageNumber, type: type, @@ -494,6 +585,7 @@ function newSuperalgosDocsCommmandInterface() { function addBook(project, type) { let template = { + created: true, type: type, definition: { text: "Write here the summary / definition of this Book." }, paragraphs: [ @@ -530,15 +622,9 @@ function newSuperalgosDocsCommmandInterface() { return } - SCHEMAS_BY_PROJECT.get(project).map.docsNodeSchema.delete(type) + let schemaDocument = SCHEMAS_BY_PROJECT.get(project).map.docsNodeSchema.get(type) + schemaDocument.deleted = true - for (let i = 0; i < SCHEMAS_BY_PROJECT.get(project).array.docsNodeSchema.length; i++) { - docsSchemaDocument = SCHEMAS_BY_PROJECT.get(project).array.docsNodeSchema[i] - if (docsSchemaDocument.type === type) { - docsSchemaDocument = SCHEMAS_BY_PROJECT.get(project).array.docsNodeSchema.splice(i, 1) - break - } - } UI.projects.superalgos.spaces.docsSpace.navigateTo('Superalgos', 'Topic', 'Docs Message Deleting Succeed') } @@ -553,15 +639,9 @@ function newSuperalgosDocsCommmandInterface() { return } - SCHEMAS_BY_PROJECT.get(project).map.docsConceptSchema.delete(type) + let schemaDocument = SCHEMAS_BY_PROJECT.get(project).map.docsConceptSchema.get(type) + schemaDocument.deleted = true - for (let i = 0; i < SCHEMAS_BY_PROJECT.get(project).array.docsConceptSchema.length; i++) { - docsSchemaDocument = SCHEMAS_BY_PROJECT.get(project).array.docsConceptSchema[i] - if (docsSchemaDocument.type === type) { - docsSchemaDocument = SCHEMAS_BY_PROJECT.get(project).array.docsConceptSchema.splice(i, 1) - break - } - } UI.projects.superalgos.spaces.docsSpace.navigateTo('Superalgos', 'Topic', 'Docs Message Deleting Succeed') } @@ -585,15 +665,9 @@ function newSuperalgosDocsCommmandInterface() { } } - SCHEMAS_BY_PROJECT.get(project).map.docsTopicSchema.delete(type) + let schemaDocument = SCHEMAS_BY_PROJECT.get(project).map.docsTopicSchema.get(type) + schemaDocument.deleted = true - for (let i = 0; i < SCHEMAS_BY_PROJECT.get(project).array.docsTopicSchema.length; i++) { - docsSchemaDocument = SCHEMAS_BY_PROJECT.get(project).array.docsTopicSchema[i] - if (docsSchemaDocument.type === type) { - docsSchemaDocument = SCHEMAS_BY_PROJECT.get(project).array.docsTopicSchema.splice(i, 1) - break - } - } UI.projects.superalgos.spaces.docsSpace.navigateTo('Superalgos', 'Topic', 'Docs Message Deleting Succeed') } @@ -617,15 +691,9 @@ function newSuperalgosDocsCommmandInterface() { } } - SCHEMAS_BY_PROJECT.get(project).map.docsTutorialSchema.delete(type) + let schemaDocument = SCHEMAS_BY_PROJECT.get(project).map.docsTutorialSchema.get(type) + schemaDocument.deleted = true - for (let i = 0; i < SCHEMAS_BY_PROJECT.get(project).array.docsTutorialSchema.length; i++) { - docsSchemaDocument = SCHEMAS_BY_PROJECT.get(project).array.docsTutorialSchema[i] - if (docsSchemaDocument.type === type) { - docsSchemaDocument = SCHEMAS_BY_PROJECT.get(project).array.docsTutorialSchema.splice(i, 1) - break - } - } UI.projects.superalgos.spaces.docsSpace.navigateTo('Superalgos', 'Topic', 'Docs Message Deleting Succeed') } @@ -640,15 +708,9 @@ function newSuperalgosDocsCommmandInterface() { return } - SCHEMAS_BY_PROJECT.get(project).map.docsBookSchema.delete(type) + let schemaDocument = SCHEMAS_BY_PROJECT.get(project).map.docsBookSchema.get(type) + schemaDocument.deleted = true - for (let i = 0; i < SCHEMAS_BY_PROJECT.get(project).array.docsBookSchema.length; i++) { - docsSchemaDocument = SCHEMAS_BY_PROJECT.get(project).array.docsBookSchema[i] - if (docsSchemaDocument.type === type) { - docsSchemaDocument = SCHEMAS_BY_PROJECT.get(project).array.docsBookSchema.splice(i, 1) - break - } - } UI.projects.superalgos.spaces.docsSpace.navigateTo('Superalgos', 'Topic', 'Docs Message Deleting Succeed') } } diff --git a/Projects/Superalgos/UI/Spaces/Docs-Space/DocumentPage.js b/Projects/Superalgos/UI/Spaces/Docs-Space/DocumentPage.js index 2aebfe1c8..53436bedf 100644 --- a/Projects/Superalgos/UI/Spaces/Docs-Space/DocumentPage.js +++ b/Projects/Superalgos/UI/Spaces/Docs-Space/DocumentPage.js @@ -137,6 +137,24 @@ function newSuperalgosDocsDocumentPage() { let titleLabel = thisObject.docsSchemaDocument.type HTML = HTML + '

' + titleLabel + '

' + if (thisObject.docsSchemaDocument.deleted === true) { + let key = 'auto-generated-flag-paragraph' + let paragraph = { + style: "Warning", + text: "This page is flagged to be deleted. Next time you execute Docs Save Command this content will be deleted from the Client's disk. If you don't really want to delete this page, the way to avoiding it is by reloading the UI by pressing F5." + } + renderParagraph(paragraph, key) + } else { + if (thisObject.docsSchemaDocument.created === true || thisObject.docsSchemaDocument.updated === true) { + let key = 'auto-generated-flag-paragraph' + let paragraph = { + style: "Important", + text: "This page is flagged to be created / updated. Next time you execute Docs Save Command this content will be saved at the Client's disk. The changes will be applied to the Docs Search Engine Index only after you manually run the Docs Reindex Command." + } + renderParagraph(paragraph, key) + } + } + addDefinitionTable(thisObject.docsSchemaDocument, 'definition-editable-', UI.projects.superalgos.spaces.docsSpace.currentDocumentBeingRendered.category, UI.projects.superalgos.spaces.docsSpace.currentDocumentBeingRendered.project, UI.projects.superalgos.spaces.docsSpace.currentDocumentBeingRendered.type) let editableParagraphIndex = 0 @@ -1849,6 +1867,10 @@ function newSuperalgosDocsDocumentPage() { } function exitEditMode() { + /* This will make the Client to save this in a file overwritting the previous version*/ + thisObject.docsSchemaDocument.updated = true + + /* We will update the paragraph that was being edited*/ let editing if (UI.projects.superalgos.spaces.docsSpace.contextMenu.selectedParagraph.id.indexOf('definition') >= 0) { editing = "Definition"