task detail editor: používáme CKEditor5
This commit is contained in:
		
							parent
							
								
									e21fc20335
								
							
						
					
					
						commit
						0d684ca4f3
					
				
					 4 changed files with 74 additions and 21 deletions
				
			
		|  | @ -24,9 +24,9 @@ | |||
|     "typescript": "^3.9.3" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@ckeditor/ckeditor5-build-classic": "^23.0.0", | ||||
|     "@types/d3": "^5.7.2", | ||||
|     "d3": "^6.2.0", | ||||
|     "sigma": "1.2.1", | ||||
|     "sirv-cli": "^1.0.0", | ||||
|     "svelte-simple-modal": "^0.6.1" | ||||
|   } | ||||
|  |  | |||
|  | @ -58,7 +58,7 @@ | |||
|       TaskDetailEditor, | ||||
|       { task: e.detail, tasks: tasks }, | ||||
|       { closeButton: false }, | ||||
|       { onClose: () => { console.log("callback invoked", tasks); tasks = tasks; }} | ||||
|       { onClose: () => { tasks = tasks; }} | ||||
|     ); | ||||
|   } | ||||
| </script> | ||||
|  |  | |||
|  | @ -2,7 +2,9 @@ | |||
|     import { getCategories } from "./task-loader"; | ||||
|     import type { TaskDescriptor, TasksFile } from "./task-loader"; | ||||
|     import { getContext } from "svelte"; | ||||
|     import { copyFieldsThatExist } from "./helpers"; | ||||
|     import { onMount } from "svelte"; | ||||
|     import ClassicEditor from "@ckeditor/ckeditor5-build-classic"; | ||||
| import App from "./App.svelte"; | ||||
| 
 | ||||
|     const { close } = getContext("simple-modal"); | ||||
| 
 | ||||
|  | @ -20,38 +22,89 @@ | |||
|         categories: getCategories(tasks, task.id), | ||||
|     }; | ||||
| 
 | ||||
|     // setup editor | ||||
|     let editor; | ||||
|     onMount(() => { | ||||
|         ClassicEditor.create(document.querySelector("#editor")) | ||||
|             .then((e) => { | ||||
|                 editor = e; | ||||
|             }) | ||||
|             .catch((error) => { | ||||
|                 alert("Editor init error. Open console to see details."); | ||||
|                 console.error(error); | ||||
|             }); | ||||
|     }); | ||||
| 
 | ||||
|     function removeCategory(catName: string) { | ||||
|         return function () { | ||||
|             editData.categories = editData.categories.filter((t) => t != catName); | ||||
|             editData.categories = editData.categories.filter( | ||||
|                 (t) => t != catName | ||||
|             ); | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     function removeDependency(dep: string) { | ||||
|         return function () { | ||||
|             editData.task.requires = editData.task.requires.filter((t) => t != dep); | ||||
|             editData.task.requires = editData.task.requires.filter( | ||||
|                 (t) => t != dep | ||||
|             ); | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     function saveAndExit() { | ||||
|         if (editData.task.type == "text") | ||||
|             editData.task.htmlContent = editor.getData() | ||||
|         Object.assign(task, editData.task); | ||||
| 
 | ||||
|         // kategorie musíme první odevšad odstranit | ||||
|         for (const t of Object.keys(tasks.clusters)) { | ||||
|             tasks.clusters[t] = tasks.clusters[t].filter( | ||||
|                 (id) => id != editData.task.id | ||||
|             ); | ||||
|         } | ||||
|         // a pak všude přidat | ||||
|         for (const t of editData.categories) { | ||||
|             tasks.clusters[t] = [ | ||||
|                 ...(tasks.clusters[t] ?? []), | ||||
|                 editData.task.id, | ||||
|             ]; | ||||
|             tasks.clusters[t].sort(); // make git happy | ||||
|         } | ||||
| 
 | ||||
|         // a nakonec zavřít dialog | ||||
|         close(); | ||||
|     } | ||||
| 
 | ||||
|    | ||||
| </script> | ||||
| 
 | ||||
| <div> | ||||
|     <div><i>ID:</i> {editData.task.id}, TYPE: {editData.task.type}</div> | ||||
|     <div> | ||||
|         <span><i>ID:</i> {editData.task.id},</span> | ||||
|         <span> | ||||
|             TYPE: <select | ||||
|                 bind:value={editData.task.type} | ||||
|                 on:blur={() => { | ||||
|                     editData = editData; | ||||
|                 }}> | ||||
|                 <option value="open-data">open-data</option> | ||||
|                 <option value="text">text</option> | ||||
|                 <option value="label">label</option> | ||||
|             </select> | ||||
|         </span> | ||||
|     </div> | ||||
|     <h1> | ||||
|         <i>TITLE:</i> | ||||
|         <span contenteditable="true" bind:textContent={editData.task.title} /> | ||||
|     </h1> | ||||
|     <div> | ||||
|         <i>COMMENT:</i> | ||||
|         <span contenteditable="true" bind:textContent={editData.task.comment} /> | ||||
|         <h3>Interní komentář</h3> | ||||
|         <div contenteditable="true" bind:textContent={editData.task.comment} /> | ||||
|     </div> | ||||
|     <div style="display: {editData.task.type == "text" ? 'block' : 'none'}"> | ||||
|         <h3>HTML obsah</h3> | ||||
|         <textarea id="editor">{editData.task.htmlContent}</textarea> | ||||
|     </div> | ||||
|     {#if editData.task.type == "text"} | ||||
|         <div><i>HTML obsah:</i></div> | ||||
|         <div contenteditable="true" bind:textContent={editData.task.htmlContent} /> | ||||
|     {/if} | ||||
|     <hr /> | ||||
|     <div> | ||||
|         <h3>Kategorie</h3> | ||||
|  | @ -90,14 +143,14 @@ | |||
|     </div> | ||||
|     <hr /> | ||||
|     <div> | ||||
|         <button on:click={saveAndExit}>Uložit a zavřít</button> | ||||
|         <button on:click={close}>Zrušit</button> | ||||
|         <button on:click={saveAndExit}>Aplikovat</button> | ||||
|         <button on:click={close}>Zrušit změny</button> | ||||
|     </div> | ||||
|     <hr /> | ||||
|     <div> | ||||
|         <h3>Vysvětlivky</h3> | ||||
|         <i>Kurzívou je psaný text, který nesouvisí s daty. Některý text psaný | ||||
|             nekurzívou se dá editovat. Změna typu ale třeba není možná, na to je | ||||
|             potřeba upravit přímo soubor <code>tasks.json</code>.</i> | ||||
|             nekurzívou se dá editovat. Jakékoliv velké operace je ale vhodné | ||||
|             dělat přímo se souborem <code>tasks.json</code></i> | ||||
|     </div> | ||||
| </div> | ||||
|  |  | |||
|  | @ -23,6 +23,11 @@ | |||
|     chalk "^2.0.0" | ||||
|     js-tokens "^4.0.0" | ||||
| 
 | ||||
| "@ckeditor/ckeditor5-build-classic@^23.0.0": | ||||
|   version "23.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-build-classic/-/ckeditor5-build-classic-23.0.0.tgz#9b4ae5dc470e9ae4be14672b49d05d21887e2d81" | ||||
|   integrity sha512-9Pgb9OAPnx1577WDYizEuOFHmLyXkwU8UxneyP4Zkr9mrJUEL0w0uVgQhiB8DYlAAArHXeFasSogwFvLX6xBtw== | ||||
| 
 | ||||
| "@emmetio/extract-abbreviation@0.1.6": | ||||
|   version "0.1.6" | ||||
|   resolved "https://registry.yarnpkg.com/@emmetio/extract-abbreviation/-/extract-abbreviation-0.1.6.tgz#e4a9856c1057f0aff7d443b8536477c243abe28c" | ||||
|  | @ -1208,11 +1213,6 @@ serialize-javascript@^4.0.0: | |||
|   dependencies: | ||||
|     randombytes "^2.1.0" | ||||
| 
 | ||||
| sigma@1.2.1: | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/sigma/-/sigma-1.2.1.tgz#2ebf3df2971715afe49ad0c08945c574bb6c5771" | ||||
|   integrity sha512-9Z0m1pssXv6sndPMvOzXnM1mVO73YCWDE6X5bKxJyG+9J0B9zJkgtgoBM7cnxEaJMzmrbxPceKTVpwF7cS/xqA== | ||||
| 
 | ||||
| sirv-cli@^1.0.0: | ||||
|   version "1.0.6" | ||||
|   resolved "https://registry.yarnpkg.com/sirv-cli/-/sirv-cli-1.0.6.tgz#a4924254d965b23a518512f70010e710185de2f1" | ||||
|  |  | |||
		Reference in a new issue