Skip to content
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

Merged
merged 9 commits into from
Jun 22, 2022
Merged

Fix sorting in dropdown #187

merged 9 commits into from
Jun 22, 2022

Conversation

Y-k-Y
Copy link
Contributor

@Y-k-Y Y-k-Y commented Apr 28, 2022

Resolves #164

src/backend/controllers/pages.ts Outdated Show resolved Hide resolved
src/backend/controllers/pages.ts Outdated Show resolved Hide resolved
src/backend/controllers/pages.ts Outdated Show resolved Hide resolved
src/backend/controllers/pages.ts Outdated Show resolved Hide resolved
src/backend/controllers/pages.ts Outdated Show resolved Hide resolved
src/backend/controllers/pages.ts Outdated Show resolved Hide resolved
src/backend/routes/pages.ts Outdated Show resolved Hide resolved
src/backend/controllers/pages.ts Outdated Show resolved Hide resolved
src/backend/controllers/pages.ts Outdated Show resolved Hide resolved
const pagesGroupedByParent:Record<string, Array<Page>> = {};

pages.forEach(page => {
pagesGroupedByParent[String(page._id)] = [];
Copy link
Member

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?

Copy link
Contributor Author

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.

Copy link
Member

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.

Copy link
Contributor Author

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.

src/backend/controllers/pages.ts Outdated Show resolved Hide resolved
src/backend/controllers/pages.ts Outdated Show resolved Hide resolved
@neSpecc
Copy link
Member

neSpecc commented Apr 29, 2022

I've got an error by vising the /page/new on local machine

image

@neSpecc
Copy link
Member

neSpecc commented Apr 29, 2022

Also, do not forget to update the '/page/edit/:id' route as well

@Y-k-Y
Copy link
Contributor Author

Y-k-Y commented Apr 29, 2022

I've got an error by vising the /page/new on local machine

image

It's strange you faced that error. Could you describe how you get that error?

@neSpecc
Copy link
Member

neSpecc commented Apr 29, 2022

It's strange you faced that error. Could you describe how you get that error?

I've just opened the page.

🔽 Here is my `pages` list. Maybe it'll help:

pages [
   Page {
     _id: 'if8mNmevxI1Yiz7b',
     body: { time: 1539628435487, blocks: [Array], version: '2.0.10' },
     title: 'First page&nbsp;',
     uri: '',
     _parent: '0'
   },
   Page {
     _id: 'X7Py25T0wlrJ9Uxb',
     body: { time: 1539628539516, blocks: [Array], version: '2.0.10' },
     title: 'First page 2',
     uri: '',
     _parent: '0'
   },
   Page {
     _id: 'TGOpp4LkLYXp4O6i',
     body: { time: 1539629270612, blocks: [Array], version: '2.0.10' },
     title: 'First page 8',
     uri: '',
     _parent: 'X7Py25T0wlrJ9Uxb'
   },
   Page {
     _id: 'tveZnwNyqR2KfK89',
     body: { time: 1539972101645, blocks: [Array], version: '2.0.10' },
     title: 'Building the first plugin',
     uri: '',
     _parent: 'PepZCQMe2C8mJiad'
   },
   Page {
     _id: 'YzQ7uC0KavXd0hUv',
     body: { time: 1540042261386, blocks: [Array], version: '2.1.3' },
     title: 'Test new tools',
     uri: '',
     _parent: 'if8mNmevxI1Yiz7b'
   },
   Page {
     _id: 'GMtOwYWEt7M1w71M',
     body: { time: 1547747401369, blocks: [Array], version: '2.7.10' },
     title: 'Base concepts',
     uri: '',
     _parent: '0'
   },
   Page {
     _id: 'GNW0w6ghRQhQjaSg',
     body: { time: 1547747411108, blocks: [Array], version: '2.7.10' },
     title: 'add',
     uri: '',
     _parent: 'GMtOwYWEt7M1w71M'
   },
   Page {
     _id: 'T6nNgnFXvt3Ly7ge',
     body: { time: 1548135034468, blocks: [Array], version: '2.7.10' },
     title: 'Installation',
     uri: 'installation',
     _parent: 'GMtOwYWEt7M1w71M'
   },
   Page {
     _id: 'OJTKvrU6dfftxcGn',
     body: { time: 1548135050875, blocks: [Array], version: '2.7.10' },
     title: 'Usage',
     uri: 'installation-1',
     _parent: 'GMtOwYWEt7M1w71M'
   },
   Page {
     _id: 'klb2kLc0MMmHAG43',
     body: { time: 1550474829908, blocks: [Array], version: '2.8.1' },
     title: 'Test',
     uri: 'test',
     _parent: '0'
   },
   Page {
     _id: 'bkImfURI6N9Z2Ngo',
     body: { time: 1550476790794, blocks: [Array], version: '2.8.1' },
     title: 'Test JSON',
     uri: 'test-json',
     _parent: 'klb2kLc0MMmHAG43'
   },
   Page {
     _id: '1dXyeY33VhFTMJ66',
     body: { time: 1550483562360, blocks: [Array], version: '2.7.28' },
     title: 'Children of the second page',
     uri: 'children-of-the-second-page',
     _parent: 'qWeDZ6l18nuiLvac'
   },
   Page {
     _id: 'PepZCQMe2C8mJiad',
     body: { time: 1550553803488, blocks: [Array], version: '2.7.28' },
     title: 'Create a Block Tool',
     uri: '',
     _parent: '0'
   },
   Page {
     _id: 'ABk9dC9owdTEeWzg',
     body: { time: 1552461757648, blocks: [Array], version: '2.11.8' },
     title: 'Проверка <mark class="cdx-marker">тайтла</mark> с тегом',
     uri: 'proverka-mark-class-cdx-marker-taytla-mark-s-tegom',
     _parent: '0'
   },
   Page {
     _id: 'SAVQ7wjLoBv6sEkS',
     body: { time: 1552461776494, blocks: [Array], version: '2.11.8' },
     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',
     _parent: '0'
   },
   Page {
     _id: 'WgpqzRSb7kWRh2V5',
     body: { time: 1552464746449, blocks: [Array], version: '2.11.8' },
     title: 'The first plugin',
     uri: 'daad',
     _parent: '0'
   },
   Page {
     _id: 'OgqoJzvgVbOE8Xew',
     body: { time: 1552466209986, blocks: [Array], version: '2.11.8' },
     title: 'Making a Block Settings',
     uri: 'vffv',
     _parent: 'nSPV4Hs6x7TuzLaA'
   },
   Page {
     _id: 'u5Jd7xn6HfpODs0z',
     body: { time: 1552466239548, blocks: [Array], version: '2.11.8' },
     title: 'The first pluign',
     uri: '',
     _parent: 'PepZCQMe2C8mJiad'
   },
   Page {
     _id: 'zaswSA5J2jwOrsaV',
     body: { time: 1552466298747, blocks: [Array], version: '2.11.8' },
     title: 'Fill Block with saved data',
     uri: 'fill-block-with-saved-data',
     _parent: 'PepZCQMe2C8mJiad'
   },
   Page {
     _id: 'bKNHiqsatoAAiyHM',
     body: { time: 1552466317539, blocks: [Array], version: '2.11.8' },
     title: 'Changing a view',
     uri: 'changing-a-view',
     _parent: 'PepZCQMe2C8mJiad'
   },
   Page {
     _id: 'yI5G0RfhcUiA0lSo',
     body: { time: 1552466334330, blocks: [Array], version: '2.11.8' },
     title: 'Saved data validation',
     uri: 'saved-data-validation',
     _parent: 'PepZCQMe2C8mJiad'
   },
   Page {
     _id: '5uBQdXB9ymH04bAZ',
     body: { time: 1552466343678, blocks: [Array], version: '2.11.8' },
     title: 'Making a Block Settings',
     uri: 'making-a-block-settings',
     _parent: 'PepZCQMe2C8mJiad'
   },
   Page {
     _id: 'Kux06I2Ji35tYiAh',
     body: { time: 1552466352474, blocks: [Array], version: '2.11.8' },
     title: 'Paste substitutions',
     uri: 'paste-substitutions',
     _parent: 'PepZCQMe2C8mJiad'
   },
   Page {
     _id: 'lD1VuTBLDjgAvepr',
     body: { time: 1552466361686, blocks: [Array], version: '2.11.8' },
     title: 'Process paste patterns',
     uri: 'process-paste-patterns',
     _parent: 'PepZCQMe2C8mJiad'
   },
   Page {
     _id: 'uBvmcSmYIcEiJUf1',
     body: { time: 1552466372181, blocks: [Array], version: '2.11.8' },
     title: 'Sanitize saved data&nbsp;',
     uri: 'sanitize-saved-data',
     _parent: 'PepZCQMe2C8mJiad'
   },
   Page {
     _id: 'TyadTFScAhdBPxZ9',
     body: { time: 1552466385651, blocks: [Array], version: '2.11.8' },
     title: 'Provide custom configuration',
     uri: 'provide-custom-configuration',
     _parent: 'WgpqzRSb7kWRh2V5'
   },
   Page {
     _id: 'GTmwM1FGbKy67Il9',
     body: { time: 1552466401107, blocks: [Array], version: '2.11.8' },
     title: "Access Editor's API",
     uri: 'access-editor-s-api',
     _parent: 'WgpqzRSb7kWRh2V5'
   },
   Page {
     _id: '3aNeZDuMfQZ9rJQd',
     body: { time: 1552466415244, blocks: [Array], version: '2.11.8' },
     title: 'Interaction with the user',
     uri: 'interaction-with-the-user',
     _parent: 'WgpqzRSb7kWRh2V5'
   },
   Page {
     _id: 'ZkA2JXStJOFlCWz4',
     body: { time: 1552466423834, blocks: [Array], version: '2.11.8' },
     title: 'Core API',
     uri: 'oo5',
     _parent: '0'
   },
   Page {
     _id: 'nHT69LoZFueqX26K',
     body: { time: 1552840244005, blocks: [Array], version: '2.11.10' },
     title: 'Test warning too',
     uri: 'test-warning-too',
     _parent: '0'
   },
   Page {
     _id: 'Ds0AgHaicAkca6bq',
     body: { time: 1554125592057, blocks: [Array], version: '2.12.3' },
     title: 'How to create a features',
     uri: 'how-to-create-a-features',
     _parent: 'nSPV4Hs6x7TuzLaA'
   },
   Page {
     _id: 'qWeDZ6l18nuiLvac',
     body: { time: 1554125984173, blocks: [Array], version: '2.12.3' },
     title: 'The second page',
     uri: 'the-second-page',
     _parent: 'nSPV4Hs6x7TuzLaA'
   },
   Page {
     _id: 'CwxPc5V2KUTUmk4V',
     body: { time: 1588278453763, blocks: [Array], version: '2.17.0' },
     title: 'The new page with todo',
     uri: 'the-new-page-with-todo',
     _parent: '0'
   },
   Page {
     _id: '1ePZOPyo4DXjgthK',
     body: { time: 1602781859833, blocks: [Array], version: '2.19.0' },
     title: 'ad',
     uri: 'ad',
     _parent: '0'
   },
   Page {
     _id: 'nSPV4Hs6x7TuzLaA',
     body: { time: 1638377238659, blocks: [Array], version: '2.23.0-rc.1' },
     title: 'Base concepts',
     uri: '',
     _parent: '0'
   }
 ]

@Y-k-Y
Copy link
Contributor Author

Y-k-Y commented Apr 30, 2022

I should have changed the way of grouping since page.body.time is mutable property it can't be used as a criteria to sort and i didn't notice that the root page can be a child page as well

@Y-k-Y Y-k-Y requested a review from neSpecc May 2, 2022 13:27
Comment on lines 84 to 86
const docs = await this.getAll();

return docs.filter(doc => doc.page === '0')[0];
Copy link
Member

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment on lines 95 to 97
const docs = await this.getAll();

return docs.filter(doc => doc.page !== '0');
Copy link
Member

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

src/backend/controllers/pages.ts Outdated Show resolved Hide resolved
src/backend/controllers/pages.ts Outdated Show resolved Hide resolved
src/backend/controllers/pages.ts Outdated Show resolved Hide resolved
src/backend/controllers/pages.ts Outdated Show resolved Hide resolved
src/backend/controllers/pages.ts Outdated Show resolved Hide resolved
src/backend/controllers/pages.ts Show resolved Hide resolved
src/backend/controllers/pages.ts Outdated Show resolved Hide resolved
Copy link
Member

@neSpecc neSpecc left a 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.

@Y-k-Y
Copy link
Contributor Author

Y-k-Y commented May 12, 2022

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 and pagesOrder.db I think it stuck on infinite looping in some ways.
Also, can you check if stage branch produce the same situation?

@neSpecc
Copy link
Member

neSpecc commented May 16, 2022

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&nbsp;view the final result&nbsp;of the plugin."}},{"type":"paragraph","data":{"text":"Ok, let's get started with creation a JavaScript class for our Tool.&nbsp;"}},{"type":"code","data":{"code":"class SimpleImage {\n\n}\n"}},{"type":"paragraph","data":{"text":"We need at least of two methods to create a&nbsp;<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&nbsp;<code class=\"inline-code\">contenteditable</code>&nbsp;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.&nbsp;"}},{"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&nbsp;<code class=\"inline-code\">contenteditable</code>&nbsp;element in where you can create different HTML markup","level":2}},{"type":"paragraph","data":{"text":"In other editors the workspace is provided by single&nbsp;<code class=\"inline-code\">contenteditable</code>&nbsp;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&nbsp;","body":{"time":1539628435487,"blocks":[{"type":"header","data":{"text":"First page&nbsp;","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&nbsp;<code class=\"inline-code\">tools</code>&nbsp;objects will be added as&nbsp;<code class=\"inline-code\">type</code>&nbsp;fields to the Saved Data.&nbsp;"}}],"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\">&lt;b&gt;</code> ad &lt;a&gt; 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":"&nbsp;Header with <code class=\"inline-code\">content</code> editable&nbsp;","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&nbsp;<code class=\"inline-code\">this.data</code>&nbsp;and access later by any method, including&nbsp;<code class=\"inline-code\">r</code>:"}},{"id":"IgPtgQCwS2","type":"header","data":{"text":"&nbsp;Header with&nbsp;<code class=\"inline-code\">content</code>&nbsp;editable&nbsp;","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&nbsp;<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&nbsp;","uri":"sanitize-saved-data","body":{"time":1552466372181,"blocks":[{"type":"header","data":{"text":"Sanitize saved data&nbsp;","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"]}

@Y-k-Y
Copy link
Contributor Author

Y-k-Y commented May 17, 2022

There is orphan pagesOrder which its parent is missing in your pagesOrder.db. As far as i know each page must have its parent page unless the page is root which the page property's value is zero. Also, when the parent page is removed its child pages should be removed as well. I'm still not sure how that orphan pageOrder is created but maybe we can ignore it since it doesn't have any page content? If so i'll skip the while loop if the remained pagesOrder has no parent neither page content.

@neSpecc
Copy link
Member

neSpecc commented May 17, 2022

There is orphan pagesOrder which its parent is missing in your pagesOrder.db. As far as i know each page must have its parent page unless the page is root which the page property's value is zero. Also, when the parent page is removed its child pages should be removed as well. I'm still not sure how that orphan pageOrder is created but maybe we can ignore it since it doesn't have any page content? If so i'll skip the while loop if the remained pagesOrder has no parent neither page content.

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.

@Y-k-Y
Copy link
Contributor Author

Y-k-Y commented May 18, 2022

There is orphan pagesOrder which its parent is missing in your pagesOrder.db. As far as i know each page must have its parent page unless the page is root which the page property's value is zero. Also, when the parent page is removed its child pages should be removed as well. I'm still not sure how that orphan pageOrder is created but maybe we can ignore it since it doesn't have any page content? If so i'll skip the while loop if the remained pagesOrder has no parent neither page content.

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 pages should exist since we need page's title to list but orphan pagesOrder doesn't have anything. What i meant by 'pagesOrder has no parent neither page content' is there isn't corresponding pages. In this case we couldn't get any info from orhan pagesOrder. 0HYPicoTHYNMNJur is orphan pagesOrder's page property which should matches with one of pages's id property but as you can see there is no pages matched with it.

@neSpecc
Copy link
Member

neSpecc commented May 20, 2022

If that is going to work, the corresponding pages should exist since we need page's title to list but orphan pagesOrder doesn't have anything. What i meant by 'pagesOrder has no parent neither page content' is there isn't corresponding pages. In this case we couldn't get any info from orhan pagesOrder. 0HYPicoTHYNMNJur is orphan pagesOrder's page property which should matches with one of pages's id property but as you can see there is no pages matched with it.

We need to handle this case somehow. Any bad situation should not cause an infinity loop i guess.

@Y-k-Y
Copy link
Contributor Author

Y-k-Y commented May 21, 2022

If that is going to work, the corresponding pages should exist since we need page's title to list but orphan pagesOrder doesn't have anything. What i meant by 'pagesOrder has no parent neither page content' is there isn't corresponding pages. In this case we couldn't get any info from orhan pagesOrder. 0HYPicoTHYNMNJur is orphan pagesOrder's page property which should matches with one of pages's id property but as you can see there is no pages matched with it.

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 pagesOrder. Although if there is orphan pagesOrder i think we can ignore it since it contains nothing🤔

@neSpecc
Copy link
Member

neSpecc commented May 23, 2022

I've tested it on the stage. Looks like some articles are not presented at the dropdown for some reason.

image

@Y-k-Y
Copy link
Contributor Author

Y-k-Y commented May 24, 2022

I've tested it on the stage. Looks like some articles are not presented at the dropdown for some reason.

image

When you edit the root page it can't be relocated at its child pages that's why it doesn't display the list of its child pages on the dropdown.

As you can see it displays the list of pages if you enter to edit mode of none root page.
image

@talyguryn
Copy link
Member

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

@talyguryn
Copy link
Member

why don't use createMenuTree() function for getting pages tree? it solves the same problem and we can upgrade it to fit this issue.

@neSpecc
Copy link
Member

neSpecc commented Jun 16, 2022

  • I can't test it locally due to infinity cycle in that branch.
  • I'm agree, that the code is not so well understandable
  • But it seems working fine on the Stage, so I'd suggest to merge it as is, since there is no progress here for a while.

@Y-k-Y
Copy link
Contributor Author

Y-k-Y commented Jun 21, 2022

Just added exit code to prevent infinite loop if the count is bigger than 1,000.
I know this approach is bad but right now i have no idea how to deal with it... And i agree with @talyguryn and @neSpecc 's comments.
It's working but not looking good and the complexity is pretty bad but since i took so much time with this pr it's time to merge and i'll refactor this one later.

@Y-k-Y Y-k-Y merged commit b3d8a1b into main Jun 22, 2022
@Y-k-Y Y-k-Y deleted the bugfix/sorting-in-dropdown branch June 22, 2022 14:09
@Y-k-Y Y-k-Y restored the bugfix/sorting-in-dropdown branch June 22, 2022 14:17
@Y-k-Y Y-k-Y deleted the bugfix/sorting-in-dropdown branch June 22, 2022 14:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fix sorting in dropdown with articles on article edit page
4 participants