-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix sorting in dropdown #187
Conversation
src/backend/controllers/pages.ts
Outdated
const pagesGroupedByParent:Record<string, Array<Page>> = {}; | ||
|
||
pages.forEach(page => { | ||
pagesGroupedByParent[String(page._id)] = []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought that _id
is arlady a string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it is but it throws type error without wrapping with String()
since the page._id
is optional.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if _id is optional so there should be a statement checking it for emptiness? The type casting looks unclearly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any chance to create Page
without its _id
property? If it's not the case i think it's better to change its type to required.
Also, do not forget to update the |
I've just opened the page. 🔽 Here is my `pages` list. Maybe it'll help:
|
I should have changed the way of grouping since |
src/backend/models/pageOrder.ts
Outdated
const docs = await this.getAll(); | ||
|
||
return docs.filter(doc => doc.page === '0')[0]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it will be better to filter documents while querying to database instead of using filter method? you can also use findOne
method if you need to find only one document
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
src/backend/models/pageOrder.ts
Outdated
const docs = await this.getAll(); | ||
|
||
return docs.filter(doc => doc.page !== '0'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here we can also filter documents while querying database
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've tested it on a local machine and the server is not responding to any requests.
This is not reproducing at the main
branch.
Can you provide your |
pages.db {"_id":"1dXyeY33VhFTMJ66","title":"Children of the second page","uri":"children-of-the-second-page","body":{"time":1550483562360,"blocks":[{"type":"header","data":{"text":"Children of the second page","level":2}},{"type":"paragraph","data":{"text":"1"}}],"version":"2.7.28"},"parent":"qWeDZ6l18nuiLvac"}
{"_id":"1ePZOPyo4DXjgthK","title":"ad","uri":"ad","body":{"time":1602781859833,"blocks":[{"type":"header","data":{"text":"ad","level":2}},{"type":"raw","data":{"html":"dada <h1>ADADA</h1>"}}],"version":"2.19.0"},"parent":"0"}
{"_id":"3aNeZDuMfQZ9rJQd","title":"Interaction with the user","uri":"interaction-with-the-user","body":{"time":1552466415244,"blocks":[{"type":"header","data":{"text":"Interaction with the user","level":2}},{"type":"paragraph","data":{"text":""}}],"version":"2.11.8"},"parent":"WgpqzRSb7kWRh2V5"}
{"_id":"5uBQdXB9ymH04bAZ","title":"Making a Block Settings","uri":"making-a-block-settings","body":{"time":1552466343678,"blocks":[{"type":"header","data":{"text":"Making a Block Settings","level":2}},{"type":"paragraph","data":{"text":""}}],"version":"2.11.8"},"parent":"PepZCQMe2C8mJiad"}
{"_id":"ABk9dC9owdTEeWzg","title":"Проверка <mark class=\"cdx-marker\">тайтла</mark> с тегом","uri":"proverka-mark-class-cdx-marker-taytla-mark-s-tegom","body":{"time":1552461757648,"blocks":[{"type":"header","data":{"text":"Проверка <mark class=\"cdx-marker\">тайтла</mark> с тегом","level":2}},{"type":"paragraph","data":{"text":"фвфв"}},{"type":"paragraph","data":{"text":"ввф"}}],"version":"2.11.8"},"parent":"0"}
{"_id":"CwxPc5V2KUTUmk4V","title":"The new page with todo","uri":"the-new-page-with-todo","body":{"time":1588278453763,"blocks":[{"type":"header","data":{"text":"The new page with todo","level":2}},{"type":"paragraph","data":{"text":"adad"}},{"type":"checklist","data":{"items":[{"text":"The first","checked":true},{"text":"The second","checked":false},{"text":"The <b>third</b>","checked":false}]}}],"version":"2.17.0"},"parent":"0"}
{"_id":"Ds0AgHaicAkca6bq","title":"How to create a features","uri":"how-to-create-a-features","body":{"time":1554125592057,"blocks":[{"type":"header","data":{"text":"How to create a features","level":2}},{"type":"paragraph","data":{"text":"adadadadada"}},{"type":"image","data":{"file":{"url":"/uploads/503b1533d0e2b35cdba2b218d29d59df.mp4","size":742148,"mime":"video/mp4"},"caption":"<b>adad</b>","withBorder":false,"stretched":false,"withBackground":false}},{"type":"image","data":{"file":{"url":"/uploads/51beca879ef9f3d1519f4581b459810e.gif","size":65313,"mime":"image/gif"},"caption":"","withBorder":false,"stretched":false,"withBackground":false}},{"type":"image","data":{"file":{"url":"/uploads/d8132d303cb35e2cb79aea6d9fba856a.jpeg","size":243368,"mime":"image/jpeg"},"caption":"","withBorder":false,"stretched":true,"withBackground":false}}],"version":"2.12.3"},"parent":"nSPV4Hs6x7TuzLaA"}
{"_id":"GMtOwYWEt7M1w71M","title":"Base concepts","body":{"time":1547747401369,"blocks":[{"type":"header","data":{"text":"Base concepts","level":2}},{"type":"paragraph","data":{"text":"ad"}},{"type":"paragraph","data":{"text":"ad"}},{"type":"paragraph","data":{"text":""}}],"version":"2.7.10"},"parent":"0"}
{"_id":"GNW0w6ghRQhQjaSg","title":"add","body":{"time":1547747411108,"blocks":[{"type":"header","data":{"text":"add","level":2}},{"type":"paragraph","data":{"text":"s"}}],"version":"2.7.10"},"parent":"GMtOwYWEt7M1w71M"}
{"_id":"GTmwM1FGbKy67Il9","title":"Access Editor's API","uri":"access-editor-s-api","body":{"time":1552466401107,"blocks":[{"type":"header","data":{"text":"Access Editor's API","level":2}},{"type":"paragraph","data":{"text":""}}],"version":"2.11.8"},"parent":"WgpqzRSb7kWRh2V5"}
{"_id":"Kux06I2Ji35tYiAh","title":"Paste substitutions","uri":"paste-substitutions","body":{"time":1552466352474,"blocks":[{"type":"header","data":{"text":"Paste substitutions","level":2}},{"type":"paragraph","data":{"text":""}}],"version":"2.11.8"},"parent":"PepZCQMe2C8mJiad"}
{"_id":"OJTKvrU6dfftxcGn","title":"Usage","uri":"installation-1","body":{"time":1548135050875,"blocks":[{"type":"header","data":{"text":"Usage","level":2}},{"type":"paragraph","data":{"text":"addada"}}],"version":"2.7.10"},"parent":"GMtOwYWEt7M1w71M"}
{"_id":"OgqoJzvgVbOE8Xew","title":"Making a Block Settings","uri":"vffv","body":{"time":1552466209986,"blocks":[{"type":"header","data":{"text":"Making a Block Settings","level":2}},{"type":"list","data":{"style":"ordered","items":["<a href=\"https://editorjs.io/making-a-block-settings\">Making a Block Settings</a>"]}},{"type":"paragraph","data":{"text":"фввффв"}}],"version":"2.11.8"},"parent":"nSPV4Hs6x7TuzLaA"}
{"_id":"PepZCQMe2C8mJiad","title":"Create a Block Tool","uri":"","body":{"time":1550553803488,"blocks":[{"type":"header","data":{"text":"Create a Block Tool","level":2}},{"type":"paragraph","data":{"text":"ad"}},{"type":"paragraph","data":{"text":"ad"}}],"version":"2.7.28"},"parent":"0"}
{"_id":"SAVQ7wjLoBv6sEkS","title":"Te<mark class=\"cdx-marker\">s</mark>t %^@3<a href=\"//ya.ru\">12</a>.13 1 3 1.. 3 1 adaddada","uri":"test-312-13-1-3-1-3-1-adaddada","body":{"time":1552461776494,"blocks":[{"type":"header","data":{"text":"Te<mark class=\"cdx-marker\">s</mark>t %^@3<a href=\"//ya.ru\">12</a>.13 1 3 1.. 3 1 adaddada","level":2}}],"version":"2.11.8"},"parent":"0"}
{"_id":"T6nNgnFXvt3Ly7ge","title":"Installation","uri":"installation","body":{"time":1548135034468,"blocks":[{"type":"header","data":{"text":"Installation","level":2}},{"type":"paragraph","data":{"text":"adadaddad"}}],"version":"2.7.10"},"parent":"GMtOwYWEt7M1w71M"}
{"_id":"TGOpp4LkLYXp4O6i","title":"First page 8","body":{"time":1539629270612,"blocks":[{"type":"header","data":{"text":"First page 8","level":2}},{"type":"paragraph","data":{"text":"ad"}},{"type":"paragraph","data":{"text":"ad"}},{"type":"paragraph","data":{"text":""}}],"version":"2.0.10"},"parent":"X7Py25T0wlrJ9Uxb"}
{"_id":"TyadTFScAhdBPxZ9","title":"Provide custom configuration","uri":"provide-custom-configuration","body":{"time":1552466385651,"blocks":[{"type":"header","data":{"text":"Provide custom configuration","level":2}},{"type":"paragraph","data":{"text":""}}],"version":"2.11.8"},"parent":"WgpqzRSb7kWRh2V5"}
{"_id":"WgpqzRSb7kWRh2V5","title":"The first plugin","uri":"daad","body":{"time":1552464746449,"blocks":[{"type":"header","data":{"text":"The first plugin","level":2}},{"type":"paragraph","data":{"text":"We will build a Simple Image plugin that allows us to add images to our articles. You can view the final result of the plugin."}},{"type":"paragraph","data":{"text":"Ok, let's get started with creation a JavaScript class for our Tool. "}},{"type":"code","data":{"code":"class SimpleImage {\n\n}\n"}},{"type":"paragraph","data":{"text":"We need at least of two methods to create a <code class=\"inline-code\">Block Tool</code> for Editor.js — render and save. First method, render, will create a UI of a Block that will be appended when our Tool will be selected from Toolbar. Second <a href=\"https://webpack.js.org/concepts\">method</a>, save — will extract the Block's data from that UI."}},{"type":"header","data":{"text":"Заголовок на <mark class=\"cdx-marker\">русском</mark>","level":2}},{"type":"paragraph","data":{"text":"Our UI will be a quite simple: just an input in which users will paste image URL."}},{"type":"code","data":{"code":"class SimpleImage {\n render(){\n return document.createElement('input');\n }\n\n save(blockContent){\n return {\n url: blockContent.value;\n }\n }\n\n}"}},{"type":"paragraph","data":{"text":"So there are few key features:"}},{"type":"list","data":{"style":"ordered","items":["Clean data output","API pluggable","Open source"]}},{"type":"header","data":{"text":"What does it mean <code class=\"inline-code\">block-styled</code>","level":2}},{"type":"paragraph","data":{"text":"In other editors the workspace is provided by single <code class=\"inline-code\">contenteditable</code> element in where you can create different HTML markup. All of us saw permanent bugs with moving text fragments or scaling images, while page parts are<a href=\"https://webpack.js.org/concepts\"> jumping and twitches</a>. Or highlighting big parts of text in case when you just want to make few words to be a heading or bold."}},{"type":"code","data":{"code":"<section name=\"0ed1\" class=\"section section--body section--first\">\n <div class=\"section-divider\">\n <hr class=\"section-divider\">\n </div>\n <div class=\"section-content\">\n <div class=\"section-inner sectionLayout--insetColumn\">\n <h3 name=\"f8e8\" class=\"graf graf--h3 graf--leading graf--title\">\n <br>\n </h3>\n <p name=\"982b\" class=\"graf graf--p graf-after--h3\">\n The example of text that was written in <strong class=\"markup--strong markup--p-strong\">one of popula</strong>r text editors.\n </p>\n <h3 name=\"c2ad\" class=\"graf graf--h3 graf-after--p\">\n With the header of course\n </h3>\n <p name=\"83d3\" class=\"graf graf--p graf-after--h3\">\n So what do we have?\n </p>\n </div>\n </div>\n</section>\n<section name=\"d1d2\" class=\"section section--body\">\n ...\n</section>"}},{"type":"header","data":{"text":"What is clean data","level":2}},{"type":"paragraph","data":{"text":"But more interest thing is, as mentioned above, that Editor.js returns clean data instead of HTML-markup. Take a look at the example."}},{"type":"paragraph","data":{"text":"If our entry consists of few paragraph and header, in popular Medium editor after saving we will have something like this:"}},{"type":"code","data":{"code":"{\n \"time\" : 1550476186479,\n \"blocks\" : [\n {\n \"type\" : \"paragraph\",\n \"data\" : {\n \"text\" : \"The example of text that was written in <b>one of popular</b> text editors.\"\n }\n },\n {\n \"type\" : \"header\",\n \"data\" : {\n \"text\" : \"With the header of course\",\n \"level\" : 2\n }\n },\n {\n \"type\" : \"paragraph\",\n \"data\" : {\n \"text\" : \"So what do we have?\"\n }\n }\n ],\n \"version\" : \"2.8.1\"\n}"}},{"type":"paragraph","data":{"text":"As you can see, there are only data we need: list of structural Blocks with their content description."}},{"type":"paragraph","data":{"text":"You can use this data to easy render in Web, native mobile/desctop application, pass to Audio Readers, create templates for Facebook Instant Articles, AMP, RSS, create chat-bots and many other."}},{"type":"paragraph","data":{"text":"Also, clean data can be useful for backend processing: sanitizing, validation, injecting an advertising or other stuff, extracting Headings, make covers for social networks from Image Blocks and other."}},{"type":"header","data":{"text":"API pluggable?","level":2}},{"type":"paragraph","data":{"text":"A key value of the Editor is the API. All main functional units of the editor — Blocks, Inline Formatting Tools, Block Tunes — are provided by external plugins that uses Editor's API."}},{"type":"paragraph","data":{"text":"We decide to extract all this Tools to separate scripts to make Editor's Core more abstract and make API more powerful. Any challenges and tasks you are facing can be implemented by you own plugins using the API. "}},{"type":"paragraph","data":{"text":"At the same time, API is created to be easy-to-understand and simple-to-use."}},{"type":"header","data":{"text":"Open Source, so?","level":2}},{"type":"paragraph","data":{"text":"Editor.js is more than just an editor. It is a big open-source community of developers and contributors. Anyone can suggest an improvement or bug fix. Anyone can create new cool API features and plugins."}},{"type":"paragraph","data":{"text":"We will support each developer of Editor.js plugins: best solutions will be collected to the awesome-lists and promoted to the community. Together we can create a big suite of different Blocks, Inline Tools, Block Tunes that can hit wide spectre of tasks."}},{"type":"delimiter","data":{}},{"type":"paragraph","data":{"text":"Thanks for your interest. Hope you enjoy Editor.js."}},{"type":"header","data":{"text":"In other editors the workspace is provided by single <code class=\"inline-code\">contenteditable</code> element in where you can create different HTML markup","level":2}},{"type":"paragraph","data":{"text":"In other editors the workspace is provided by single <code class=\"inline-code\">contenteditable</code> element in where you can create different HTML markup"}}],"version":"2.11.8"},"parent":"0"}
{"_id":"X7Py25T0wlrJ9Uxb","title":"First page 2","body":{"time":1539628539516,"blocks":[{"type":"header","data":{"text":"First page 2","level":2}},{"type":"paragraph","data":{"text":"ad"}},{"type":"paragraph","data":{"text":"ad"}},{"type":"paragraph","data":{"text":""}}],"version":"2.0.10"},"parent":"0"}
{"_id":"YzQ7uC0KavXd0hUv","title":"Test new tools","body":{"time":1540042261386,"blocks":[{"type":"header","data":{"text":"Test new tools","level":2}},{"type":"paragraph","data":{"text":"There is a text"}},{"type":"header","data":{"text":"There is a header","level":3}},{"type":"paragraph","data":{"text":"addad"}},{"type":"code","data":{"code":"/**\n * Return Editor data\n * @return {Promise.<{}>}\n */\nsave() {\n return this.editor.saver.save();\n}"}},{"type":"paragraph","data":{"text":"adada"}},{"type":"list","data":{"style":"ordered","items":["List <span class=\"inline-code\">item</span> 1","List item 2"]}}],"version":"2.1.3"},"parent":"if8mNmevxI1Yiz7b"}
{"_id":"ZkA2JXStJOFlCWz4","title":"Core API","uri":"oo5","body":{"time":1552466423834,"blocks":[{"type":"header","data":{"text":"Core API","level":2}}],"version":"2.11.8"},"parent":"0"}
{"_id":"bKNHiqsatoAAiyHM","title":"Changing a view","uri":"changing-a-view","body":{"time":1552466317539,"blocks":[{"type":"header","data":{"text":"Changing a view","level":2}},{"type":"paragraph","data":{"text":""}},{"type":"paragraph","data":{"text":"Changing a view"}}],"version":"2.11.8"},"parent":"PepZCQMe2C8mJiad"}
{"_id":"bkImfURI6N9Z2Ngo","title":"Test JSON","uri":"test-json","body":{"time":1550476790794,"blocks":[{"type":"header","data":{"text":"Test JSON","level":2}},{"type":"code","data":{"code":"{\n \"time\" : 1550476186479,\n \"blocks\" : [\n {\n \"type\" : \"paragraph\",\n \"data\" : {\n \"text\" : \"The example of text that was written in <b>one of popular</b> text editors.\"\n }\n },\n {\n \"type\" : \"header\",\n \"data\" : {\n \"text\" : \"With the header of course\",\n \"level\" : 2\n }\n },\n {\n \"type\" : \"paragraph\",\n \"data\" : {\n \"text\" : \"So what do we have?\"\n }\n }\n ],\n \"version\" : \"2.8.1\"\n}"}},{"type":"paragraph","data":{"text":"The bare minimum for using highlight.js on a web page is linking to the library along .... The official site for the library is at https://highlightjs.org/. Further in-depth <a href=\"https://codex.so\">documentation</a> for the API and other topics is at http://highlightjs.readthedocs.io/."}}],"version":"2.8.1"},"parent":"klb2kLc0MMmHAG43"}
{"_id":"if8mNmevxI1Yiz7b","title":"First page ","body":{"time":1539628435487,"blocks":[{"type":"header","data":{"text":"First page ","level":2}},{"type":"paragraph","data":{"text":"ad"}},{"type":"paragraph","data":{"text":"ad"}}],"version":"2.0.10"},"parent":"0"}
{"_id":"klb2kLc0MMmHAG43","title":"Test","uri":"test","body":{"time":1550474829908,"blocks":[{"type":"header","data":{"text":"Test","level":2}},{"type":"code","data":{"code":"<section name=\"0ed1\" class=\"section section--body section--first\">\n <div class=\"section-divider\">\n <hr class=\"section-divider\">\n </div>\n <div class=\"section-content\">\n <div class=\"section-inner sectionLayout--insetColumn\">\n <h3 name=\"f8e8\" class=\"graf graf--h3 graf--leading graf--title\">\n <br>\n </h3>\n <p name=\"982b\" class=\"graf graf--p graf-after--h3\">\n The example of text that was written in <strong class=\"markup--strong markup--p-strong\">one of popula</strong>r text editors.\n </p>\n <h3 name=\"c2ad\" class=\"graf graf--h3 graf-after--p\">\n With the header of course\n </h3>\n <p name=\"83d3\" class=\"graf graf--p graf-after--h3\">\n So what do we have?\n </p>\n </div>\n </div>\n</section>\n<section name=\"d1d2\" class=\"section section--body\">\n ...\n</section>"}},{"type":"paragraph","data":{"text":"ad"}},{"type":"paragraph","data":{"text":"<mark class=\"cdx-marker\">addadada</mark>"}},{"type":"paragraph","data":{"text":"Привет. Перед вами на<mark class=\"cdx-marker\">ш обновленный редактор. На этой странице вы можете проверить его в действ</mark>ии — попробуйте отредактировать или дополнить материал. Код страницы содержит пример <code class=\"inline-code\">подключения</code> и простейшей настройки."}},{"type":"code","data":{"code":" /**\n * Returns all writing form data\n * @throws {Error} - validation error\n * @return {Promise.<{parent: string, body: {editorData}}>}\n */\n async getData() {\n const editorData = await this.editor.save();\n const firstBlock = editorData.blocks.length ? editorData.blocks[0] : null;\n const title = firstBlock && firstBlock.type === 'header' ? firstBlock.data.text : null;\n let uri = '';\n\n if (this.nodes.uriInput && this.nodes.uriInput.value) {\n if (this.nodes.uriInput.value.match(/^[a-z0-9'-]+$/i)) {\n uri = this.nodes.uriInput.value;\n } else {\n throw new Error('Uri has unexpected characters');\n }\n }\n\n if (!title) {\n throw new Error('Entry should start with Header');\n }\n\n /** get ordering selector value */\n let putAbovePageId = null;\n if (this.nodes.putAboveIdSelector) {\n putAbovePageId = this.nodes.putAboveIdSelector.value;\n }\n\n return {\n parent: this.nodes.parentIdSelector.value,\n putAbovePageId: putAbovePageId,\n uri: uri,\n body: editorData\n };\n }"}}],"version":"2.8.1"},"parent":"0"}
{"_id":"lD1VuTBLDjgAvepr","title":"Process paste patterns","uri":"process-paste-patterns","body":{"time":1552466361686,"blocks":[{"type":"header","data":{"text":"Process paste patterns","level":2}},{"type":"paragraph","data":{"text":""}}],"version":"2.11.8"},"parent":"PepZCQMe2C8mJiad"}
{"_id":"nHT69LoZFueqX26K","title":"Test warning too","uri":"test-warning-too","body":{"time":1552840244005,"blocks":[{"type":"header","data":{"text":"Test warning too","level":2}},{"type":"warning","data":{"title":"Note.","message":"The keys of <code class=\"inline-code\">tools</code> objects will be added as <code class=\"inline-code\">type</code> fields to the Saved Data. "}}],"version":"2.11.10"},"parent":"0"}
{"_id":"nSPV4Hs6x7TuzLaA","title":"Base concepts","uri":"","body":{"time":1638377238659,"blocks":[{"id":"L3MatOqmFP","type":"header","data":{"text":"Base concepts","level":2}},{"id":"cpdz1IWoC-","type":"paragraph","data":{"text":"ad <code class=\"inline-code\"><b></code> ad <a> added"}},{"id":"matW6VoSjc","type":"paragraph","data":{"text":"CSS style:"}},{"id":"7EjW3ONUT4","type":"code","data":{"code":".simple-image {\n margin: 20px 0;\n}\n\n.simple-image input {\n width: 100%;\n padding: 10px;\n border: 1px solid #e4e4e4;\n border-radius: 3px;\n outline: none;\n font-size: 14px;\n}"}},{"id":"gZH499usM6","type":"image","data":{"file":{"url":"/uploads/1c9b2ae74f050b97f5f05dbe60d57a9f.png","size":41530,"mime":"image/png"},"caption":"Caption with <i>markup</i> <code class=\"inline-code\">elements</code>","withBorder":false,"stretched":false,"withBackground":false}},{"id":"wsEkGbD8Ck","type":"header","data":{"text":" Header with <code class=\"inline-code\">content</code> editable ","level":2}},{"id":"RwUCLeP0EW","type":"paragraph","data":{"text":"We should provide a mechanism for showing a saved data by our Tool. It is a quite simple: data will be passed to the class's <a href=\"//codex.so\"><code class=\"inline-code\">constructor</code></a>, so we can save it at the property, for example <code class=\"inline-code\">this.data</code> and access later by any method, including <code class=\"inline-code\">r</code>:"}},{"id":"IgPtgQCwS2","type":"header","data":{"text":" Header with <code class=\"inline-code\">content</code> editable ","level":3}},{"id":"5IjhNpXppA","type":"warning","data":{"title":"Note","message":"We should <b>provide</b> a mechanism for <a href=\"//codex.so\">showing</a> a saved data by our Tool. It is a quite simple: data will be <code class=\"inline-code\">passed</code> to the class's <i>constructor</i>, so we can save it at the <mark class=\"cdx-marker\">property</mark>, for example this.data and access later by any method, including render:"}},{"id":"aKWbzZPjcx","type":"paragraph","data":{"text":"adda"}},{"id":"RQIG3bckTD","type":"warning","data":{"title":"","message":"Read more about available sanitizer rules <a href=\"https://editorjs.io/sanitizer#clean\">here</a>."}},{"id":"bfeYjD7rKL","type":"embed","data":{"service":"youtube","source":"https://www.youtube.com/watch?v=iFKaWr7FTNc&t=1512s","embed":"https://www.youtube.com/embed/iFKaWr7FTNc?start=1512s","width":580,"height":320,"caption":"Caption"}}],"version":"2.23.0-rc.1"},"parent":"0"}
{"_id":"qWeDZ6l18nuiLvac","title":"The second page","uri":"the-second-page","body":{"time":1554125984173,"blocks":[{"type":"header","data":{"text":"The second page","level":2}},{"type":"paragraph","data":{"text":"adadaddad"}},{"type":"code","data":{"code":"import hljs from 'highlight.js/lib/highlight';\nimport javascript from 'highlight.js/lib/languages/javascript';\nimport xml from 'highlight.js/lib/languages/xml';\nimport json from 'highlight.js/lib/languages/json';\nimport css from 'highlight.js/lib/languages/css';\nimport style from 'highlight.js/styles/github-gist.css'; // eslint-disable-line no-unused-vars\nimport diffStyles from '../../styles/diff.pcss'; // eslint-disable-line no-unused-vars\n\n/**\n * @class CodeStyles\n * @classdesc Provides styling for code blocks\n */\nexport default class CodeStyler {\n /**\n * @param {string} selector - CSS selector for code blocks\n * @param {string[]} languages - list of languages to highlight, see hljs.listLanguages()\n */\n constructor({ selector, languages = ['javascript', 'xml', 'json', 'css'] }) {\n this.codeBlocksSelector = selector;\n this.languages = languages;\n this.langsAvailable = {\n javascript,\n xml,\n json,\n css\n };\n\n this.init();\n }\n\n /**\n * Start to highlight\n */\n init() {\n const codeBlocks = document.querySelectorAll(this.codeBlocksSelector);\n\n- if (!codeBlocks.length) {\n- return;\n- }\n\n this.languages.forEach(lang => {\n hljs.registerLanguage(lang, this.langsAvailable[lang]);\n });\n\n hljs.configure({\n languages: this.languages\n });\n\n Array.from(codeBlocks).forEach(block => {\n hljs.highlightBlock(block);\n\n+ this.highlightDiffs(block);\n });\n }\n\n+ /**\n+ * Highlight lines started from + or -\n+ * @param {Element} block\n+ */\n+ higlightDiffs(block){\n+ let temp = block.innerHTML.split('\\n');\n+ \n+ temp = temp.map(str => str.replace(/^(\\+.*)$/ig, '<span class=\"diff diff--added\">$1</span>'));\n+ temp = temp.map(str => str.replace(/^(-.*)$/ig, '<span class=\"diff diff--removed\">$1</span>'));\n+ block.innerHTML = temp.join('\\n');\n+ }\n}\n"}},{"type":"code","data":{"code":"\n.uri-input {\n- box-sizing: border-box;\n+ box-sizing: content-box;\n width: 100%;\n padding: 10px 12px;\n border-radius: 3px;\n+ border: 1px solid rgba(201, 201, 204, 0.48);\n+ box-shadow: inset 0 1px 2px 0 rgba(35, 44, 72, 0.06);\n outline: none;\n}\n"}},{"type":"code","data":{"code":"<div class=\"docs-aside-toggler\" onclick=\"document.querySelector('.docs-aside').classList.toggle('docs-aside--toggled')\">\n+ {{ svg('menu') }} Table of contents\n- {{ svg('menu') }} Old code\n</div>"}}],"version":"2.12.3"},"parent":"nSPV4Hs6x7TuzLaA"}
{"_id":"tveZnwNyqR2KfK89","title":"Building the first plugin","body":{"time":1539972101645,"blocks":[{"type":"header","data":{"text":"Building the first plugin","level":2}},{"type":"paragraph","data":{"text":""}}],"version":"2.0.10"},"parent":"PepZCQMe2C8mJiad"}
{"_id":"u5Jd7xn6HfpODs0z","title":"The first pluign","uri":"","body":{"time":1552466239548,"blocks":[{"type":"header","data":{"text":"The first pluign","level":2}}],"version":"2.11.8"},"parent":"PepZCQMe2C8mJiad"}
{"_id":"uBvmcSmYIcEiJUf1","title":"Sanitize saved data ","uri":"sanitize-saved-data","body":{"time":1552466372181,"blocks":[{"type":"header","data":{"text":"Sanitize saved data ","level":2}},{"type":"paragraph","data":{"text":""}}],"version":"2.11.8"},"parent":"PepZCQMe2C8mJiad"}
{"_id":"yI5G0RfhcUiA0lSo","title":"Saved data validation","uri":"saved-data-validation","body":{"time":1552466334330,"blocks":[{"type":"header","data":{"text":"Saved data validation","level":2}},{"type":"paragraph","data":{"text":""}},{"type":"paragraph","data":{"text":"Saved data validation"}}],"version":"2.11.8"},"parent":"PepZCQMe2C8mJiad"}
{"_id":"zaswSA5J2jwOrsaV","title":"Fill Block with saved data","uri":"fill-block-with-saved-data","body":{"time":1552466298747,"blocks":[{"type":"header","data":{"text":"Fill Block with saved data","level":2}},{"type":"paragraph","data":{"text":""}},{"type":"paragraph","data":{"text":"Fill Block with saved data"}}],"version":"2.11.8"},"parent":"PepZCQMe2C8mJiad"} pagesOrder.db {"_id":"2KWWjusi62GqbFxV","page":"PepZCQMe2C8mJiad","order":["zaswSA5J2jwOrsaV","bKNHiqsatoAAiyHM","yI5G0RfhcUiA0lSo","5uBQdXB9ymH04bAZ","Kux06I2Ji35tYiAh","lD1VuTBLDjgAvepr","uBvmcSmYIcEiJUf1"]}
{"_id":"6C75qA63glYEwIF2","page":"0","order":["nSPV4Hs6x7TuzLaA","PepZCQMe2C8mJiad","WgpqzRSb7kWRh2V5","ZkA2JXStJOFlCWz4","klb2kLc0MMmHAG43","GMtOwYWEt7M1w71M","X7Py25T0wlrJ9Uxb","if8mNmevxI1Yiz7b","ABk9dC9owdTEeWzg","SAVQ7wjLoBv6sEkS","nHT69LoZFueqX26K","CwxPc5V2KUTUmk4V","1ePZOPyo4DXjgthK"]}
{"_id":"OxFQYLZQDhewhe25","page":"qWeDZ6l18nuiLvac","order":["1dXyeY33VhFTMJ66"]}
{"_id":"lDykh75Gwyil9U38","page":"0HYPicoTHYNMNJur","order":[]}
{"_id":"lOYPy5RHjbStCNdZ","page":"WgpqzRSb7kWRh2V5","order":["TyadTFScAhdBPxZ9","GTmwM1FGbKy67Il9","3aNeZDuMfQZ9rJQd"]}
{"_id":"q68hFjLF9TYLhypi","page":"nSPV4Hs6x7TuzLaA","order":["Ds0AgHaicAkca6bq","OgqoJzvgVbOE8Xew","qWeDZ6l18nuiLvac"]}
{"_id":"wdPJpCbI5eyEzBxO","page":"klb2kLc0MMmHAG43","order":["bkImfURI6N9Z2Ngo"]} |
There is orphan |
I'd suggest to treat such a case like a root page and to not to skip such pages. And add a warning to the logs. |
If that is going to work, the corresponding |
We need to handle this case somehow. Any bad situation should not cause an infinity loop i guess. |
I agree that An infinity loop should not be occurred in any case. And I think if all of methods we wrote are working property then it should not make orphan |
it works but i don't why sorting function is unclear. i don't understand it at all. why two separate functions for getting pages from the database |
why don't use |
|
Just added exit code to prevent infinite loop if the count is bigger than 1,000. |
Resolves #164