diff --git a/index.html b/index.html index 4219408..6beceaa 100644 --- a/index.html +++ b/index.html @@ -202,7 +202,7 @@

Dados de acesso:

enableToolbar: true, height: "800px", serviceUrl: - "https://ej2services.syncfusion.com/production/web-services/api/documenteditor/", + "https://api.iarahealth.com/speech/syncfusion/api/documenteditor/", }); editorContainer.appendTo("#editor-container"); @@ -222,7 +222,7 @@

Dados de acesso:

recognition.interimResults = true; const syncfusionAdapter = new IaraSyncfusionAdapter( - editorContainer, + editorContainer.documentEditor, recognition ); diff --git a/package-lock.json b/package-lock.json index 6731904..2e5066d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,9 +33,9 @@ "vitest": "^0.29.8" }, "peerDependencies": { - "@syncfusion/ej2-documenteditor": ">=23.2", - "@syncfusion/ej2-locale": ">=23.1", - "@syncfusion/ej2-ribbon": ">=24.1", + "@syncfusion/ej2-documenteditor": ">=24.2", + "@syncfusion/ej2-locale": ">=24.2", + "@syncfusion/ej2-ribbon": ">=24.2", "tinymce": ">=6.5" }, "peerDependenciesMeta": { @@ -676,227 +676,367 @@ } }, "node_modules/@syncfusion/ej2-base": { - "version": "24.1.42", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-base/-/ej2-base-24.1.42.tgz", - "integrity": "sha512-3Zolyu6xA2pasid3Ttaf0qqQcEU/cQMJwuhaGa5vBnt1Xmo4oPkipUAsWLCtlfkmF/iUN9Hts3+8a4fBr4x3dA==", - "optional": true, + "version": "24.2.8", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-base/-/ej2-base-24.2.8.tgz", + "integrity": "sha512-GzTH2VELnmBFCrzfkGSTw7oALFNBYq6ysGDTAfpo0GIAd9Ge3yCTCU7wELJoKJhmg2I4RVgQlrZF5o7z7ajxTQ==", "peer": true, "dependencies": { - "@syncfusion/ej2-icons": "~24.1.41" + "@syncfusion/ej2-icons": "~24.2.3" }, "bin": { "syncfusion-license": "bin/syncfusion-license.js" } }, "node_modules/@syncfusion/ej2-buttons": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-buttons/-/ej2-buttons-24.1.41.tgz", - "integrity": "sha512-hko5TLLCssu7O9/iJKlogCR9hP6faaE6H96pOQ1qpuemv85SxUVBbDoAzCkDUg4/2HlsMJMSHGZ9ZHrPGUZJHA==", - "optional": true, + "version": "24.2.7", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-buttons/-/ej2-buttons-24.2.7.tgz", + "integrity": "sha512-tHrl3zqhsgRD+lUZDAy7XmbRbNCZuIn588ip0cwFXHHqbk0eLJnd/PTBS5TodSp+VMpOeiHsu0IVbuZg1dXRwg==", "peer": true, "dependencies": { - "@syncfusion/ej2-base": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.7" } }, "node_modules/@syncfusion/ej2-calendars": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-calendars/-/ej2-calendars-24.1.41.tgz", - "integrity": "sha512-rpTYU6TwqdTXyOfKKubeLKTkBDv4AbkCyi1W3fdMs6RmobozjmkgquzNZFsVlFwRMYjViShoyUlWptrQw4iUAw==", + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-calendars/-/ej2-calendars-24.2.9.tgz", + "integrity": "sha512-WyY+eTgHlPiNQ7WqCJfuI8mlsx9XuC7ywgwBNWojK18wmETETPZ2freTlo59khHfWSW5xqKKFXy2lVTtw5NYvw==", "optional": true, "peer": true, "dependencies": { - "@syncfusion/ej2-base": "~24.1.41", - "@syncfusion/ej2-buttons": "~24.1.41", - "@syncfusion/ej2-inputs": "~24.1.41", - "@syncfusion/ej2-lists": "~24.1.41", - "@syncfusion/ej2-popups": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.7", + "@syncfusion/ej2-buttons": "~24.2.7", + "@syncfusion/ej2-inputs": "~24.2.9", + "@syncfusion/ej2-lists": "~24.2.8", + "@syncfusion/ej2-popups": "~24.2.9" } }, "node_modules/@syncfusion/ej2-charts": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-charts/-/ej2-charts-24.1.41.tgz", - "integrity": "sha512-FEsEsHdA3TDpQw0LhfYR4YFR9u0M7CoBhsc13UlEgs90r5QgqDQXw9AxDmHOO2HXaCQihueVDBeWPiH9emts/A==", + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-charts/-/ej2-charts-24.2.9.tgz", + "integrity": "sha512-zaw19XrMa0feDBk1RJldI99TMgRDoligeH4fbcxkP2PFR3ANdNmIYiWRakX/AwsAJSaSUOnvz/Lhv0q2y4/L2g==", "optional": true, "peer": true, "dependencies": { - "@syncfusion/ej2-base": "~24.1.41", - "@syncfusion/ej2-calendars": "~24.1.41", - "@syncfusion/ej2-data": "~24.1.41", - "@syncfusion/ej2-excel-export": "~24.1.41", - "@syncfusion/ej2-navigations": "~24.1.41", - "@syncfusion/ej2-pdf-export": "~24.1.41", - "@syncfusion/ej2-svg-base": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.7", + "@syncfusion/ej2-calendars": "~24.2.9", + "@syncfusion/ej2-data": "~24.2.3", + "@syncfusion/ej2-excel-export": "~24.2.4", + "@syncfusion/ej2-navigations": "~24.2.8", + "@syncfusion/ej2-pdf-export": "~24.2.3", + "@syncfusion/ej2-svg-base": "~24.2.3" } }, "node_modules/@syncfusion/ej2-compression": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-compression/-/ej2-compression-24.1.41.tgz", - "integrity": "sha512-OO3Am1WXMi+6V25QG3iySmikWA2gXWgKh4B9p1L8nksUptrvfdNFJqzNEEdZWoF9ftOMWHcagwklbFATjxEgRw==", + "version": "24.2.3", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-compression/-/ej2-compression-24.2.3.tgz", + "integrity": "sha512-ZjDxhlxf2cWoRGLOVwYhEW/RUhzDtyGOZ2VlcG0KT0L4EFVdAHHKSY40urDtpCTWln4fW0Ki6KFDsM9gWnNLeQ==", "optional": true, "peer": true, "dependencies": { - "@syncfusion/ej2-file-utils": "~24.1.41" + "@syncfusion/ej2-file-utils": "~24.2.3" } }, "node_modules/@syncfusion/ej2-data": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-data/-/ej2-data-24.1.41.tgz", - "integrity": "sha512-xKSaV7CaF8K37nIf9SuG6387mqXoNt+k4uqiAI1Xsp9Z+UkpEd8wm1skeW2qJao5AyxVhUhV6MtX9grO8udCjg==", - "optional": true, + "version": "24.2.3", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-data/-/ej2-data-24.2.3.tgz", + "integrity": "sha512-nZai/hmBuD2tAAXPF/oHZj5z6UfqjQ9PIlKvt+rOFdvQ5pOQHavv+OUpdUAeQPijgqzprnUVcmRlsn7XcS17bw==", "peer": true, "dependencies": { - "@syncfusion/ej2-base": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.3" } }, "node_modules/@syncfusion/ej2-documenteditor": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-documenteditor/-/ej2-documenteditor-24.1.41.tgz", - "integrity": "sha512-QL7qYxQpW0NPMPQZKbCB5XwcKROV9tYyQaZqq78rS+YQxEMWGUHme9aI9utfC+nZiVm6GNfet3q7fPz6NIyalA==", + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-documenteditor/-/ej2-documenteditor-24.2.9.tgz", + "integrity": "sha512-DlloM0G3NdHHXj+0XsJ4aLk3fau4+2zbzB8a6YcdCqxIZSjuc2Gd9uywP9x2T/wXAHC3c0LhvFjTnc9OV+pOzQ==", "optional": true, "peer": true, "dependencies": { - "@syncfusion/ej2-base": "~24.1.41", - "@syncfusion/ej2-buttons": "~24.1.41", - "@syncfusion/ej2-calendars": "~24.1.41", - "@syncfusion/ej2-compression": "~24.1.41", - "@syncfusion/ej2-dropdowns": "~24.1.41", - "@syncfusion/ej2-file-utils": "~24.1.41", - "@syncfusion/ej2-inputs": "~24.1.41", - "@syncfusion/ej2-navigations": "~24.1.41", - "@syncfusion/ej2-office-chart": "~24.1.41", - "@syncfusion/ej2-popups": "~24.1.41", - "@syncfusion/ej2-splitbuttons": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.7", + "@syncfusion/ej2-buttons": "~24.2.7", + "@syncfusion/ej2-calendars": "~24.2.9", + "@syncfusion/ej2-compression": "~24.2.3", + "@syncfusion/ej2-dropdowns": "~24.2.9", + "@syncfusion/ej2-file-utils": "~24.2.3", + "@syncfusion/ej2-inputs": "~24.2.9", + "@syncfusion/ej2-navigations": "~24.2.8", + "@syncfusion/ej2-office-chart": "~24.2.3", + "@syncfusion/ej2-popups": "~24.2.9", + "@syncfusion/ej2-splitbuttons": "~24.2.7" } }, "node_modules/@syncfusion/ej2-dropdowns": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-dropdowns/-/ej2-dropdowns-24.1.41.tgz", - "integrity": "sha512-oVNjjjhSvZ3HSAW+E0WadpxD2fmiCXXmrMHNPtVTv31EXQryNVzVrMvMcn6dWmrg052NOG5MpYhmWdrh/vuWxA==", - "optional": true, + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-dropdowns/-/ej2-dropdowns-24.2.9.tgz", + "integrity": "sha512-va8WauFI/LSIvhAvhqSGlGwrHWHV6d9SbkfJy+uQ6w6eDnNTzD9ZH+eUcu7bhSoNVHdOSjPIFbLh8Ea2ev4LEA==", "peer": true, "dependencies": { - "@syncfusion/ej2-base": "~24.1.41", - "@syncfusion/ej2-data": "~24.1.41", - "@syncfusion/ej2-inputs": "~24.1.41", - "@syncfusion/ej2-lists": "~24.1.41", - "@syncfusion/ej2-navigations": "~24.1.41", - "@syncfusion/ej2-notifications": "~24.1.41", - "@syncfusion/ej2-popups": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.7", + "@syncfusion/ej2-data": "~24.2.3", + "@syncfusion/ej2-inputs": "~24.2.9", + "@syncfusion/ej2-lists": "~24.2.8", + "@syncfusion/ej2-navigations": "~24.2.8", + "@syncfusion/ej2-notifications": "~24.2.4", + "@syncfusion/ej2-popups": "~24.2.9" } }, "node_modules/@syncfusion/ej2-excel-export": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-excel-export/-/ej2-excel-export-24.1.41.tgz", - "integrity": "sha512-ieLWcOeHc4jIhfcrUA79m0C60g44bbM1O+BhequQB/GK9o7WjhD7TmRUYZSK/4jU1pm9tu+YI8+P18vjDxWIgw==", + "version": "24.2.4", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-excel-export/-/ej2-excel-export-24.2.4.tgz", + "integrity": "sha512-ppMKz6nCxoUQYlfI6iqv4pfyhb8ZZJlfkaTpgcj4oys/Oss6MgQgZrpVepyFBoW735NtvM0BOVrs6ZnAui03jg==", "optional": true, "peer": true, "dependencies": { - "@syncfusion/ej2-base": "~24.1.41", - "@syncfusion/ej2-compression": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.3", + "@syncfusion/ej2-compression": "~24.2.3" } }, "node_modules/@syncfusion/ej2-file-utils": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-file-utils/-/ej2-file-utils-24.1.41.tgz", - "integrity": "sha512-lMCSB9kZrn2qe7UvFq8N2xERCu8sCg+5LRESjlsB4+k+02MLhponHmMzAPbvMr3DJ5ctb7A1dihAdQT0Mwd3Jg==", + "version": "24.2.3", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-file-utils/-/ej2-file-utils-24.2.3.tgz", + "integrity": "sha512-kPejWNjWoougUu/tsxh6ywKR/cr5+2tIZO1BUWlTO+XyFk/uolZ4Xx14tGVnrLpzl4+DaSLfv73b6VDvqpIbzg==", "optional": true, "peer": true }, "node_modules/@syncfusion/ej2-icons": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-icons/-/ej2-icons-24.1.41.tgz", - "integrity": "sha512-r44Xr0QC1iGP6Ed5UVNyfIa3lmcDn680nzNoUbykUv02JaJv6nF0OQZeZNjjY3m8YrFhYCHdms0h9A9sU7c9/Q==", - "optional": true, + "version": "24.2.3", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-icons/-/ej2-icons-24.2.3.tgz", + "integrity": "sha512-JdQ7w2SiiUUXZFrmX0j3+0iQZdT+Z5NP7jb1zTKDAiTGB3IjcSTQc8MtPmORTG4vvG6lOSLYHrn2HtP7mqvlEQ==", "peer": true }, "node_modules/@syncfusion/ej2-inputs": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-inputs/-/ej2-inputs-24.1.41.tgz", - "integrity": "sha512-scVtCR6XMrdr2RQe0HUG+y7Mdr4hnYrNJAYntUJgO0gxMiWjHku6UG+9FBruA3rC7INvNsBviCqvZIHyTXz4NA==", - "optional": true, + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-inputs/-/ej2-inputs-24.2.9.tgz", + "integrity": "sha512-inUPQt387emSR12p8hHWVQUA4q2oH8kcMPNe8mc06TN5wgPnSDYjciV2oTam9xkOchOlYrRmL0gsV6a72ilYPw==", "peer": true, "dependencies": { - "@syncfusion/ej2-base": "~24.1.41", - "@syncfusion/ej2-buttons": "~24.1.41", - "@syncfusion/ej2-popups": "~24.1.41", - "@syncfusion/ej2-splitbuttons": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.7", + "@syncfusion/ej2-buttons": "~24.2.7", + "@syncfusion/ej2-popups": "~24.2.9", + "@syncfusion/ej2-splitbuttons": "~24.2.7" } }, "node_modules/@syncfusion/ej2-lists": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-lists/-/ej2-lists-24.1.41.tgz", - "integrity": "sha512-TZrHBq02s2vxVwqjLUxx+iTGP8X93eJCkCwlhjajnjw7jU5Yireb//FVORwTzWuwlrVc2tEkDiGW3WYhnowVMg==", - "optional": true, + "version": "24.2.8", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-lists/-/ej2-lists-24.2.8.tgz", + "integrity": "sha512-K1HXJL2Dz02XmTTWxZAxJ6SLJwp6pwcVLXi7L5T5NHcfOvSrPmL+vb1ZLoABHe+7Cm2snTaINdQky9cmvgBK6w==", "peer": true, "dependencies": { - "@syncfusion/ej2-base": "~24.1.41", - "@syncfusion/ej2-buttons": "~24.1.41", - "@syncfusion/ej2-data": "~24.1.41", - "@syncfusion/ej2-popups": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.7", + "@syncfusion/ej2-buttons": "~24.2.7", + "@syncfusion/ej2-data": "~24.2.3", + "@syncfusion/ej2-popups": "~24.2.8" } }, "node_modules/@syncfusion/ej2-locale": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-locale/-/ej2-locale-24.1.41.tgz", - "integrity": "sha512-Um8HWtIbIj8iMHX5yStSx3xFjj0axCeOxrHJV1f6VDCvCleF8S/aERqp4dxNm+mJQTs6aNUyWSiBIs7ErCZdWw==", + "version": "24.2.7", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-locale/-/ej2-locale-24.2.7.tgz", + "integrity": "sha512-87O6fYjRXmV8VkRmzJVg/dPYtWlTYuZqbgpqFKN8M19pEkiryy0tVKerGSIkcoO7Bq/h8yVSShO+mLl6nv7EhQ==", "peer": true }, "node_modules/@syncfusion/ej2-navigations": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-navigations/-/ej2-navigations-24.1.41.tgz", - "integrity": "sha512-l551sMOEpXeTSkaWNNEhmkSw5vGYIX8lURuywyUnF7L1QMbfZwhiy2fLYopcRqFOOXFsLchGXzaHBrcfcMtF2g==", - "optional": true, + "version": "24.2.8", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-navigations/-/ej2-navigations-24.2.8.tgz", + "integrity": "sha512-dQ3Xnjvg1sf595M7EvDQmM10iNFU1mlqUZ/J9cdTMGoyiMeat5DtTTWVOc1NShFyJjCqHlfg5c8LNfqKRerIcA==", "peer": true, "dependencies": { - "@syncfusion/ej2-base": "~24.1.41", - "@syncfusion/ej2-buttons": "~24.1.41", - "@syncfusion/ej2-data": "~24.1.41", - "@syncfusion/ej2-inputs": "~24.1.41", - "@syncfusion/ej2-lists": "~24.1.41", - "@syncfusion/ej2-popups": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.7", + "@syncfusion/ej2-buttons": "~24.2.7", + "@syncfusion/ej2-data": "~24.2.3", + "@syncfusion/ej2-inputs": "~24.2.7", + "@syncfusion/ej2-lists": "~24.2.8", + "@syncfusion/ej2-popups": "~24.2.8" } }, "node_modules/@syncfusion/ej2-notifications": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-notifications/-/ej2-notifications-24.1.41.tgz", - "integrity": "sha512-equJ8+DrZj2yaGyAxs7GiGWtH14ns74RFj0q2ma/SCGQUNyUARgDiMdF5NlN4btnE3UGoAtKk5ikW8boole8Bw==", - "optional": true, + "version": "24.2.4", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-notifications/-/ej2-notifications-24.2.4.tgz", + "integrity": "sha512-14oBybExHpxSF88p5tbMvURoUnVNOj4nBDZJo1fnU8fb8KxHvmxtSm5ObLwe4nGiPZ/1QspGyLwL2GLKM0Ncig==", "peer": true, "dependencies": { - "@syncfusion/ej2-base": "~24.1.41", - "@syncfusion/ej2-buttons": "~24.1.41", - "@syncfusion/ej2-popups": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.3", + "@syncfusion/ej2-buttons": "~24.2.3", + "@syncfusion/ej2-popups": "~24.2.3" } }, "node_modules/@syncfusion/ej2-office-chart": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-office-chart/-/ej2-office-chart-24.1.41.tgz", - "integrity": "sha512-NYVwyiUzp/ff4SMufz2tqdx9oWUL99pHJYuH5qpmI3NoEOPpOoviX/8HI/GzvBBamFeZTeZIVBwbvYRwoPQX9w==", + "version": "24.2.3", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-office-chart/-/ej2-office-chart-24.2.3.tgz", + "integrity": "sha512-lpQp6YMXuf6THswcn0a3hKXXK2WNgb1TMXuVxbsA1JYz3aeuUe00IM9o94Hi9uI3BJVS/ZIRy3yDW6ycEZJnKA==", "optional": true, "peer": true, "dependencies": { - "@syncfusion/ej2-charts": "~24.1.41" + "@syncfusion/ej2-charts": "~24.2.3" } }, "node_modules/@syncfusion/ej2-pdf-export": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-pdf-export/-/ej2-pdf-export-24.1.41.tgz", - "integrity": "sha512-AsPl0mHerlNPVEy+qm9CDxneDIAOIMVPxlVTcxhXeOwEugdkPAF9vTzx5jX3hoMLqnpnpxXq/FjyXcz4+fapbw==", + "version": "24.2.3", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-pdf-export/-/ej2-pdf-export-24.2.3.tgz", + "integrity": "sha512-h6fmsSxQA4BuwuYusPruQYUrdyH1NJIXMrcRN0zAhORPEKDeLy/jp1qiBILBtjGFI3JWxVRXfz4Fm6Ln7j766A==", "optional": true, "peer": true, "dependencies": { - "@syncfusion/ej2-compression": "~24.1.41" + "@syncfusion/ej2-compression": "~24.2.3" } }, "node_modules/@syncfusion/ej2-popups": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-popups/-/ej2-popups-24.1.41.tgz", - "integrity": "sha512-SSx3ZfdRAuSLjoo2/qU4PLLmbo5L+x1LqyxgxNq2bflRhx3Xdk51iEdS00ihTjBoMweE6KS3nPGHI8krOzv44A==", - "optional": true, + "version": "24.2.10", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-popups/-/ej2-popups-24.2.10.tgz", + "integrity": "sha512-1BJZ05Ms2BfEkPWdpaCuzBe2DwYNUmz2Qz7ys3z+74a46vWWQANL1s8Xet9ApB7r4UR59jcKAxYfbI4lAU73ag==", "peer": true, "dependencies": { - "@syncfusion/ej2-base": "~24.1.41", - "@syncfusion/ej2-buttons": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.7", + "@syncfusion/ej2-buttons": "~24.2.7" + } + }, + "node_modules/@syncfusion/ej2-ribbon": { + "version": "24.2.8", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-ribbon/-/ej2-ribbon-24.2.8.tgz", + "integrity": "sha512-JaIVUqgk0Mzxh4W35W45wHi93c3upeVfkPPc3wmkfwXk0EKsNh7PrvDYjlE2KRPX5OF5QOLKUKYG5jj/Cb5pKQ==", + "peer": true, + "dependencies": { + "@syncfusion/ej2-base": "~24.2.7", + "@syncfusion/ej2-buttons": "~24.2.7", + "@syncfusion/ej2-dropdowns": "~24.2.8", + "@syncfusion/ej2-lists": "~24.2.8", + "@syncfusion/ej2-navigations": "~24.2.8", + "@syncfusion/ej2-popups": "~24.2.8", + "@syncfusion/ej2-splitbuttons": "~24.2.7" + } + }, + "node_modules/@syncfusion/ej2-ribbon": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-ribbon/-/ej2-ribbon-25.1.35.tgz", + "integrity": "sha512-pMG+SDXU7X8xPEtzIomUfKF2+PLNLaytrfrxXs6giTm7/ri7eziLCiTLl6L7K5jaH8vE30HQSxwKogNAdVMmDQ==", + "peer": true, + "dependencies": { + "@syncfusion/ej2-base": "~25.1.35", + "@syncfusion/ej2-buttons": "~25.1.35", + "@syncfusion/ej2-dropdowns": "~25.1.35", + "@syncfusion/ej2-lists": "~25.1.35", + "@syncfusion/ej2-navigations": "~25.1.35", + "@syncfusion/ej2-popups": "~25.1.35", + "@syncfusion/ej2-splitbuttons": "~25.1.35" + } + }, + "node_modules/@syncfusion/ej2-ribbon/node_modules/@syncfusion/ej2-base": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-base/-/ej2-base-25.1.35.tgz", + "integrity": "sha512-eH/zLft7j5jhbNquVNcKoDmlx+ZU/77mHAJwpG9Ad4+C/+7UcWlIi/RDORJ0QreosZM4gMyCYzxDAZ5QOI3txw==", + "peer": true, + "dependencies": { + "@syncfusion/ej2-icons": "~25.1.35" + }, + "bin": { + "syncfusion-license": "bin/syncfusion-license.js" + } + }, + "node_modules/@syncfusion/ej2-ribbon/node_modules/@syncfusion/ej2-buttons": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-buttons/-/ej2-buttons-25.1.35.tgz", + "integrity": "sha512-4a3+OAkHdaJTxRd/QJln7PglxDeRa9yGpnuFUDOUaA0sf7gvBKumBg5JP1llSpblKaK7JSRs42QOL/EG/d075g==", + "peer": true, + "dependencies": { + "@syncfusion/ej2-base": "~25.1.35" + } + }, + "node_modules/@syncfusion/ej2-ribbon/node_modules/@syncfusion/ej2-data": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-data/-/ej2-data-25.1.35.tgz", + "integrity": "sha512-eHWkoQcokKFiLUMpcw2IM1ul9v8HeRgIrUzowyWPpamuZASX8luczDy3VLR5AX0YeiE9aNv3QKsr04t4F1GRcQ==", + "peer": true, + "dependencies": { + "@syncfusion/ej2-base": "~25.1.35" + } + }, + "node_modules/@syncfusion/ej2-ribbon/node_modules/@syncfusion/ej2-dropdowns": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-dropdowns/-/ej2-dropdowns-25.1.35.tgz", + "integrity": "sha512-0P6t07FSGNzRlpm/Nsd63V+QKr58kgqjBdypDpsYmS5BKmimoLeWPboWdpi8lSWLZh4Mh4u+NM4WXXMyZjsg/A==", + "peer": true, + "dependencies": { + "@syncfusion/ej2-base": "~25.1.35", + "@syncfusion/ej2-data": "~25.1.35", + "@syncfusion/ej2-inputs": "~25.1.35", + "@syncfusion/ej2-lists": "~25.1.35", + "@syncfusion/ej2-navigations": "~25.1.35", + "@syncfusion/ej2-notifications": "~25.1.35", + "@syncfusion/ej2-popups": "~25.1.35" + } + }, + "node_modules/@syncfusion/ej2-ribbon/node_modules/@syncfusion/ej2-icons": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-icons/-/ej2-icons-25.1.35.tgz", + "integrity": "sha512-E8ypbeB9ISTsaj8Q29w3Ysh6HG35GOdTjfaU6JTCaZ9wP30q04B4WfN9lqcd42Q198qhynFAXd3lJyYev68aGw==", + "peer": true + }, + "node_modules/@syncfusion/ej2-ribbon/node_modules/@syncfusion/ej2-inputs": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-inputs/-/ej2-inputs-25.1.35.tgz", + "integrity": "sha512-vVU55vBalmNKI1kon3F2IM/yzatC/2IU+Hso2fp1pFO5OzNfySCOtnWkMypVYc/9+pAG6qxuPIg7GyqjsrsWRg==", + "peer": true, + "dependencies": { + "@syncfusion/ej2-base": "~25.1.35", + "@syncfusion/ej2-buttons": "~25.1.35", + "@syncfusion/ej2-popups": "~25.1.35", + "@syncfusion/ej2-splitbuttons": "~25.1.35" + } + }, + "node_modules/@syncfusion/ej2-ribbon/node_modules/@syncfusion/ej2-lists": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-lists/-/ej2-lists-25.1.35.tgz", + "integrity": "sha512-7aFOGU67t3V/AGTB/N4mU1eVGSYhPCwkPXsvsl4BN/YcrsthdC90AXbrKgUb3Hwbuynps+du/nEDH8ujK8LNRg==", + "peer": true, + "dependencies": { + "@syncfusion/ej2-base": "~25.1.35", + "@syncfusion/ej2-buttons": "~25.1.35", + "@syncfusion/ej2-data": "~25.1.35", + "@syncfusion/ej2-popups": "~25.1.35" + } + }, + "node_modules/@syncfusion/ej2-ribbon/node_modules/@syncfusion/ej2-navigations": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-navigations/-/ej2-navigations-25.1.35.tgz", + "integrity": "sha512-4VeoH70R16RnfzVzVa/urGNIH3g1WkBnBvasAWQPY/TQQ8umk0EDEY22+TEzkGRWb7zc8K6Km9nQ57NxbLdDiA==", + "peer": true, + "dependencies": { + "@syncfusion/ej2-base": "~25.1.35", + "@syncfusion/ej2-buttons": "~25.1.35", + "@syncfusion/ej2-data": "~25.1.35", + "@syncfusion/ej2-inputs": "~25.1.35", + "@syncfusion/ej2-lists": "~25.1.35", + "@syncfusion/ej2-popups": "~25.1.35" + } + }, + "node_modules/@syncfusion/ej2-ribbon/node_modules/@syncfusion/ej2-notifications": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-notifications/-/ej2-notifications-25.1.35.tgz", + "integrity": "sha512-ioSI36uCSA9hxB8fiUAvI0u7c2eIs1sw3kC0cfL2HbGHHOmhWjm4yoTIl13sKoXU6Sv2A2V3xsFAf97cBTjFvA==", + "peer": true, + "dependencies": { + "@syncfusion/ej2-base": "~25.1.35", + "@syncfusion/ej2-buttons": "~25.1.35", + "@syncfusion/ej2-popups": "~25.1.35" + } + }, + "node_modules/@syncfusion/ej2-ribbon/node_modules/@syncfusion/ej2-popups": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-popups/-/ej2-popups-25.1.35.tgz", + "integrity": "sha512-tuo2YpcnCWFZntR77Cy/8rrWWAgLgxiGQC2ffXD2fnwuw5+Sp04MagefyoriAOMglXQHvNh2e+9//pVDA0NcmA==", + "peer": true, + "dependencies": { + "@syncfusion/ej2-base": "~25.1.35", + "@syncfusion/ej2-buttons": "~25.1.35" + } + }, + "node_modules/@syncfusion/ej2-ribbon/node_modules/@syncfusion/ej2-splitbuttons": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-splitbuttons/-/ej2-splitbuttons-25.1.35.tgz", + "integrity": "sha512-S/MhCWHB59e8bm8ZRL896XxtQtNcyNNVcpclus8tsuN9sCiM7Dsg/HPtoZ04hZRgRs7nNJmyA0u+Z8E7HkaQHg==", + "peer": true, + "dependencies": { + "@syncfusion/ej2-base": "~25.1.35", + "@syncfusion/ej2-popups": "~25.1.35" } }, "node_modules/@syncfusion/ej2-ribbon": { @@ -1035,24 +1175,23 @@ } }, "node_modules/@syncfusion/ej2-splitbuttons": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-splitbuttons/-/ej2-splitbuttons-24.1.41.tgz", - "integrity": "sha512-Drbvk2aD37anSVeP4WRqzipZYobRPFpaitlNGjP+qLb0UDzo8IHNE99McPRCC9C8wwYp4QAxhBfCZDQRkdW8gg==", - "optional": true, + "version": "24.2.7", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-splitbuttons/-/ej2-splitbuttons-24.2.7.tgz", + "integrity": "sha512-2zoBRtjQUlVd3mawSZ8S7zOviypjNLb3ix7ktwWEvU5Ll8L/iWw7D9ps8JDITTIgB+ZupYoxl3OAQMvZ8PnHUQ==", "peer": true, "dependencies": { - "@syncfusion/ej2-base": "~24.1.41", - "@syncfusion/ej2-popups": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.7", + "@syncfusion/ej2-popups": "~24.2.5" } }, "node_modules/@syncfusion/ej2-svg-base": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-svg-base/-/ej2-svg-base-24.1.41.tgz", - "integrity": "sha512-yYJ0+Yhs+8ESjsDHLOGcVwrp6N12pqx371Ob1eyzFjJ524N1A2DcIOyDGiFTWh9S9Iv7TdiSmh3GlyI8aDAh3g==", + "version": "24.2.3", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-svg-base/-/ej2-svg-base-24.2.3.tgz", + "integrity": "sha512-1fQsvaq3tNtLqL3Rt5rsh6Dgp+DgMePhjVvj76ASaIZnrEKvZQOR4yOeTOKQmireIWNJra5S509uFDtWYQ67Aw==", "optional": true, "peer": true, "dependencies": { - "@syncfusion/ej2-base": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.3" } }, "node_modules/@tsconfig/node10": { @@ -6047,224 +6186,363 @@ } }, "@syncfusion/ej2-base": { - "version": "24.1.42", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-base/-/ej2-base-24.1.42.tgz", - "integrity": "sha512-3Zolyu6xA2pasid3Ttaf0qqQcEU/cQMJwuhaGa5vBnt1Xmo4oPkipUAsWLCtlfkmF/iUN9Hts3+8a4fBr4x3dA==", - "optional": true, + "version": "24.2.8", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-base/-/ej2-base-24.2.8.tgz", + "integrity": "sha512-GzTH2VELnmBFCrzfkGSTw7oALFNBYq6ysGDTAfpo0GIAd9Ge3yCTCU7wELJoKJhmg2I4RVgQlrZF5o7z7ajxTQ==", "peer": true, "requires": { - "@syncfusion/ej2-icons": "~24.1.41" + "@syncfusion/ej2-icons": "~24.2.3" } }, "@syncfusion/ej2-buttons": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-buttons/-/ej2-buttons-24.1.41.tgz", - "integrity": "sha512-hko5TLLCssu7O9/iJKlogCR9hP6faaE6H96pOQ1qpuemv85SxUVBbDoAzCkDUg4/2HlsMJMSHGZ9ZHrPGUZJHA==", - "optional": true, + "version": "24.2.7", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-buttons/-/ej2-buttons-24.2.7.tgz", + "integrity": "sha512-tHrl3zqhsgRD+lUZDAy7XmbRbNCZuIn588ip0cwFXHHqbk0eLJnd/PTBS5TodSp+VMpOeiHsu0IVbuZg1dXRwg==", "peer": true, "requires": { - "@syncfusion/ej2-base": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.7" } }, "@syncfusion/ej2-calendars": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-calendars/-/ej2-calendars-24.1.41.tgz", - "integrity": "sha512-rpTYU6TwqdTXyOfKKubeLKTkBDv4AbkCyi1W3fdMs6RmobozjmkgquzNZFsVlFwRMYjViShoyUlWptrQw4iUAw==", + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-calendars/-/ej2-calendars-24.2.9.tgz", + "integrity": "sha512-WyY+eTgHlPiNQ7WqCJfuI8mlsx9XuC7ywgwBNWojK18wmETETPZ2freTlo59khHfWSW5xqKKFXy2lVTtw5NYvw==", "optional": true, "peer": true, "requires": { - "@syncfusion/ej2-base": "~24.1.41", - "@syncfusion/ej2-buttons": "~24.1.41", - "@syncfusion/ej2-inputs": "~24.1.41", - "@syncfusion/ej2-lists": "~24.1.41", - "@syncfusion/ej2-popups": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.7", + "@syncfusion/ej2-buttons": "~24.2.7", + "@syncfusion/ej2-inputs": "~24.2.9", + "@syncfusion/ej2-lists": "~24.2.8", + "@syncfusion/ej2-popups": "~24.2.9" } }, "@syncfusion/ej2-charts": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-charts/-/ej2-charts-24.1.41.tgz", - "integrity": "sha512-FEsEsHdA3TDpQw0LhfYR4YFR9u0M7CoBhsc13UlEgs90r5QgqDQXw9AxDmHOO2HXaCQihueVDBeWPiH9emts/A==", + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-charts/-/ej2-charts-24.2.9.tgz", + "integrity": "sha512-zaw19XrMa0feDBk1RJldI99TMgRDoligeH4fbcxkP2PFR3ANdNmIYiWRakX/AwsAJSaSUOnvz/Lhv0q2y4/L2g==", "optional": true, "peer": true, "requires": { - "@syncfusion/ej2-base": "~24.1.41", - "@syncfusion/ej2-calendars": "~24.1.41", - "@syncfusion/ej2-data": "~24.1.41", - "@syncfusion/ej2-excel-export": "~24.1.41", - "@syncfusion/ej2-navigations": "~24.1.41", - "@syncfusion/ej2-pdf-export": "~24.1.41", - "@syncfusion/ej2-svg-base": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.7", + "@syncfusion/ej2-calendars": "~24.2.9", + "@syncfusion/ej2-data": "~24.2.3", + "@syncfusion/ej2-excel-export": "~24.2.4", + "@syncfusion/ej2-navigations": "~24.2.8", + "@syncfusion/ej2-pdf-export": "~24.2.3", + "@syncfusion/ej2-svg-base": "~24.2.3" } }, "@syncfusion/ej2-compression": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-compression/-/ej2-compression-24.1.41.tgz", - "integrity": "sha512-OO3Am1WXMi+6V25QG3iySmikWA2gXWgKh4B9p1L8nksUptrvfdNFJqzNEEdZWoF9ftOMWHcagwklbFATjxEgRw==", + "version": "24.2.3", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-compression/-/ej2-compression-24.2.3.tgz", + "integrity": "sha512-ZjDxhlxf2cWoRGLOVwYhEW/RUhzDtyGOZ2VlcG0KT0L4EFVdAHHKSY40urDtpCTWln4fW0Ki6KFDsM9gWnNLeQ==", "optional": true, "peer": true, "requires": { - "@syncfusion/ej2-file-utils": "~24.1.41" + "@syncfusion/ej2-file-utils": "~24.2.3" } }, "@syncfusion/ej2-data": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-data/-/ej2-data-24.1.41.tgz", - "integrity": "sha512-xKSaV7CaF8K37nIf9SuG6387mqXoNt+k4uqiAI1Xsp9Z+UkpEd8wm1skeW2qJao5AyxVhUhV6MtX9grO8udCjg==", - "optional": true, + "version": "24.2.3", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-data/-/ej2-data-24.2.3.tgz", + "integrity": "sha512-nZai/hmBuD2tAAXPF/oHZj5z6UfqjQ9PIlKvt+rOFdvQ5pOQHavv+OUpdUAeQPijgqzprnUVcmRlsn7XcS17bw==", "peer": true, "requires": { - "@syncfusion/ej2-base": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.3" } }, "@syncfusion/ej2-documenteditor": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-documenteditor/-/ej2-documenteditor-24.1.41.tgz", - "integrity": "sha512-QL7qYxQpW0NPMPQZKbCB5XwcKROV9tYyQaZqq78rS+YQxEMWGUHme9aI9utfC+nZiVm6GNfet3q7fPz6NIyalA==", + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-documenteditor/-/ej2-documenteditor-24.2.9.tgz", + "integrity": "sha512-DlloM0G3NdHHXj+0XsJ4aLk3fau4+2zbzB8a6YcdCqxIZSjuc2Gd9uywP9x2T/wXAHC3c0LhvFjTnc9OV+pOzQ==", "optional": true, "peer": true, "requires": { - "@syncfusion/ej2-base": "~24.1.41", - "@syncfusion/ej2-buttons": "~24.1.41", - "@syncfusion/ej2-calendars": "~24.1.41", - "@syncfusion/ej2-compression": "~24.1.41", - "@syncfusion/ej2-dropdowns": "~24.1.41", - "@syncfusion/ej2-file-utils": "~24.1.41", - "@syncfusion/ej2-inputs": "~24.1.41", - "@syncfusion/ej2-navigations": "~24.1.41", - "@syncfusion/ej2-office-chart": "~24.1.41", - "@syncfusion/ej2-popups": "~24.1.41", - "@syncfusion/ej2-splitbuttons": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.7", + "@syncfusion/ej2-buttons": "~24.2.7", + "@syncfusion/ej2-calendars": "~24.2.9", + "@syncfusion/ej2-compression": "~24.2.3", + "@syncfusion/ej2-dropdowns": "~24.2.9", + "@syncfusion/ej2-file-utils": "~24.2.3", + "@syncfusion/ej2-inputs": "~24.2.9", + "@syncfusion/ej2-navigations": "~24.2.8", + "@syncfusion/ej2-office-chart": "~24.2.3", + "@syncfusion/ej2-popups": "~24.2.9", + "@syncfusion/ej2-splitbuttons": "~24.2.7" } }, "@syncfusion/ej2-dropdowns": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-dropdowns/-/ej2-dropdowns-24.1.41.tgz", - "integrity": "sha512-oVNjjjhSvZ3HSAW+E0WadpxD2fmiCXXmrMHNPtVTv31EXQryNVzVrMvMcn6dWmrg052NOG5MpYhmWdrh/vuWxA==", - "optional": true, + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-dropdowns/-/ej2-dropdowns-24.2.9.tgz", + "integrity": "sha512-va8WauFI/LSIvhAvhqSGlGwrHWHV6d9SbkfJy+uQ6w6eDnNTzD9ZH+eUcu7bhSoNVHdOSjPIFbLh8Ea2ev4LEA==", "peer": true, "requires": { - "@syncfusion/ej2-base": "~24.1.41", - "@syncfusion/ej2-data": "~24.1.41", - "@syncfusion/ej2-inputs": "~24.1.41", - "@syncfusion/ej2-lists": "~24.1.41", - "@syncfusion/ej2-navigations": "~24.1.41", - "@syncfusion/ej2-notifications": "~24.1.41", - "@syncfusion/ej2-popups": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.7", + "@syncfusion/ej2-data": "~24.2.3", + "@syncfusion/ej2-inputs": "~24.2.9", + "@syncfusion/ej2-lists": "~24.2.8", + "@syncfusion/ej2-navigations": "~24.2.8", + "@syncfusion/ej2-notifications": "~24.2.4", + "@syncfusion/ej2-popups": "~24.2.9" } }, "@syncfusion/ej2-excel-export": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-excel-export/-/ej2-excel-export-24.1.41.tgz", - "integrity": "sha512-ieLWcOeHc4jIhfcrUA79m0C60g44bbM1O+BhequQB/GK9o7WjhD7TmRUYZSK/4jU1pm9tu+YI8+P18vjDxWIgw==", + "version": "24.2.4", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-excel-export/-/ej2-excel-export-24.2.4.tgz", + "integrity": "sha512-ppMKz6nCxoUQYlfI6iqv4pfyhb8ZZJlfkaTpgcj4oys/Oss6MgQgZrpVepyFBoW735NtvM0BOVrs6ZnAui03jg==", "optional": true, "peer": true, "requires": { - "@syncfusion/ej2-base": "~24.1.41", - "@syncfusion/ej2-compression": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.3", + "@syncfusion/ej2-compression": "~24.2.3" } }, "@syncfusion/ej2-file-utils": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-file-utils/-/ej2-file-utils-24.1.41.tgz", - "integrity": "sha512-lMCSB9kZrn2qe7UvFq8N2xERCu8sCg+5LRESjlsB4+k+02MLhponHmMzAPbvMr3DJ5ctb7A1dihAdQT0Mwd3Jg==", + "version": "24.2.3", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-file-utils/-/ej2-file-utils-24.2.3.tgz", + "integrity": "sha512-kPejWNjWoougUu/tsxh6ywKR/cr5+2tIZO1BUWlTO+XyFk/uolZ4Xx14tGVnrLpzl4+DaSLfv73b6VDvqpIbzg==", "optional": true, "peer": true }, "@syncfusion/ej2-icons": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-icons/-/ej2-icons-24.1.41.tgz", - "integrity": "sha512-r44Xr0QC1iGP6Ed5UVNyfIa3lmcDn680nzNoUbykUv02JaJv6nF0OQZeZNjjY3m8YrFhYCHdms0h9A9sU7c9/Q==", - "optional": true, + "version": "24.2.3", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-icons/-/ej2-icons-24.2.3.tgz", + "integrity": "sha512-JdQ7w2SiiUUXZFrmX0j3+0iQZdT+Z5NP7jb1zTKDAiTGB3IjcSTQc8MtPmORTG4vvG6lOSLYHrn2HtP7mqvlEQ==", "peer": true }, "@syncfusion/ej2-inputs": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-inputs/-/ej2-inputs-24.1.41.tgz", - "integrity": "sha512-scVtCR6XMrdr2RQe0HUG+y7Mdr4hnYrNJAYntUJgO0gxMiWjHku6UG+9FBruA3rC7INvNsBviCqvZIHyTXz4NA==", - "optional": true, + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-inputs/-/ej2-inputs-24.2.9.tgz", + "integrity": "sha512-inUPQt387emSR12p8hHWVQUA4q2oH8kcMPNe8mc06TN5wgPnSDYjciV2oTam9xkOchOlYrRmL0gsV6a72ilYPw==", "peer": true, "requires": { - "@syncfusion/ej2-base": "~24.1.41", - "@syncfusion/ej2-buttons": "~24.1.41", - "@syncfusion/ej2-popups": "~24.1.41", - "@syncfusion/ej2-splitbuttons": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.7", + "@syncfusion/ej2-buttons": "~24.2.7", + "@syncfusion/ej2-popups": "~24.2.9", + "@syncfusion/ej2-splitbuttons": "~24.2.7" } }, "@syncfusion/ej2-lists": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-lists/-/ej2-lists-24.1.41.tgz", - "integrity": "sha512-TZrHBq02s2vxVwqjLUxx+iTGP8X93eJCkCwlhjajnjw7jU5Yireb//FVORwTzWuwlrVc2tEkDiGW3WYhnowVMg==", - "optional": true, + "version": "24.2.8", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-lists/-/ej2-lists-24.2.8.tgz", + "integrity": "sha512-K1HXJL2Dz02XmTTWxZAxJ6SLJwp6pwcVLXi7L5T5NHcfOvSrPmL+vb1ZLoABHe+7Cm2snTaINdQky9cmvgBK6w==", "peer": true, "requires": { - "@syncfusion/ej2-base": "~24.1.41", - "@syncfusion/ej2-buttons": "~24.1.41", - "@syncfusion/ej2-data": "~24.1.41", - "@syncfusion/ej2-popups": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.7", + "@syncfusion/ej2-buttons": "~24.2.7", + "@syncfusion/ej2-data": "~24.2.3", + "@syncfusion/ej2-popups": "~24.2.8" } }, "@syncfusion/ej2-locale": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-locale/-/ej2-locale-24.1.41.tgz", - "integrity": "sha512-Um8HWtIbIj8iMHX5yStSx3xFjj0axCeOxrHJV1f6VDCvCleF8S/aERqp4dxNm+mJQTs6aNUyWSiBIs7ErCZdWw==", + "version": "24.2.7", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-locale/-/ej2-locale-24.2.7.tgz", + "integrity": "sha512-87O6fYjRXmV8VkRmzJVg/dPYtWlTYuZqbgpqFKN8M19pEkiryy0tVKerGSIkcoO7Bq/h8yVSShO+mLl6nv7EhQ==", "peer": true }, "@syncfusion/ej2-navigations": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-navigations/-/ej2-navigations-24.1.41.tgz", - "integrity": "sha512-l551sMOEpXeTSkaWNNEhmkSw5vGYIX8lURuywyUnF7L1QMbfZwhiy2fLYopcRqFOOXFsLchGXzaHBrcfcMtF2g==", - "optional": true, + "version": "24.2.8", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-navigations/-/ej2-navigations-24.2.8.tgz", + "integrity": "sha512-dQ3Xnjvg1sf595M7EvDQmM10iNFU1mlqUZ/J9cdTMGoyiMeat5DtTTWVOc1NShFyJjCqHlfg5c8LNfqKRerIcA==", "peer": true, "requires": { - "@syncfusion/ej2-base": "~24.1.41", - "@syncfusion/ej2-buttons": "~24.1.41", - "@syncfusion/ej2-data": "~24.1.41", - "@syncfusion/ej2-inputs": "~24.1.41", - "@syncfusion/ej2-lists": "~24.1.41", - "@syncfusion/ej2-popups": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.7", + "@syncfusion/ej2-buttons": "~24.2.7", + "@syncfusion/ej2-data": "~24.2.3", + "@syncfusion/ej2-inputs": "~24.2.7", + "@syncfusion/ej2-lists": "~24.2.8", + "@syncfusion/ej2-popups": "~24.2.8" } }, "@syncfusion/ej2-notifications": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-notifications/-/ej2-notifications-24.1.41.tgz", - "integrity": "sha512-equJ8+DrZj2yaGyAxs7GiGWtH14ns74RFj0q2ma/SCGQUNyUARgDiMdF5NlN4btnE3UGoAtKk5ikW8boole8Bw==", - "optional": true, + "version": "24.2.4", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-notifications/-/ej2-notifications-24.2.4.tgz", + "integrity": "sha512-14oBybExHpxSF88p5tbMvURoUnVNOj4nBDZJo1fnU8fb8KxHvmxtSm5ObLwe4nGiPZ/1QspGyLwL2GLKM0Ncig==", "peer": true, "requires": { - "@syncfusion/ej2-base": "~24.1.41", - "@syncfusion/ej2-buttons": "~24.1.41", - "@syncfusion/ej2-popups": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.3", + "@syncfusion/ej2-buttons": "~24.2.3", + "@syncfusion/ej2-popups": "~24.2.3" } }, "@syncfusion/ej2-office-chart": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-office-chart/-/ej2-office-chart-24.1.41.tgz", - "integrity": "sha512-NYVwyiUzp/ff4SMufz2tqdx9oWUL99pHJYuH5qpmI3NoEOPpOoviX/8HI/GzvBBamFeZTeZIVBwbvYRwoPQX9w==", + "version": "24.2.3", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-office-chart/-/ej2-office-chart-24.2.3.tgz", + "integrity": "sha512-lpQp6YMXuf6THswcn0a3hKXXK2WNgb1TMXuVxbsA1JYz3aeuUe00IM9o94Hi9uI3BJVS/ZIRy3yDW6ycEZJnKA==", "optional": true, "peer": true, "requires": { - "@syncfusion/ej2-charts": "~24.1.41" + "@syncfusion/ej2-charts": "~24.2.3" } }, "@syncfusion/ej2-pdf-export": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-pdf-export/-/ej2-pdf-export-24.1.41.tgz", - "integrity": "sha512-AsPl0mHerlNPVEy+qm9CDxneDIAOIMVPxlVTcxhXeOwEugdkPAF9vTzx5jX3hoMLqnpnpxXq/FjyXcz4+fapbw==", + "version": "24.2.3", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-pdf-export/-/ej2-pdf-export-24.2.3.tgz", + "integrity": "sha512-h6fmsSxQA4BuwuYusPruQYUrdyH1NJIXMrcRN0zAhORPEKDeLy/jp1qiBILBtjGFI3JWxVRXfz4Fm6Ln7j766A==", "optional": true, "peer": true, "requires": { - "@syncfusion/ej2-compression": "~24.1.41" + "@syncfusion/ej2-compression": "~24.2.3" } }, "@syncfusion/ej2-popups": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-popups/-/ej2-popups-24.1.41.tgz", - "integrity": "sha512-SSx3ZfdRAuSLjoo2/qU4PLLmbo5L+x1LqyxgxNq2bflRhx3Xdk51iEdS00ihTjBoMweE6KS3nPGHI8krOzv44A==", - "optional": true, + "version": "24.2.10", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-popups/-/ej2-popups-24.2.10.tgz", + "integrity": "sha512-1BJZ05Ms2BfEkPWdpaCuzBe2DwYNUmz2Qz7ys3z+74a46vWWQANL1s8Xet9ApB7r4UR59jcKAxYfbI4lAU73ag==", + "peer": true, + "requires": { + "@syncfusion/ej2-base": "~24.2.7", + "@syncfusion/ej2-buttons": "~24.2.7" + } + }, + "@syncfusion/ej2-ribbon": { + "version": "24.2.8", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-ribbon/-/ej2-ribbon-24.2.8.tgz", + "integrity": "sha512-JaIVUqgk0Mzxh4W35W45wHi93c3upeVfkPPc3wmkfwXk0EKsNh7PrvDYjlE2KRPX5OF5QOLKUKYG5jj/Cb5pKQ==", + "peer": true, + "requires": { + "@syncfusion/ej2-base": "~24.2.7", + "@syncfusion/ej2-buttons": "~24.2.7", + "@syncfusion/ej2-dropdowns": "~24.2.8", + "@syncfusion/ej2-lists": "~24.2.8", + "@syncfusion/ej2-navigations": "~24.2.8", + "@syncfusion/ej2-popups": "~24.2.8", + "@syncfusion/ej2-splitbuttons": "~24.2.7" + } + }, + "@syncfusion/ej2-ribbon": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-ribbon/-/ej2-ribbon-25.1.35.tgz", + "integrity": "sha512-pMG+SDXU7X8xPEtzIomUfKF2+PLNLaytrfrxXs6giTm7/ri7eziLCiTLl6L7K5jaH8vE30HQSxwKogNAdVMmDQ==", "peer": true, "requires": { - "@syncfusion/ej2-base": "~24.1.41", - "@syncfusion/ej2-buttons": "~24.1.41" + "@syncfusion/ej2-base": "~25.1.35", + "@syncfusion/ej2-buttons": "~25.1.35", + "@syncfusion/ej2-dropdowns": "~25.1.35", + "@syncfusion/ej2-lists": "~25.1.35", + "@syncfusion/ej2-navigations": "~25.1.35", + "@syncfusion/ej2-popups": "~25.1.35", + "@syncfusion/ej2-splitbuttons": "~25.1.35" + }, + "dependencies": { + "@syncfusion/ej2-base": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-base/-/ej2-base-25.1.35.tgz", + "integrity": "sha512-eH/zLft7j5jhbNquVNcKoDmlx+ZU/77mHAJwpG9Ad4+C/+7UcWlIi/RDORJ0QreosZM4gMyCYzxDAZ5QOI3txw==", + "peer": true, + "requires": { + "@syncfusion/ej2-icons": "~25.1.35" + } + }, + "@syncfusion/ej2-buttons": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-buttons/-/ej2-buttons-25.1.35.tgz", + "integrity": "sha512-4a3+OAkHdaJTxRd/QJln7PglxDeRa9yGpnuFUDOUaA0sf7gvBKumBg5JP1llSpblKaK7JSRs42QOL/EG/d075g==", + "peer": true, + "requires": { + "@syncfusion/ej2-base": "~25.1.35" + } + }, + "@syncfusion/ej2-data": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-data/-/ej2-data-25.1.35.tgz", + "integrity": "sha512-eHWkoQcokKFiLUMpcw2IM1ul9v8HeRgIrUzowyWPpamuZASX8luczDy3VLR5AX0YeiE9aNv3QKsr04t4F1GRcQ==", + "peer": true, + "requires": { + "@syncfusion/ej2-base": "~25.1.35" + } + }, + "@syncfusion/ej2-dropdowns": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-dropdowns/-/ej2-dropdowns-25.1.35.tgz", + "integrity": "sha512-0P6t07FSGNzRlpm/Nsd63V+QKr58kgqjBdypDpsYmS5BKmimoLeWPboWdpi8lSWLZh4Mh4u+NM4WXXMyZjsg/A==", + "peer": true, + "requires": { + "@syncfusion/ej2-base": "~25.1.35", + "@syncfusion/ej2-data": "~25.1.35", + "@syncfusion/ej2-inputs": "~25.1.35", + "@syncfusion/ej2-lists": "~25.1.35", + "@syncfusion/ej2-navigations": "~25.1.35", + "@syncfusion/ej2-notifications": "~25.1.35", + "@syncfusion/ej2-popups": "~25.1.35" + } + }, + "@syncfusion/ej2-icons": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-icons/-/ej2-icons-25.1.35.tgz", + "integrity": "sha512-E8ypbeB9ISTsaj8Q29w3Ysh6HG35GOdTjfaU6JTCaZ9wP30q04B4WfN9lqcd42Q198qhynFAXd3lJyYev68aGw==", + "peer": true + }, + "@syncfusion/ej2-inputs": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-inputs/-/ej2-inputs-25.1.35.tgz", + "integrity": "sha512-vVU55vBalmNKI1kon3F2IM/yzatC/2IU+Hso2fp1pFO5OzNfySCOtnWkMypVYc/9+pAG6qxuPIg7GyqjsrsWRg==", + "peer": true, + "requires": { + "@syncfusion/ej2-base": "~25.1.35", + "@syncfusion/ej2-buttons": "~25.1.35", + "@syncfusion/ej2-popups": "~25.1.35", + "@syncfusion/ej2-splitbuttons": "~25.1.35" + } + }, + "@syncfusion/ej2-lists": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-lists/-/ej2-lists-25.1.35.tgz", + "integrity": "sha512-7aFOGU67t3V/AGTB/N4mU1eVGSYhPCwkPXsvsl4BN/YcrsthdC90AXbrKgUb3Hwbuynps+du/nEDH8ujK8LNRg==", + "peer": true, + "requires": { + "@syncfusion/ej2-base": "~25.1.35", + "@syncfusion/ej2-buttons": "~25.1.35", + "@syncfusion/ej2-data": "~25.1.35", + "@syncfusion/ej2-popups": "~25.1.35" + } + }, + "@syncfusion/ej2-navigations": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-navigations/-/ej2-navigations-25.1.35.tgz", + "integrity": "sha512-4VeoH70R16RnfzVzVa/urGNIH3g1WkBnBvasAWQPY/TQQ8umk0EDEY22+TEzkGRWb7zc8K6Km9nQ57NxbLdDiA==", + "peer": true, + "requires": { + "@syncfusion/ej2-base": "~25.1.35", + "@syncfusion/ej2-buttons": "~25.1.35", + "@syncfusion/ej2-data": "~25.1.35", + "@syncfusion/ej2-inputs": "~25.1.35", + "@syncfusion/ej2-lists": "~25.1.35", + "@syncfusion/ej2-popups": "~25.1.35" + } + }, + "@syncfusion/ej2-notifications": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-notifications/-/ej2-notifications-25.1.35.tgz", + "integrity": "sha512-ioSI36uCSA9hxB8fiUAvI0u7c2eIs1sw3kC0cfL2HbGHHOmhWjm4yoTIl13sKoXU6Sv2A2V3xsFAf97cBTjFvA==", + "peer": true, + "requires": { + "@syncfusion/ej2-base": "~25.1.35", + "@syncfusion/ej2-buttons": "~25.1.35", + "@syncfusion/ej2-popups": "~25.1.35" + } + }, + "@syncfusion/ej2-popups": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-popups/-/ej2-popups-25.1.35.tgz", + "integrity": "sha512-tuo2YpcnCWFZntR77Cy/8rrWWAgLgxiGQC2ffXD2fnwuw5+Sp04MagefyoriAOMglXQHvNh2e+9//pVDA0NcmA==", + "peer": true, + "requires": { + "@syncfusion/ej2-base": "~25.1.35", + "@syncfusion/ej2-buttons": "~25.1.35" + } + }, + "@syncfusion/ej2-splitbuttons": { + "version": "25.1.35", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-splitbuttons/-/ej2-splitbuttons-25.1.35.tgz", + "integrity": "sha512-S/MhCWHB59e8bm8ZRL896XxtQtNcyNNVcpclus8tsuN9sCiM7Dsg/HPtoZ04hZRgRs7nNJmyA0u+Z8E7HkaQHg==", + "peer": true, + "requires": { + "@syncfusion/ej2-base": "~25.1.35", + "@syncfusion/ej2-popups": "~25.1.35" + } + } } }, "@syncfusion/ej2-ribbon": { @@ -6402,24 +6680,23 @@ } }, "@syncfusion/ej2-splitbuttons": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-splitbuttons/-/ej2-splitbuttons-24.1.41.tgz", - "integrity": "sha512-Drbvk2aD37anSVeP4WRqzipZYobRPFpaitlNGjP+qLb0UDzo8IHNE99McPRCC9C8wwYp4QAxhBfCZDQRkdW8gg==", - "optional": true, + "version": "24.2.7", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-splitbuttons/-/ej2-splitbuttons-24.2.7.tgz", + "integrity": "sha512-2zoBRtjQUlVd3mawSZ8S7zOviypjNLb3ix7ktwWEvU5Ll8L/iWw7D9ps8JDITTIgB+ZupYoxl3OAQMvZ8PnHUQ==", "peer": true, "requires": { - "@syncfusion/ej2-base": "~24.1.41", - "@syncfusion/ej2-popups": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.7", + "@syncfusion/ej2-popups": "~24.2.5" } }, "@syncfusion/ej2-svg-base": { - "version": "24.1.41", - "resolved": "https://registry.npmjs.org/@syncfusion/ej2-svg-base/-/ej2-svg-base-24.1.41.tgz", - "integrity": "sha512-yYJ0+Yhs+8ESjsDHLOGcVwrp6N12pqx371Ob1eyzFjJ524N1A2DcIOyDGiFTWh9S9Iv7TdiSmh3GlyI8aDAh3g==", + "version": "24.2.3", + "resolved": "https://registry.npmjs.org/@syncfusion/ej2-svg-base/-/ej2-svg-base-24.2.3.tgz", + "integrity": "sha512-1fQsvaq3tNtLqL3Rt5rsh6Dgp+DgMePhjVvj76ASaIZnrEKvZQOR4yOeTOKQmireIWNJra5S509uFDtWYQ67Aw==", "optional": true, "peer": true, "requires": { - "@syncfusion/ej2-base": "~24.1.41" + "@syncfusion/ej2-base": "~24.2.3" } }, "@tsconfig/node10": { diff --git a/package.json b/package.json index 01f8769..45d4560 100644 --- a/package.json +++ b/package.json @@ -47,9 +47,9 @@ "vitest": "^0.29.8" }, "peerDependencies": { - "@syncfusion/ej2-documenteditor": ">=23.2", - "@syncfusion/ej2-locale": ">=23.1", - "@syncfusion/ej2-ribbon": ">=24.1", + "@syncfusion/ej2-documenteditor": ">=24.2", + "@syncfusion/ej2-locale": ">=24.2", + "@syncfusion/ej2-ribbon": ">=24.2", "tinymce": ">=6.5" }, "peerDependenciesMeta": { diff --git a/src/editor/formatter.ts b/src/editor/formatter.ts index c79fdee..971785e 100644 --- a/src/editor/formatter.ts +++ b/src/editor/formatter.ts @@ -106,9 +106,6 @@ export class IaraEditorInferenceFormatter { return a.replace(new RegExp(`(por|x) ${oldText}`, "gui"), `x ${newText}`); }, text); - //convert the 'por' before or after a number and return the formatted expression without a space ex:1x1 - text = text.replace(/(\d+(?:,\d+)?) (por|x) (?=\d+(?:,\d+)?)/giu, "$1x"); - return text; } diff --git a/src/editor/index.ts b/src/editor/index.ts index 3d24c8a..066355c 100644 --- a/src/editor/index.ts +++ b/src/editor/index.ts @@ -1,9 +1,9 @@ -import { DocumentEditorContainer } from "@syncfusion/ej2-documenteditor"; -import { Editor as TinymceEditor } from "tinymce"; import { IaraSpeechRecognition, IaraSpeechRecognitionDetail } from "../speech"; import { IaraEditorInferenceFormatter } from "./formatter"; import { IaraEditorStyleManager } from "./style"; +import { IaraEditorNavigationFieldManager } from "./navigationFields"; + export interface IaraEditorConfig { darkMode: boolean; font?: { @@ -13,24 +13,27 @@ export interface IaraEditorConfig { size: number; }; saveReport: boolean; + zoomFactor: string; } export abstract class EditorAdapter { public onIaraCommand?: (command: string) => void; - + public iaraRecognizes = true; protected abstract _styleManager: IaraEditorStyleManager; + protected abstract _navigationFieldManager: IaraEditorNavigationFieldManager; protected static DefaultConfig: IaraEditorConfig = { darkMode: false, saveReport: true, + zoomFactor: "100%", }; - protected _inferenceFormatter: IaraEditorInferenceFormatter; private _listeners = [ { key: "iaraSpeechRecognitionResult", callback: (event?: CustomEvent) => { - if (event?.detail) this.insertInference(event.detail); + if (event?.detail && this.iaraRecognizes) + this.insertInference(event.detail); }, }, { @@ -61,7 +64,6 @@ export abstract class EditorAdapter { ]; constructor( - protected _editorContainer: DocumentEditorContainer | TinymceEditor, protected _recognition: IaraSpeechRecognition, protected _config: IaraEditorConfig = EditorAdapter.DefaultConfig ) { @@ -70,42 +72,46 @@ export abstract class EditorAdapter { this._initListeners(); this._recognition.internal.settings.replaceCommandActivationStringBeforeCallback = true; - if (this._config.saveReport && !this._recognition.report["_key"]) { - if (this._recognition.ready) this.beginReport(); - else { - this._recognition.addEventListener("iaraSpeechRecognitionReady", () => { - this.beginReport(); - }); - } - } } abstract blockEditorWhileSpeaking(status: boolean): void; abstract clearReport(): void; - abstract copyReport(): Promise; + abstract copyReport(): Promise; abstract insertInference(inference: IaraSpeechRecognitionDetail): void; abstract getEditorContent(): Promise<[string, string, string, string?]>; abstract print(): void; - beginReport(): string | void { + async beginReport(): Promise { if (!this._config.saveReport) return; - return this._recognition.beginReport({ richText: "", text: "" }); + return this._recognition.report.begin("", ""); } async finishReport(): Promise { if (!this._config.saveReport) return; - await this.copyReport(); + const content = await this.copyReport(); this.clearReport(); - this._recognition.finishReport(); + await this._recognition.report.finish(content[0], content[1]); + } + + hasEmptyRequiredFields(): boolean { + return this._navigationFieldManager.hasEmptyRequiredFields(); } private _initCommands(): void { this._recognition.commands.add("iara copiar laudo", async () => { + if (this.hasEmptyRequiredFields()) { + this.onIaraCommand?.("required fields to copy"); + return; + } this._recognition.stop(); await this.copyReport(); this.onIaraCommand?.("iara copiar laudo"); }); this._recognition.commands.add("iara finalizar laudo", async () => { + if (this.hasEmptyRequiredFields()) { + this.onIaraCommand?.("required fields to finish"); + return; + } this._recognition.stop(); await this.finishReport(); this.onIaraCommand?.("iara finalizar laudo"); @@ -125,6 +131,27 @@ export abstract class EditorAdapter { this._recognition.commands.add("iara imprimir", () => { this.print(); }); + this._recognition.commands.add("iara próximo campo", () => { + this._navigationFieldManager.nextField(); + }); + this._recognition.commands.add("iara campo anterior", () => { + this._navigationFieldManager.previousField(); + }); + this._recognition.commands.add("next", () => { + this._navigationFieldManager.nextField(); + }); + this._recognition.commands.add( + `buscar (\\p{Letter}+)`, + (detail, command, param, groups) => { + try { + this._navigationFieldManager.goToField(groups ? groups[1] : ""); + } catch (e) { + this.onIaraCommand?.("buscar"); + } finally { + console.info(detail, command, param); + } + } + ); } private _initListeners(): void { diff --git a/src/editor/navigationFields.ts b/src/editor/navigationFields.ts new file mode 100644 index 0000000..19cfc82 --- /dev/null +++ b/src/editor/navigationFields.ts @@ -0,0 +1,17 @@ +import type { IaraSpeechRecognition } from "../speech"; + +export abstract class IaraEditorNavigationFieldManager { + abstract nextField(): void; + abstract previousField(): void; + abstract goToField(title: string): void; + abstract hasEmptyRequiredFields(): boolean; + + constructor(private _recognition: IaraSpeechRecognition) { + this._recognition.addEventListener("iaraSpeechMikeForwardButtonPress", () => + this.nextField() + ); + this._recognition.addEventListener("iaraSpeechMikeRewindButtonPress", () => + this.previousField() + ); + } +} diff --git a/src/syncfusion/content.ts b/src/syncfusion/content.ts index b5bf4fc..4a290b7 100644 --- a/src/syncfusion/content.ts +++ b/src/syncfusion/content.ts @@ -1,5 +1,4 @@ import { DocumentEditor, ImageFormat } from "@syncfusion/ej2-documenteditor"; -import { IaraSpeechRecognition } from "../speech"; import { PdfBitmap, PdfDocument, @@ -11,17 +10,17 @@ import { import { IaraSyncfusionConfig } from "."; export enum IaraSyncfusionContentTypes { - SFDT = "SFDT", - HTML = "HTML", - RTF = "RTF", + SFDT = "sfdt", + HTML = "html", + RTF = "rtf", } export class IaraSFDT { public html: string | undefined; + public plainText: string | undefined; public rtf: string | undefined; - public pdf: string | undefined; - constructor(public value: string, private _authHeaders: HeadersInit) {} + constructor(public value: string, private _editor: DocumentEditor) {} static detectContentType(content: string): IaraSyncfusionContentTypes { if (content.startsWith("{\\rtf")) return IaraSyncfusionContentTypes.RTF; @@ -31,56 +30,44 @@ export class IaraSFDT { else throw new Error("Content type not recognized."); } - static async fromContent(content: string, authHeaders: HeadersInit) { + static async fromContent(content: string, editor: DocumentEditor) { const contentType = IaraSFDT.detectContentType(content); - switch (contentType) { - case IaraSyncfusionContentTypes.SFDT: - return new IaraSFDT(content, authHeaders); - case IaraSyncfusionContentTypes.HTML: - return IaraSFDT.fromHtml(content, authHeaders); - case IaraSyncfusionContentTypes.RTF: - return IaraSFDT.fromRtf(content, authHeaders); - } + if (contentType === IaraSyncfusionContentTypes.SFDT) + return new IaraSFDT(content, editor); + else return IaraSFDT.import(content, editor, contentType); } - static async fromEditor(editor: DocumentEditor, authHeaders: HeadersInit) { + static async fromEditor(editor: DocumentEditor) { const value: string = await editor .saveAsBlob("Sfdt") .then((blob: Blob) => blob.text()); - return new IaraSFDT(value, authHeaders); + return new IaraSFDT(value, editor); } - static async fromHtml(content: string, authHeaders: HeadersInit) { - content = content.replace(/
/g, "
"); - const response = await fetch( - "https://api.iarahealth.com/speech/syncfusion/html_to_sfdt/", - { - method: "POST", - headers: { - "Content-Type": "application/json", - ...authHeaders, - }, - body: JSON.stringify({ html: content }), - } + static async import( + content: string, + editor: DocumentEditor, + contentType?: IaraSyncfusionContentTypes + ) { + if (!contentType) contentType = IaraSFDT.detectContentType(content); + if (contentType === IaraSyncfusionContentTypes.HTML) + content = content.replace(/
/g, "
"); + const mimeType = + contentType === IaraSyncfusionContentTypes.SFDT + ? "application/json" + : `text/${contentType}`; + const formData = new FormData(); + formData.append( + "Files", + new Blob([content], { type: mimeType }), + `file.${contentType}` ); - const responseText = await response.text(); - if (!response.ok) { - throw new Error(responseText); - } - - return new IaraSFDT(responseText, authHeaders); - } - static async fromRtf(content: string, authHeaders: HeadersInit) { const response = await fetch( - "https://api.iarahealth.com/speech/syncfusion/rtf_to_sfdt/", + "https://api.iarahealth.com/speech/syncfusion/api/documenteditor/Import", { method: "POST", - headers: { - "Content-Type": "application/json", - ...authHeaders, - }, - body: JSON.stringify({ rtf: content }), + body: formData, } ); const responseText = await response.text(); @@ -88,31 +75,29 @@ export class IaraSFDT { throw new Error(responseText); } - return new IaraSFDT(responseText, authHeaders); + return new IaraSFDT(responseText, editor); } - static async toHtml( - content: string, - authHeaders: HeadersInit - ): Promise { + static async toHtml(content: string): Promise { const response = await fetch( - "https://api.iarahealth.com/speech/syncfusion/sfdt_to_html/", + "https://api.iarahealth.com/speech/syncfusion/api/documenteditor/ExportSFDT/", { method: "POST", headers: { "Content-Type": "application/json", - ...authHeaders, }, - body: content, + body: JSON.stringify({ + Content: content, + FileName: "file.html", + }), } ); - const responseJson = await response.json(); + const responseText = await response.text(); if (!response.ok) { - throw new Error(responseJson); + throw new Error(responseText); } - let { html } = responseJson; - html = responseJson.html.replace( + const html = responseText.replace( ``, "" ); @@ -120,28 +105,26 @@ export class IaraSFDT { return html; } - static async toRtf( - content: string, - authHeaders: HeadersInit - ): Promise { + static async toRtf(content: string): Promise { const response = await fetch( - "https://api.iarahealth.com/speech/syncfusion/sfdt_to_rtf/", + "https://api.iarahealth.com/speech/syncfusion/api/documenteditor/ExportSFDT/", { method: "POST", headers: { "Content-Type": "application/json", - ...authHeaders, }, - body: content, + body: JSON.stringify({ + Content: content, + FileName: "file.rtf", + }), } ); - const responseJson = await response.json(); + const responseText = await response.text(); if (!response.ok) { - throw new Error(responseJson); + throw new Error(responseText); } - const { rtf } = responseJson; - return rtf; + return responseText; } static toPdf(content: any, config?: IaraSyncfusionConfig) { @@ -208,14 +191,27 @@ export class IaraSFDT { } } + static async editorToPlainText(editor: DocumentEditor): Promise { + const plainText = await editor + .saveAsBlob("Txt") + .then((blob: Blob) => blob.text()); + return plainText; + } + async toHtml(): Promise { - return this.html - ? this.html - : IaraSFDT.toHtml(this.value, this._authHeaders); + if (!this.html) this.html = await IaraSFDT.toHtml(this.value); + return this.html; } async toRtf(): Promise { - return this.rtf ? this.rtf : IaraSFDT.toRtf(this.value, this._authHeaders); + if (!this.rtf) this.rtf = await IaraSFDT.toRtf(this.value); + return this.rtf; + } + + async toPlainText(): Promise { + if (!this.plainText) + this.plainText = await IaraSFDT.editorToPlainText(this._editor); + return this.plainText; } toString(): string { @@ -224,26 +220,31 @@ export class IaraSFDT { } export class IaraSyncfusionEditorContentManager { - private _isPlainTextDirty = true; - private _isSfdtDirty = true; - private _plainText: string | undefined; + private _isDirty = true; private _sfdt: IaraSFDT | undefined; - constructor( - private _editor: DocumentEditor, - private _recognition: IaraSpeechRecognition, - onContentChange: () => void - ) { + constructor(private _editor: DocumentEditor, onContentChange: () => void) { this._editor.contentChange = () => { this._onContentChange(); onContentChange(); }; } + async fromContent(content: string) { + this._sfdt = await IaraSFDT.fromContent(content, this._editor); + return this._sfdt; + } + + async fromEditor() { + const sfdt = await IaraSFDT.fromEditor(this._editor); + this._sfdt = sfdt; + return this._sfdt; + } + async getContent(): Promise<[string, string, string, string]> { const sfdt = await this._getSfdtContent(); return Promise.all([ - this.getPlainTextContent(), + sfdt.toPlainText(), sfdt.toHtml(), sfdt.toRtf(), sfdt.value, @@ -255,8 +256,9 @@ export class IaraSyncfusionEditorContentManager { return sfdt.toHtml(); } - getPlainTextContent(): Promise { - return this._getPlainTextContent(); + async getPlainTextContent(): Promise { + const sfdt = await this._getSfdtContent(); + return sfdt.toPlainText(); } async getRtfContent(): Promise { @@ -268,33 +270,20 @@ export class IaraSyncfusionEditorContentManager { return this._getSfdtContent(); } + import(content: string, contentType?: IaraSyncfusionContentTypes) { + return IaraSFDT.import(content, this._editor, contentType); + } + private async _getSfdtContent(): Promise { - if (this._isSfdtDirty) { - this._isSfdtDirty = false; - this._sfdt = await IaraSFDT.fromEditor( - this._editor, - this._recognition.internal.iaraAPIMandatoryHeaders as HeadersInit - ); + if (this._isDirty) { + this._isDirty = false; + await this.fromEditor(); } if (!this._sfdt) throw new Error("Invalid SFDT content"); - return this._sfdt; } - private async _getPlainTextContent(): Promise { - if (this._isPlainTextDirty) { - this._isPlainTextDirty = false; - this._plainText = await this._editor - .saveAsBlob("Txt") - .then((blob: Blob) => blob.text()); - } - if (!this._plainText) throw new Error("Invalid plain text content"); - - return this._plainText; - } - private _onContentChange(): void { - this._isPlainTextDirty = true; - this._isSfdtDirty = true; + this._isDirty = true; } } diff --git a/src/syncfusion/contextMenu/index.ts b/src/syncfusion/contextMenu/index.ts new file mode 100644 index 0000000..a6dc8ae --- /dev/null +++ b/src/syncfusion/contextMenu/index.ts @@ -0,0 +1,65 @@ +import { + CustomContentMenuEventArgs, + DocumentEditor, +} from "@syncfusion/ej2-documenteditor"; +import { MenuItemModel } from "@syncfusion/ej2-navigations"; +import { IaraSyncfusionNavigationFieldManager } from "../navigationFields"; + +export class IaraSyncfusionContextMenuManager { + constructor( + private _editor: DocumentEditor, + private _navigationFieldManager: IaraSyncfusionNavigationFieldManager + ) { + const menuItems: MenuItemModel[] = [ + { + separator: true, + }, + { + iconCss: "e-icons e-bookmark", + text: "Campos de navegação", + id: "navigation-fields", + items: [ + { + iconCss: "e-icons e-plus", + id: "add-navigation-field", + text: "Adicionar campo", + }, + { + iconCss: "e-icons e-lock", + id: "add-mandatory-field", + text: "Adicionar campo obrigatório", + }, + { + iconCss: "e-icons e-circle-info", + id: "add-optional-field", + text: "Adicionar campo opcional", + }, + ], + }, + ]; + + this._editor.contextMenu.addCustomMenu(menuItems, false, true); + + this._editor.customContextMenuSelect = ( + args: CustomContentMenuEventArgs + ): void => { + const item: string = args.id; + + const selectedText = this._editor.selection.text + ? this._editor.selection.text.trim() + : undefined; + + switch (item) { + case "add-navigation-field": + this._navigationFieldManager.insertField(selectedText); + break; + case "add-mandatory-field": + this._navigationFieldManager.insertMandatoryField(selectedText); + break; + case "add-optional-field": + this._navigationFieldManager.insertOptionalField(selectedText); + break; + } + }; + } +} diff --git a/src/syncfusion/index.ts b/src/syncfusion/index.ts index 7af19a3..c99fb2f 100644 --- a/src/syncfusion/index.ts +++ b/src/syncfusion/index.ts @@ -1,7 +1,7 @@ -import type { DocumentEditorContainer } from "@syncfusion/ej2-documenteditor"; import { CharacterFormatProperties, DocumentEditor, + DocumentEditorContainer, Print, } from "@syncfusion/ej2-documenteditor"; import { ListView, SelectedCollection } from "@syncfusion/ej2-lists"; @@ -13,7 +13,9 @@ import { } from "@syncfusion/ej2-popups"; import { EditorAdapter, IaraEditorConfig } from "../editor"; import { IaraSpeechRecognition, IaraSpeechRecognitionDetail } from "../speech"; -import { IaraSFDT, IaraSyncfusionEditorContentManager } from "./content"; +import { IaraSyncfusionEditorContentManager } from "./content"; +import { IaraSyncfusionContextMenuManager } from "./contextMenu"; +import { IaraSyncfusionNavigationFieldManager } from "./navigationFields/index"; import { IaraSyncfusionSelectionManager } from "./selection"; import { IaraSyncfusionShortcutsManager } from "./shortcuts"; import { IaraSyncfusionStyleManager } from "./style"; @@ -31,15 +33,18 @@ export class IaraSyncfusionAdapter private _contentDate?: Date; private _cursorSelection?: IaraSyncfusionSelectionManager; private _debouncedSaveReport: () => void; + private _documentEditor: DocumentEditor; + private _editorContainer?: DocumentEditorContainer; private _selectionManager?: IaraSyncfusionSelectionManager; private _inferenceEndOffset = "0;0;0"; private _toolbarManager?: IaraSyncfusionToolbarManager; + protected _navigationFieldManager: IaraSyncfusionNavigationFieldManager; + protected static DefaultConfig: IaraSyncfusionConfig = { ...EditorAdapter.DefaultConfig, replaceToolbar: false, }; - protected _styleManager: IaraSyncfusionStyleManager; public savingReportSpan = document.createElement("span"); @@ -48,55 +53,76 @@ export class IaraSyncfusionAdapter public get contentManager(): IaraSyncfusionEditorContentManager { return this._contentManager; } + public get documentEditor(): DocumentEditor { + return this._documentEditor; + } public defaultFormat: CharacterFormatProperties = {}; constructor( - protected _editorContainer: DocumentEditorContainer, + _editorInstance: DocumentEditorContainer | DocumentEditor, protected _recognition: IaraSpeechRecognition, protected _config: IaraSyncfusionConfig = IaraSyncfusionAdapter.DefaultConfig ) { - super(_editorContainer, _recognition, _config); + super(_recognition, _config); + + if ("documentEditor" in _editorInstance) { + this._editorContainer = _editorInstance; + this._documentEditor = _editorInstance.documentEditor; + } else { + this._documentEditor = _editorInstance; + } this._contentManager = new IaraSyncfusionEditorContentManager( - _editorContainer.documentEditor, - _recognition, + this._documentEditor, () => (this._config.saveReport ? this._debouncedSaveReport() : undefined) ); - new IaraSyncfusionShortcutsManager( - _editorContainer.documentEditor, - _recognition, - this.onTemplateSelectedAtShortCut.bind(this) - ); - this._styleManager = new IaraSyncfusionStyleManager( - _editorContainer.documentEditor, + this._documentEditor, this._config ); - if (this._config.replaceToolbar) { + if (this._config.replaceToolbar && this._editorContainer) { this._toolbarManager = new IaraSyncfusionToolbarManager( - _editorContainer, + this._editorContainer, this._config ); this._toolbarManager.init(); } DocumentEditor.Inject(Print); - this._editorContainer.documentEditor.enablePrint = true; - this._editorContainer.documentEditor.enableImageResizer = true; + this._documentEditor.enablePrint = true; + this._documentEditor.enableImageResizer = true; this._debouncedSaveReport = this._debounce(this._saveReport.bind(this)); - this._editorContainer.addEventListener( + this._documentEditor.addEventListener( "destroyed", this._onEditorDestroyed.bind(this) ); + this._navigationFieldManager = new IaraSyncfusionNavigationFieldManager( + this._documentEditor, + this._config, + _recognition + ); + + new IaraSyncfusionShortcutsManager( + this._documentEditor, + _recognition, + this.onTemplateSelectedAtShortCut.bind(this), + this._navigationFieldManager + ); + + new IaraSyncfusionContextMenuManager( + this._documentEditor, + this._navigationFieldManager + ); + createSpinner({ - target: _editorContainer.editorContainer, + target: this._documentEditor.editor.documentHelper.viewerContainer, }); this._setScrollClickHandler(); @@ -107,64 +133,170 @@ export class IaraSyncfusionAdapter if (wrapper) wrapper.style.cursor = status ? "not-allowed" : "auto"; } - async copyReport(): Promise { - this._editorContainer.documentEditor.focusIn(); - this._editorContainer.documentEditor.selection.selectAll(); - showSpinner(this._editorContainer.editorContainer); - const content = await this._contentManager.getContent(); - - // By pretending our html comes from google docs, we can paste it into - // tinymce without losing the formatting for some reason. - const htmlContent = content[1].replace( - '
', - '
' - ); - this._recognition.automation.copyText(content[0], htmlContent, content[2]); - hideSpinner(this._editorContainer.editorContainer); - this._editorContainer.documentEditor.selection.moveNextPosition(); + async copyReport(): Promise { + this._documentEditor.revisions.acceptAll(); + this._documentEditor.enableTrackChanges = false; + + this._documentEditor.focusIn(); + this._documentEditor.selection.selectAll(); + + this.showSpinner(); + try { + const content = await this._contentManager.getContent(); + + // By pretending our html comes from google docs, we can paste it into + // tinymce without losing the formatting for some reason. + const htmlContent = content[1].replace( + '
', + '
' + ); + console.log("copyReport", content[0], htmlContent, content[2]); + this._recognition.automation.copyText( + content[0], + htmlContent, + content[2] + ); + this.hideSpinner(); + this._documentEditor.selection.moveNextPosition(); + + return content.slice(0, 3); + } catch (error) { + this.hideSpinner(); + this._documentEditor.selection.moveToDocumentStart(); + throw error; + } } clearReport(): void { - this._editorContainer.documentEditor.selection.selectAll(); - this._editorContainer.documentEditor.editor.delete(); + this._documentEditor.enableTrackChanges = false; + this._documentEditor.selection.selectAll(); + this._documentEditor.editor.delete(); + this._styleManager.setEditorDefaultFont(); } getEditorContent(): Promise<[string, string, string, string]> { return this._contentManager.getContent(); } + private _formatSectionTitle(titleQueries: string[]): void { + let matchedQuery = ""; + while (!matchedQuery && titleQueries.length) { + const query = titleQueries.shift(); + if (!query) continue; + + this._documentEditor.search.findAll(query); + if (this._documentEditor.search.searchResults.length) { + matchedQuery = query; + this._documentEditor.selection.characterFormat.bold = true; + } + } + + this._documentEditor.search.searchResults.clear(); + } + + formatSectionTitles(): void { + this._formatSectionTitle(["Técnica:", "Técnica de Exame:"]); + this._formatSectionTitle(["Contraste:"]); + this._formatSectionTitle([ + "Histórico Clínico:", + "Indicação Clínica:", + "Informações Clínicas:", + ]); + this._formatSectionTitle(["Exames Anteriores:"]); + this._formatSectionTitle([ + "Análise:", + "Interpretação:", + "Os seguintes aspectos foram observados:", + "Relatório:", + ]); + this._formatSectionTitle(["Objetivo:"]); + this._formatSectionTitle([ + "Conclusão:", + "Hipótese Diagnóstica:", + "Impressão Diagnóstica:", + "Impressão:", + "Resumo:", + "Observação:", + "Observações:", + "Opinião:", + ]); + this._formatSectionTitle([ + "Achados:", + "Achados Adicionais:", + "Comparação:", + "Demais Achados:", + "Método:", + "Protocolo:", + ]); + } + + formatTitle(): void { + this._documentEditor.selection.moveToDocumentEnd(); + const lastParagraph = parseInt( + this._documentEditor.selection.endOffset.split(";")[1] + ); + this._documentEditor.selection.moveToDocumentStart(); + + let titleLine = ""; + let currentParagraph = 0; + while (!titleLine && currentParagraph <= lastParagraph) { + this._documentEditor.selection.selectLine(); + titleLine = this._documentEditor.selection.text.trim(); + currentParagraph++; + } + if (titleLine) { + this._documentEditor.selection.characterFormat.bold = true; + this._documentEditor.selection.characterFormat.allCaps = true; + this._documentEditor.selection.paragraphFormat.textAlignment = "Center"; + } + } + + hideSpinner(): void { + hideSpinner(this._documentEditor.editor.documentHelper.viewerContainer); + } + insertParagraph(): void { - this._editorContainer.documentEditor.editor.insertText("\n"); + this._documentEditor.editor.insertText("\n"); } async insertTemplate( content: string, replaceAllContent = false ): Promise { - const sfdt = await IaraSFDT.fromContent( - content, - this._recognition.internal.iaraAPIMandatoryHeaders as HeadersInit - ); - if (replaceAllContent) - this._editorContainer.documentEditor.open(sfdt.value); - else this._editorContainer.documentEditor.editor.paste(sfdt.value); + console.log("insertTemplate0", content, replaceAllContent); + const sfdt = await this.contentManager.fromContent(content); + if (replaceAllContent) this._documentEditor.open(sfdt.value); + else { + this._documentEditor.editor.paste(sfdt.value); + this._documentEditor.editor.onBackSpace(); + } + console.log("insertTemplate1", sfdt.value); - this._editorContainer.documentEditor.selection.moveToDocumentStart(); + this._documentEditor.selection.moveToDocumentStart(); + console.log( + "insertTemplate2", + this._documentEditor.selection.characterFormat.fontFamily, + this._documentEditor.selection.characterFormat.fontSize + ); // Set the default editor format after inserting the template - this._editorContainer.documentEditor.setDefaultCharacterFormat({ - fontFamily: - this._editorContainer.documentEditor.selection.characterFormat - .fontFamily, - fontSize: - this._editorContainer.documentEditor.selection.characterFormat.fontSize, + this._documentEditor.setDefaultCharacterFormat({ + fontFamily: this._documentEditor.selection.characterFormat.fontFamily, + fontSize: this._documentEditor.selection.characterFormat.fontSize, }); - this._editorContainer.documentEditor.selection.moveToDocumentEnd(); + this._navigationFieldManager.getBookmarks(); + this._documentEditor.selection.moveToDocumentEnd(); } insertText(text: string): void { - this._editorContainer.documentEditor.editor.insertText(text); + const [firstLine, ...lines]: string[] = text.split("\n"); + this._documentEditor.editor.insertText(firstLine); + lines.forEach(line => { + this.insertParagraph(); + line = line.trimStart(); + if (line) this._documentEditor.editor.insertText(line); + }); } insertInference(inference: IaraSpeechRecognitionDetail): void { @@ -175,7 +307,7 @@ export class IaraSyncfusionAdapter if (inference.isFirst) { this._handleFirstInference(); } else if (this._selectionManager) { - this._editorContainer.documentEditor.selection.select( + this._documentEditor.selection.select( this._selectionManager.initialSelectionData.startOffset, this._inferenceEndOffset ); @@ -196,24 +328,20 @@ export class IaraSyncfusionAdapter this._selectionManager.isAtStartOfLine ); - if (text.length) { - const [firstLine, ...lines]: string[] = text.split("\n"); - this.insertText(firstLine); - lines.forEach(line => { - this.insertParagraph(); - line = line.trimStart(); - if (line) this.insertText(line); - }); - } else this._editorContainer.documentEditor.editor.delete(); + if (text.length) this.insertText(text); + else this._documentEditor.editor.delete(); - this._inferenceEndOffset = - this._editorContainer.documentEditor.selection.endOffset; + this._inferenceEndOffset = this._documentEditor.selection.endOffset; if (inference.isFinal) this._selectionManager = undefined; } + moveToDocumentEnd() { + this._documentEditor.selection.moveToDocumentEnd(); + } + undo(): void { - this._editorContainer.documentEditor.editorHistory.undo(); + this._documentEditor.editorHistory.undo(); } private _debounce(func: () => unknown) { @@ -231,25 +359,37 @@ export class IaraSyncfusionAdapter this._contentDate = contentDate; const element = document.querySelector(".e-de-status-bar"); + + const content: string[] = await this._contentManager.getContent(); + const emptyContent = content[0].trim().length === 0; + + if (emptyContent) { + return; + } + if (element) { + this.savingReportSpan.style.width = "120px"; this.savingReportSpan.style.margin = "10px"; this.savingReportSpan.style.fontSize = "12px"; - this.savingReportSpan.style.display = "flex"; - this.savingReportSpan.style.justifyContent = "end"; this.savingReportSpan.style.color = "black"; - this.savingReportSpan.innerText = "Salvando..."; + this.savingReportSpan.innerHTML = + 'Salvando...'; element.insertBefore(this.savingReportSpan, element.firstChild); } - const content: string[] = await Promise.all([ - this._contentManager.getPlainTextContent(), - this._contentManager.getHtmlContent(), - ]); - - if (contentDate !== this._contentDate) return; + try { + if (contentDate !== this._contentDate) return; - await this._updateReport(content[0], content[1]); - this.savingReportSpan.innerText = "Salvo"; + if (!this._recognition.report["_key"]) { + await this.beginReport(); + } + await this._updateReport(content[0], content[1]); + this.savingReportSpan.innerHTML = + 'Salvo'; + } catch { + this.savingReportSpan.innerHTML = + 'Erro ao salvar'; + } } onTemplateSelectedAtShortCut( @@ -275,7 +415,7 @@ export class IaraSyncfusionAdapter print(): void { if (this._config.darkMode) this._styleManager.setEditorFontColor("#000"); - this._editorContainer.documentEditor.print(); + this._documentEditor.print(); if (this._config.darkMode) this._styleManager.setEditorFontColor("#fff"); } @@ -284,26 +424,32 @@ export class IaraSyncfusionAdapter paragraphIndex: number, content: string ) { - this._editorContainer.documentEditor.selection.select( + this._documentEditor.selection.select( `${sectionIndex};${paragraphIndex};0`, `${sectionIndex};${paragraphIndex};0` ); - this._editorContainer.documentEditor.selection.extendToParagraphEnd(); + this._documentEditor.selection.extendToParagraphEnd(); this.insertText(content); } + showSpinner(): void { + showSpinner(this._documentEditor.editor.documentHelper.viewerContainer); + } + private _setScrollClickHandler() { - this._editorContainer.element.addEventListener("mousedown", event => { - if (event.button === 1) { - this._cursorSelection = new IaraSyncfusionSelectionManager( - this._editorContainer.documentEditor, - false - ); - } - }); + this._documentEditor + .getRootElement() + .addEventListener("mousedown", event => { + if (event.button === 1) { + this._cursorSelection = new IaraSyncfusionSelectionManager( + this._documentEditor, + false + ); + } + }); - this._editorContainer.element.addEventListener("mouseup", event => { + this._documentEditor.getRootElement().addEventListener("mouseup", event => { if (event.button === 1) { this._cursorSelection?.resetSelection(); this._cursorSelection = undefined; @@ -314,18 +460,18 @@ export class IaraSyncfusionAdapter } private _handleFirstInference(): void { - if (this._editorContainer.documentEditor.selection.text.length) { - this._editorContainer.documentEditor.editor.delete(); + if (this._documentEditor.selection.text.length) { + this._documentEditor.editor.delete(); } this._selectionManager = new IaraSyncfusionSelectionManager( - this._editorContainer.documentEditor + this._documentEditor ); if (this._selectionManager.wordBeforeSelection.endsWith(" ")) { - this._editorContainer.documentEditor.selection.extendBackward(); - this._editorContainer.documentEditor.editor.delete(); + this._documentEditor.selection.extendBackward(); + this._documentEditor.editor.delete(); this._selectionManager = new IaraSyncfusionSelectionManager( - this._editorContainer.documentEditor + this._documentEditor ); } } diff --git a/src/syncfusion/navigationFields/bookmark.ts b/src/syncfusion/navigationFields/bookmark.ts new file mode 100644 index 0000000..8f47a3e --- /dev/null +++ b/src/syncfusion/navigationFields/bookmark.ts @@ -0,0 +1,9 @@ +export interface IaraBookmark { + name: string; + content: string; + title: string; + offset: { + start: string; + end: string; + }; +} diff --git a/src/syncfusion/navigationFields/index.ts b/src/syncfusion/navigationFields/index.ts new file mode 100644 index 0000000..ae6dbde --- /dev/null +++ b/src/syncfusion/navigationFields/index.ts @@ -0,0 +1,652 @@ +import { + BookmarkElementBox, + Dictionary, + DocumentEditor, + TextPosition, +} from "@syncfusion/ej2-documenteditor"; +import { IaraSyncfusionConfig } from ".."; +import { IaraEditorNavigationFieldManager } from "../../editor/navigationFields"; +import { IaraSpeechRecognition } from "../../speech"; +import { IaraBookmark } from "./bookmark"; + +export class IaraSyncfusionNavigationFieldManager extends IaraEditorNavigationFieldManager { + previousBookmark: IaraBookmark = { + name: "", + content: "", + title: "", + offset: { + start: "", + end: "", + }, + }; + nextBookmark: IaraBookmark = { + name: "", + content: "", + title: "", + offset: { + start: "", + end: "", + }, + }; + currentSelectionOffset: { + start: string; + end: string; + } = { + start: "", + end: "", + }; + insertedBookmark: IaraBookmark = { + name: "", + content: "", + title: "", + offset: { + start: "", + end: "", + }, + }; + isFirstNextNavigation = false; + isFirstPreviousNavigation = false; + private _bookmarks: IaraBookmark[] = []; + + private _previousBookmarksTitles: string[] = []; + + constructor( + private _documentEditor: DocumentEditor, + private _config: IaraSyncfusionConfig, + _recognition: IaraSpeechRecognition + ) { + super(_recognition); + const navigationBtn = ( + document.getElementById("navigation_fields") + ); + + if (!navigationBtn) return; + + navigationBtn.addEventListener("click", () => { + const insertBtn = document.getElementById("add_field"); + const nextFieldBtn = document.getElementById("next_field"); + const previousFieldBtn = ( + document.getElementById("previous_field") + ); + const insertMandatoryFieldBtn = ( + document.getElementById("add_mandatory_field") + ); + const insertOptionalFieldBtn = ( + document.getElementById("add_optional_field") + ); + + const selectedText = this._documentEditor.selection.text + ? this._documentEditor.selection.text.trim() + : undefined; + + insertBtn.addEventListener("click", () => { + this.insertField(selectedText); + }); + insertMandatoryFieldBtn.addEventListener("click", () => { + this.insertMandatoryField(selectedText); + }); + insertOptionalFieldBtn.addEventListener("click", () => { + this.insertOptionalField(selectedText); + }); + nextFieldBtn.addEventListener("click", () => { + this.nextField(); + }); + previousFieldBtn.addEventListener("click", () => { + this.previousField(); + }); + }); + } + + insertField(content = "Escreva uma dica de texto"): void { + const bookmarksCount = Date.now(); + this._documentEditor.editor.insertText(" "); + this._documentEditor.selection.movePreviousPosition(); + this._documentEditor.editor.insertBookmark(`Field-${bookmarksCount}`); + const title = "Nome do campo"; + this._documentEditor.editor.insertText("[]"); + this._documentEditor.selection.movePreviousPosition(); + this._documentEditor.editor.insertText("<>"); + this._documentEditor.selection.movePreviousPosition(); + this._documentEditor.editor.insertText(title); + this._documentEditor.selection.clear(); + this._documentEditor.selection.moveNextPosition(); + this._documentEditor.editor.insertText(content); + this.getBookmarks(); + this.isFirstNextNavigation = true; + this.isFirstPreviousNavigation = true; + this.getOffsetsAndSelect(`Field-${bookmarksCount}`, true); + this.selectTitle(title, `Field-${bookmarksCount}`); + } + + insertMandatoryField(content = "Escreva uma dica de texto"): void { + const bookmarksCount = Date.now(); + this._documentEditor.editor.insertText(" "); + this._documentEditor.selection.movePreviousPosition(); + this._documentEditor.editor.insertBookmark(`Mandatory-${bookmarksCount}`); + const title = "Nome do campo"; + this._documentEditor.editor.insertText("[]"); + this._documentEditor.selection.movePreviousPosition(); + this._documentEditor.editor.insertText("<>"); + this._documentEditor.selection.movePreviousPosition(); + this._documentEditor.editor.insertText(title); + this._documentEditor.selection.clear(); + this._documentEditor.selection.moveNextPosition(); + this._documentEditor.editor.insertText(`${content}*`); + this.getBookmarks(); + this.isFirstNextNavigation = true; + this.isFirstPreviousNavigation = true; + this.getOffsetsAndSelect(`Mandatory-${bookmarksCount}`, true); + this.selectTitle(title, `Mandatory-${bookmarksCount}`); + } + + insertOptionalField(content = "Escreva uma dica de texto"): void { + const bookmarksCount = Date.now(); + this._documentEditor.editor.insertText(" "); + this._documentEditor.selection.movePreviousPosition(); + this._documentEditor.editor.insertBookmark(`Optional-${bookmarksCount}`); + const title = "Nome do campo"; + this._documentEditor.editor.insertText("[]"); + this._documentEditor.selection.movePreviousPosition(); + this._documentEditor.editor.insertText("<>"); + this._documentEditor.selection.movePreviousPosition(); + this._documentEditor.editor.insertText(title); + this._documentEditor.selection.clear(); + this._documentEditor.selection.moveNextPosition(); + this._documentEditor.editor.insertText(`${content}?`); + this.getBookmarks(); + this.isFirstNextNavigation = true; + this.isFirstPreviousNavigation = true; + this.getOffsetsAndSelect(`Optional-${bookmarksCount}`, true); + this.selectTitle(title, `Optional-${bookmarksCount}`); + } + + getBookmarks(setColor = true): void { + const editorBookmarks = this._documentEditor.getBookmarks(); + this.updateBookmark(editorBookmarks); + this.removeEmptyField(editorBookmarks); + if (this.isFirstNextNavigation || this.isFirstPreviousNavigation) { + this.insertedBookmark = this._bookmarks.filter( + bookmark => + bookmark.name === editorBookmarks[editorBookmarks.length - 1] + )[0]; + } + this.sortByPosition(); + if (this._bookmarks.length > 1) + this.getPreviousAndNext(this.currentSelectionOffset); + + if (setColor) this.setColor(); + + this._documentEditor.selection.clear(); + } + + goToField(title: string): void | string { + this._previousBookmarksTitles = [...this._previousBookmarksTitles, title]; + const bookmarks = this._bookmarks.filter( + bookmark => + bookmark.title.toLowerCase() === title.toLowerCase() && + bookmark.title !== "Nome do campo" && + bookmark.title !== "" + ); + if (bookmarks.length === 1) { + this.getOffsetsAndSelect(bookmarks[0].name); + this._previousBookmarksTitles = []; + } else if (bookmarks.length > 1) { + this.getOffsetsAndSelect( + bookmarks[this._previousBookmarksTitles.length - 1].name + ); + } else throw new Error("Method not implemented."); + } + + nextField(isShortcutNavigation?: boolean): void { + this.currentSelectionOffset = { + start: this._documentEditor.selection.startOffset, + end: this._documentEditor.selection.endOffset, + }; + this.getBookmarks(false); + + if (isShortcutNavigation && this.isFirstNextNavigation) + this.selectContent( + this.insertedBookmark.title, + this.insertedBookmark.content, + this.insertedBookmark.name + ); + else { + this.getOffsetsAndSelect(this.nextBookmark.name); + } + this.isFirstNextNavigation = false; + this.currentSelectionOffset = { + start: this.nextBookmark.offset.start, + end: this.nextBookmark.offset.end, + }; + } + + previousField(isShortcutNavigation?: boolean): void { + this.currentSelectionOffset = { + start: this._documentEditor.selection.startOffset, + end: this._documentEditor.selection.endOffset, + }; + + this.getBookmarks(false); + + if (isShortcutNavigation && this.isFirstPreviousNavigation) + this.selectTitle(this.insertedBookmark.title, this.insertedBookmark.name); + else { + this.getOffsetsAndSelect(this.previousBookmark.name); + } + this.isFirstPreviousNavigation = false; + this.currentSelectionOffset = { + start: this.previousBookmark.offset.start, + end: this.previousBookmark.offset.end, + }; + } + + selectContent(title: string, content: string, bookmarkName: string): void { + this.getOffsetsAndSelect(bookmarkName, true); + this._documentEditor.selection.select( + this._documentEditor.selection.startOffset, + this._documentEditor.selection.startOffset + ); + const startOffset = this._documentEditor.selection.startOffset.split(";"); + + //title lenght and add 3 positions to pass startOffset to content + startOffset[2] = String( + Number(this._documentEditor.selection.startOffset.split(";")[2]) + + (title.length + 3) + ); + const start = startOffset.join(";"); + + const endOffset = this._documentEditor.selection.endOffset.split(";"); + //add content lenght to endOffset to pass endOffset to content + endOffset[2] = String(Number(start.split(";")[2]) + content.length); + const end = endOffset.join(";"); + + this._documentEditor.selection.select(start, end); + } + + selectTitle( + title: string, + bookmarkName: string, + selectAllTitle?: boolean + ): void { + this.getOffsetsAndSelect(bookmarkName, true); + this._documentEditor.selection.select( + this._documentEditor.selection.startOffset, + this._documentEditor.selection.startOffset + ); + const startOffset = this._documentEditor.selection.startOffset.split(";"); + //add 2 positions so as not to select [ or < + startOffset[2] = String( + selectAllTitle + ? Number(this._documentEditor.selection.startOffset.split(";")[2]) + 1 + : Number(this._documentEditor.selection.startOffset.split(";")[2]) + 2 + ); + const start = startOffset.join(";"); + + const endOffset = this._documentEditor.selection.endOffset.split(";"); + //remove the content size plus 2 positions so as not to select > or ] + endOffset[2] = String( + selectAllTitle + ? Number(this._documentEditor.selection.endOffset.split(";")[2]) + + (title.length + 3) + : Number(this._documentEditor.selection.endOffset.split(";")[2]) + + (title.length + 2) + ); + const end = endOffset.join(";"); + this._documentEditor.selection.select(start, end); + } + + sortByPosition(): void { + this._bookmarks.sort( + ( + currentOffset: { offset: { start: string; end: string } }, + nextOffset: { offset: { start: string; end: string } } + ) => { + const current = currentOffset.offset.start.split(";").map(Number); + const next = nextOffset.offset.start.split(";").map(Number); + return ( + current[0] - next[0] || current[1] - next[1] || current[2] - next[2] + ); + } + ); + } + + getTitleAndContent(bookmarkContent: string): { + title: string; + content: string; + } { + let title = ""; + let content = ""; + if (bookmarkContent.includes("[")) { + const insideContent = bookmarkContent.replace( + /\[(.*)\]/, + (_match, group1) => group1 + ); + title = insideContent.split(">")[0].substring(1); + content = insideContent.split(">")[1]; + } else { + content = bookmarkContent; + } + return { + title, + content, + }; + } + + popAndUpdate(bookmarkName: string, content: string, title: string): void { + const index = this._bookmarks.findIndex(item => item.name === bookmarkName); + if ( + bookmarkName.includes("Field") || + bookmarkName.includes("Mandatory") || + bookmarkName.includes("Optional") + ) { + if (index !== -1) { + this._bookmarks = this._bookmarks.map(item => { + if (item.name === bookmarkName) { + return { + name: bookmarkName, + content, + title, + offset: { + start: this._documentEditor.selection.startOffset, + end: this._documentEditor.selection.endOffset, + }, + }; + } + return item; + }); + } else { + this._bookmarks = [ + ...this._bookmarks, + { + name: bookmarkName, + content, + title, + offset: { + start: this._documentEditor.selection.startOffset, + end: this._documentEditor.selection.endOffset, + }, + }, + ]; + } + } + } + + setColor() { + this._bookmarks.map(bookmark => { + this._documentEditor.selection.select( + bookmark.offset.start, + bookmark.offset.end + ); + if (bookmark.name.includes("Mandatory")) { + this._config.darkMode + ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + (this._documentEditor.selection.characterFormat.highlightColor = + "#6C4E35") + : // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + (this._documentEditor.selection.characterFormat.highlightColor = + "#FFD5BB"); + this.selectTitle(bookmark.title, bookmark.name, true); + this._config.darkMode + ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + (this._documentEditor.selection.characterFormat.highlightColor = + "#C07240") + : // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + (this._documentEditor.selection.characterFormat.highlightColor = + "#FFEBD8"); + this.selectContent(bookmark.title, bookmark.content, bookmark.name); + this._config.darkMode + ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + (this._documentEditor.selection.characterFormat.highlightColor = + "#6C4E35") + : // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + (this._documentEditor.selection.characterFormat.highlightColor = + "#FFD5BB"); + } + if (bookmark.name.includes("Field")) { + this._config.darkMode + ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + (this._documentEditor.selection.characterFormat.highlightColor = + "#565656") + : // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + (this._documentEditor.selection.characterFormat.highlightColor = + "#DDDDDD"); + this.selectTitle(bookmark.title, bookmark.name, true); + this._config.darkMode + ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + (this._documentEditor.selection.characterFormat.highlightColor = + "#3F3F3F") + : // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + (this._documentEditor.selection.characterFormat.highlightColor = + "#AEAEAE"); + this.selectContent(bookmark.title, bookmark.content, bookmark.name); + this._config.darkMode + ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + (this._documentEditor.selection.characterFormat.highlightColor = + "#565656") + : // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + (this._documentEditor.selection.characterFormat.highlightColor = + "#DDDDDD"); + } + if (bookmark.name.includes("Optional")) { + this._config.darkMode + ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + (this._documentEditor.selection.characterFormat.highlightColor = + "#4C83AC") + : // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + (this._documentEditor.selection.characterFormat.highlightColor = + "#CEEFFE"); + this.selectTitle(bookmark.title, bookmark.name, true); + this._config.darkMode + ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + (this._documentEditor.selection.characterFormat.highlightColor = + "#356688") + : // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + (this._documentEditor.selection.characterFormat.highlightColor = + "#BAE1FE"); + this.selectContent(bookmark.title, bookmark.content, bookmark.name); + this._config.darkMode + ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + (this._documentEditor.selection.characterFormat.highlightColor = + "#4C83AC") + : // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + (this._documentEditor.selection.characterFormat.highlightColor = + "#CEEFFE"); + } + }); + } + + updateBookmark(editorBookmarks: string[]): void { + editorBookmarks.map(bookmark => { + this.getOffsetsAndSelect(bookmark); + const bookmarkContent = this._documentEditor.selection.text; + const { title, content } = this.getTitleAndContent(bookmarkContent); + this.popAndUpdate(bookmark, content, title); + }); + } + + removeEmptyField(editorBookmarks: string[]): void { + this._bookmarks = this._bookmarks.filter(item => + editorBookmarks.includes(item.name) + ); + this._bookmarks = this._bookmarks.filter(bookmark => bookmark.title); + } + + getPreviousAndNext(currentOffset: { start: string; end: string }): void { + const index = this._bookmarks.findIndex( + bookmark => this.findCurrentIndex(currentOffset, bookmark.offset) < 0 + ); + + const previousIndex = index <= 0 ? this._bookmarks.length - 1 : index - 1; + + let previousField = + index <= 0 + ? this._bookmarks[previousIndex] + : this._bookmarks[previousIndex]; + + const nextField = + index === -1 ? this._bookmarks[0] : this._bookmarks[index]; + + previousField = this.checkIsSelectedAndUpdatePrevious(previousIndex); + + this.previousBookmark = previousField; + this.nextBookmark = nextField; + } + + findCurrentIndex( + bookmark: { start: string; end: string }, + currentOffset: { start: string; end: string } + ): number { + const bookmarkOffsetStart = bookmark.start.split(";").map(Number); + const currentOffsetStart = currentOffset.start.split(";").map(Number); + const bookmarkOffsetEnd = bookmark.end.split(";").map(Number); + const currentOffsetEnd = currentOffset.end.split(";").map(Number); + for (let i = 0; i < bookmarkOffsetStart.length; i++) { + if (bookmarkOffsetStart[i] !== currentOffsetStart[i]) { + return bookmarkOffsetStart[i] - currentOffsetStart[i]; + } + } + for (let i = 0; i < bookmarkOffsetEnd.length; i++) { + if (bookmarkOffsetEnd[i] !== currentOffsetEnd[i]) { + return bookmarkOffsetEnd[i] - currentOffsetEnd[i]; + } + } + return 0; + } + + checkIsSelectedAndUpdatePrevious(previousIndex: number): IaraBookmark { + let selected = this._bookmarks[previousIndex]; + + const compareCurrentOffsetWithPreviousOffset = + this.currentSelectionOffset.start && + this.currentSelectionOffset.start === + this.previousBookmark.offset.start && + this.previousBookmark.offset.end === this.currentSelectionOffset.end; + + const compareCurrentOffsetWithNextOffset = + this.currentSelectionOffset.start && + this.currentSelectionOffset.start === this.nextBookmark.offset.start && + this.currentSelectionOffset.end === this.nextBookmark.offset.end; + + const compareCurrentOffsetWithSelecteOffset = + this.previousBookmark.offset.start && + this.previousBookmark.content !== selected.content; + + if ( + compareCurrentOffsetWithPreviousOffset || + compareCurrentOffsetWithNextOffset || + compareCurrentOffsetWithSelecteOffset + ) { + selected = this._bookmarks[previousIndex - 1]; + return previousIndex <= 0 + ? this._bookmarks[this._bookmarks.length - 1] + : this._bookmarks[previousIndex - 1]; + } + return this._bookmarks[previousIndex]; + } + + getOffsetsAndSelect(name: string, excludeBookmarkStartEnd?: boolean): void { + const bookmarks: Dictionary = + this._documentEditor.documentHelper.bookmarks; + + if (bookmarks.containsKey(name)) { + //bookmark start element + const bookmrkElmnt: BookmarkElementBox = bookmarks.get(name); + + let offset: number = bookmrkElmnt.line.getOffset(bookmrkElmnt, 0); + + if (excludeBookmarkStartEnd) { + offset++; + } + + const startPosition: TextPosition = new TextPosition( + this._documentEditor + ); + startPosition.setPositionParagraph(bookmrkElmnt.line, offset); + + //bookmark end element + let bookmrkEnd: BookmarkElementBox = bookmrkElmnt.reference; + if ( + bookmrkElmnt.reference && + bookmrkElmnt.reference.line.paragraph.bodyWidget == null + ) { + bookmrkEnd = bookmrkElmnt; + } + + let endoffset: number = bookmrkEnd.line.getOffset(bookmrkEnd, 1); + + if (excludeBookmarkStartEnd) { + endoffset--; + } + const endPosition: TextPosition = new TextPosition(this._documentEditor); + endPosition.setPositionParagraph(bookmrkEnd.line, endoffset); + //selects the bookmark range + this._documentEditor.documentHelper.selection.selectRange( + startPosition, + endPosition + ); + } + } + + clearReportToCopyContent(): void { + this.getBookmarks(false); + this._bookmarks.filter(field => { + this.getOffsetsAndSelect(field.name); + if (field.name.includes("Field")) { + if (field.content && field.content !== "Escreva uma dica de texto") { + this._documentEditor.editor.insertText(field.content); + this._documentEditor.editor.deleteBookmark(field.name); + } else { + this._documentEditor.editor.delete(); + this._documentEditor.editor.onBackSpace(); + this._documentEditor.editor.deleteBookmark(field.name); + } + } + if (field.name.includes("Optional")) { + if (field.title) { + this._documentEditor.editor.delete(); + this._documentEditor.editor.onBackSpace(); + this._documentEditor.editor.deleteBookmark(field.name); + } + } + }); + } + + requiredFields(): boolean { + this.getBookmarks(false); + const mandatoriesFields = this._bookmarks.filter( + bookmark => bookmark.name.includes("Mandatory") && bookmark.title + ); + if (mandatoriesFields.length) { + if (mandatoriesFields[0].title) { + this.getOffsetsAndSelect(mandatoriesFields[0].name); + } + return true; + } + return false; + } + + hasEmptyRequiredFields(): boolean { + if (!this.requiredFields()) { + this.clearReportToCopyContent(); + } + return this.requiredFields(); + } +} diff --git a/src/syncfusion/shortcuts/index.ts b/src/syncfusion/shortcuts/index.ts index cc67b49..5598c3c 100644 --- a/src/syncfusion/shortcuts/index.ts +++ b/src/syncfusion/shortcuts/index.ts @@ -6,6 +6,7 @@ import { ListView } from "@syncfusion/ej2-lists"; import { Dialog } from "@syncfusion/ej2-popups"; import { IaraSpeechRecognition } from "../../speech"; import { IaraSyncfusionTemplateSearch } from "./templateSearch"; +import { IaraSyncfusionNavigationFieldManager } from "../navigationFields"; export class IaraSyncfusionShortcutsManager { constructor( @@ -14,43 +15,61 @@ export class IaraSyncfusionShortcutsManager { private onTemplateSelected: ( listViewInstance: ListView, dialogObj: Dialog - ) => void + ) => void, + private _navigationFieldManager: IaraSyncfusionNavigationFieldManager ) { this._editor.keyDown = this.onKeyDown.bind(this); } onKeyDown(args: DocumentEditorKeyDownEventArgs): void { - if (args.event.key === "@") { - const templates = [ - ...Object.values(this._recognition.richTranscriptTemplates.templates), - ]; + switch (args.event.key) { + case "@": + this.shortcutByAt(); + break; + case "Tab": + args.isHandled = true; + this.shortcutByTabAndShiftTab(args); + break; + default: + break; + } + } - const updateFormatTemplates = templates.map(template => { - const metadata = template.metadata as { - category: string; - name: string; - }; - return { - name: metadata.name, - category: metadata.category ? metadata.category : "", - content: template.replaceText, - }; - }); + shortcutByAt(): void { + const templates = [ + ...Object.values(this._recognition.richTranscriptTemplates.templates), + ]; - const sortOrder = updateFormatTemplates.sort( - (oldTemplate, newTemplate) => { - // Compare based on the 'type' key - if (oldTemplate.category === newTemplate.category) { - // If types are the same, order by the 'value' key - return oldTemplate["name"].localeCompare(newTemplate["name"]); - } else { - // Order 'template' items first - return oldTemplate.category === "Template" ? -1 : 1; - } - } - ); + const updateFormatTemplates = templates.map(template => { + const metadata = template.metadata as { + category: string; + name: string; + }; + return { + name: metadata.name, + category: metadata.category ? metadata.category : "", + content: template.replaceText, + }; + }); + + const sortOrder = updateFormatTemplates.sort((oldTemplate, newTemplate) => { + // Compare based on the 'type' key + if (oldTemplate.category === newTemplate.category) { + // If types are the same, order by the 'value' key + return oldTemplate["name"].localeCompare(newTemplate["name"]); + } else { + // Order 'template' items first + return oldTemplate.category === "Template" ? -1 : 1; + } + }); + new IaraSyncfusionTemplateSearch(sortOrder, this.onTemplateSelected); + } - new IaraSyncfusionTemplateSearch(sortOrder, this.onTemplateSelected); + shortcutByTabAndShiftTab(args: DocumentEditorKeyDownEventArgs): void { + if (args.event.shiftKey && args.event.key == "Tab") { + this._navigationFieldManager.previousField(true); + } else if (args.event.key == "Tab") { + this._navigationFieldManager.nextField(true); } } } diff --git a/src/syncfusion/style.ts b/src/syncfusion/style.ts index 9783808..0ae6e1b 100644 --- a/src/syncfusion/style.ts +++ b/src/syncfusion/style.ts @@ -3,6 +3,8 @@ import { IaraSyncfusionConfig } from "."; import { IaraEditorStyleManager } from "../editor/style"; export class IaraSyncfusionStyleManager extends IaraEditorStyleManager { + public zoomInterval: ReturnType | null = null; + constructor( private _editor: DocumentEditor, private _config: IaraSyncfusionConfig @@ -10,12 +12,19 @@ export class IaraSyncfusionStyleManager extends IaraEditorStyleManager { super(); this.setTheme(this._config.darkMode ? "dark" : "light"); + this.setEditorDefaultFont(); + } + setEditorDefaultFont(): void { this._editor.setDefaultCharacterFormat({ fontFamily: this._config.font?.family, fontSize: this._config.font?.size, fontColor: this._config.darkMode ? "#fff" : "#000", }); + + // this.zoomInterval = setInterval(() => { + // this.setZoomFactor(this._config.zoomFactor ?? "100%"); + // }, 100); } setEditorFontColor(color: string): void { @@ -38,6 +47,19 @@ export class IaraSyncfusionStyleManager extends IaraEditorStyleManager { this._editor.setDefaultCharacterFormat({ fontColor: "#fff" }); } + public setZoomFactor(zoomFactor: string) { + if (zoomFactor.match("Fit one page")) { + this._editor.fitPage("FitOnePage"); + } else if (zoomFactor.match("Fit page width")) { + this._editor.fitPage("FitPageWidth"); + } else { + const zoomFactorFixed = parseInt(zoomFactor, 0) / 100; + this._editor.zoomFactor = Number(zoomFactorFixed); + } + + if (this.zoomInterval) clearInterval(this.zoomInterval); + } + static loadThemeCss(theme: "light" | "dark") { if (theme === "dark") { const FILE = "https://cdn.syncfusion.com/ej2/24.2.9/material3-dark.css"; diff --git a/src/syncfusion/toolbar/config.ts b/src/syncfusion/toolbar/config.ts index 9ea163b..75fa03e 100644 --- a/src/syncfusion/toolbar/config.ts +++ b/src/syncfusion/toolbar/config.ts @@ -9,8 +9,8 @@ import { RibbonFileMenu, } from "@syncfusion/ej2-ribbon"; import { IaraSyncfusionConfig } from ".."; -import { tabsConfig } from "./ribbonTabs"; import { IaraSFDT } from "../content"; +import { tabsConfig } from "./ribbonTabs"; export interface RibbonFontMethods { changeFontFamily: ( @@ -243,6 +243,14 @@ const toolbarButtonClick = ( editor.documentEditor.documentEditorSettings.showHiddenMarks = !editor.documentEditor.documentEditorSettings.showHiddenMarks; break; + case "ToggleTrackChanges": + editor.documentEditor.enableTrackChanges = + !editor.documentEditor.enableTrackChanges; + changeActiveState( + editor.documentEditor.enableTrackChanges, + "trackChangesBtn" + ); + break; default: break; } diff --git a/src/syncfusion/toolbar/index.ts b/src/syncfusion/toolbar/index.ts index 8ecdb26..66b957e 100644 --- a/src/syncfusion/toolbar/index.ts +++ b/src/syncfusion/toolbar/index.ts @@ -2,6 +2,8 @@ import type { DocumentEditorContainer } from "@syncfusion/ej2-documenteditor"; import * as EJ2_LOCALE from "@syncfusion/ej2-locale/src/pt-BR.json"; import { toolBarSettings } from "./config"; import { IaraSyncfusionConfig } from ".."; +import { createElement } from "@syncfusion/ej2-base"; +import { TabItemModel, SelectingEventArgs } from "@syncfusion/ej2-navigations"; export class IaraSyncfusionToolbarManager { constructor( @@ -12,6 +14,7 @@ export class IaraSyncfusionToolbarManager { public init(): void { this._addRibbonToolbar(); this._removePropertiesPane(); + this._setupTrackChangesTab(); } private _removePropertiesPane(): void { @@ -102,4 +105,40 @@ export class IaraSyncfusionToolbarManager { this._editorContainer.resize(); } } + + private _setupTrackChangesTab() { + const acceptAllHeader: HTMLElement = createElement("div", { + innerHTML: "Aceitar tudo", + }); + const rejectAllHeader: HTMLElement = createElement("div", { + innerHTML: "Rejeitar tudo", + }); + + const totalItems = document.querySelectorAll( + "#iara-syncfusion-editor-container_editorReview_Tab_tab_header_items .e-toolbar-item" + ).length; + const items: TabItemModel[] = [ + { header: { text: acceptAllHeader } }, + { header: { text: rejectAllHeader } }, + ] as TabItemModel[]; + this._editorContainer.documentEditor.trackChangesPane[ + "commentReviewPane" + ].reviewTab.addTab(items, totalItems); + + this._editorContainer.documentEditor.trackChangesPane[ + "commentReviewPane" + ].reviewTab.addEventListener("selecting", (event: SelectingEventArgs) => { + const selectedTabText = ( + event.selectingItem.getElementsByClassName("e-tab-text")[0] + .childNodes[0] as HTMLElement + ).innerText; + if (selectedTabText == "ACEITAR TUDO") { + event.cancel = true; + this._editorContainer.documentEditor.revisions.acceptAll(); + } else if (selectedTabText == "REJEITAR TUDO") { + event.cancel = true; + this._editorContainer.documentEditor.revisions.rejectAll(); + } + }); + } } diff --git a/src/syncfusion/toolbar/ribbonTabs.ts b/src/syncfusion/toolbar/ribbonTabs.ts index 602f9d2..6053ade 100644 --- a/src/syncfusion/toolbar/ribbonTabs.ts +++ b/src/syncfusion/toolbar/ribbonTabs.ts @@ -540,9 +540,55 @@ export const tabsConfig = ( }, ], }, + { + id: "navigation_fields_content", + header: "Marcadores", + groupIconCss: "e-icons e-align-center", + collections: [ + { + items: [ + { + displayOptions: DisplayMode.Classic, + type: "DropDown", + id: "navigation_fields", + dropDownSettings: { + iconCss: "e-icons e-bookmark", + content: "Campos de navegação", + items: [ + { + id: "add_field", + iconCss: "e-icons e-plus", + text: "Adicionar campo", + }, + { + id: "add_mandatory_field", + iconCss: "e-icons e-lock", + text: "Adicionar campo obrigatório", + }, + { + id: "add_optional_field", + iconCss: "e-icons e-circle-info", + text: "Adicionar campo opcional", + }, + { + id: "next_field", + iconCss: "e-icons e-arrow-right", + text: "Próximo campo", + }, + { + id: "previous_field", + iconCss: "e-icons e-arrow-left", + text: "Campo anterior", + }, + ], + }, + }, + ], + }, + ], + }, { id: "export_group", - orientation: "Row", header: editorContainerLocale.grid["Export"], groupIconCss: "e-icons e-align-center", collections: [ @@ -565,6 +611,31 @@ export const tabsConfig = ( }, ], }, + { + id: "track_changes", + header: "Revisão", + collections: [ + { + items: [ + { + id: "trackChangesBtn", + type: "Button", + buttonSettings: { + iconCss: "e-icons e-changes-track", + content: "Rastrear mudanças", + clicked: function () { + toolbarButtonClick("ToggleTrackChanges", editor, config); + }, + }, + ribbonTooltipSettings: { + title: + editorContainerLocale.documenteditor["Tracked changes"], + }, + }, + ], + }, + ], + }, ], }, ]; diff --git a/src/tinymce/index.ts b/src/tinymce/index.ts index 99e4d37..e36a7e3 100644 --- a/src/tinymce/index.ts +++ b/src/tinymce/index.ts @@ -1,26 +1,34 @@ import { Editor } from "tinymce"; import { EditorAdapter, IaraEditorConfig } from "../editor"; import { IaraEditorInferenceFormatter } from "../editor/formatter"; -import { IaraSpeechRecognition, IaraSpeechRecognitionDetail } from "../speech"; +import type { + IaraSpeechRecognition, + IaraSpeechRecognitionDetail, +} from "../speech"; import { IaraTinyMceStyleManager } from "./style"; +import { IaraTinyMceNavigationFieldManager } from "./navigationFields"; export class IaraTinyMCEAdapter extends EditorAdapter implements EditorAdapter { protected _styleManager: IaraTinyMceStyleManager; + protected _navigationFieldManager: IaraTinyMceNavigationFieldManager; private _initialUndoStackSize = 0; constructor( - protected _editorContainer: Editor, + protected _editor: Editor, protected _recognition: IaraSpeechRecognition, protected _config: IaraEditorConfig ) { - super(_editorContainer, _recognition, _config); + super(_recognition, _config); this._inferenceFormatter = new IaraEditorInferenceFormatter(); this._styleManager = new IaraTinyMceStyleManager(); - this._editorContainer.on("destroyed", this._onEditorDestroyed.bind(this)); + this._navigationFieldManager = new IaraTinyMceNavigationFieldManager( + _recognition + ); + this._editor.on("destroyed", this._onEditorDestroyed.bind(this)); } getUndoStackSize(): number { - return (this._editorContainer.undoManager as any).data.length || 0; + return (this._editor.undoManager as any).data.length || 0; } getEditorContent(): Promise<[string, string, string]> { @@ -51,11 +59,11 @@ export class IaraTinyMCEAdapter extends EditorAdapter implements EditorAdapter { } insertParagraph() { - this._editorContainer.execCommand("InsertParagraph"); + this._editor.execCommand("InsertParagraph"); } insertText(text: string) { - this._editorContainer.insertContent(text); + this._editor.insertContent(text); } blockEditorWhileSpeaking(status: boolean) { @@ -64,10 +72,10 @@ export class IaraTinyMCEAdapter extends EditorAdapter implements EditorAdapter { } undo() { - this._editorContainer.undoManager.undo(); + this._editor.undoManager.undo(); } - copyReport(): Promise { + copyReport(): Promise { throw new Error("Método não implementado."); } @@ -78,4 +86,18 @@ export class IaraTinyMCEAdapter extends EditorAdapter implements EditorAdapter { print(): void { throw new Error("Method not implemented."); } + + nextField(): void { + throw new Error("Method not implemented."); + } + previousField(): void { + throw new Error("Method not implemented."); + } + goToField(title: string): void { + console.log(title); + throw new Error("Method not implemented."); + } + hasEmptyRequiredFields(): boolean { + throw new Error("Method not implemented."); + } } diff --git a/src/tinymce/navigationFields.ts b/src/tinymce/navigationFields.ts new file mode 100644 index 0000000..d2c7a09 --- /dev/null +++ b/src/tinymce/navigationFields.ts @@ -0,0 +1,17 @@ +import { IaraEditorNavigationFieldManager } from "../editor/navigationFields"; + +export class IaraTinyMceNavigationFieldManager extends IaraEditorNavigationFieldManager { + nextField(): void { + throw new Error("Method not implemented."); + } + previousField(): void { + throw new Error("Method not implemented."); + } + goToField(title: string): void { + console.log(title); + throw new Error(`Method not implemented.`); + } + hasEmptyRequiredFields(): boolean { + throw new Error("Method not implemented."); + } +}