diff --git a/package-lock.json b/package-lock.json
index d0158b768..d166fe18b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3857,7 +3857,6 @@
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "dev": true,
"requires": {
"sprintf-js": "~1.0.2"
}
@@ -11820,6 +11819,14 @@
"type-check": "~0.3.2"
}
},
+ "linkify-it": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz",
+ "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==",
+ "requires": {
+ "uc.micro": "^1.0.1"
+ }
+ },
"load-json-file": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
@@ -12049,6 +12056,30 @@
"integrity": "sha512-lbRZ2mE3Q9RtLjxZBZ9+IMl68DKIXaVAhwvwn9pmjnPLS0h/6kyBMgNhqi1xFJ/2yv6cSyv0jbiZavZv93JkkA==",
"dev": true
},
+ "markdown-it": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz",
+ "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==",
+ "requires": {
+ "argparse": "^1.0.7",
+ "entities": "~2.0.0",
+ "linkify-it": "^2.0.0",
+ "mdurl": "^1.0.1",
+ "uc.micro": "^1.0.5"
+ },
+ "dependencies": {
+ "entities": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz",
+ "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw=="
+ }
+ }
+ },
+ "markdown-it-task-lists": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/markdown-it-task-lists/-/markdown-it-task-lists-2.1.1.tgz",
+ "integrity": "sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA=="
+ },
"markdown-table": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.2.tgz",
@@ -12107,6 +12138,11 @@
"unist-util-visit": "^1.1.0"
}
},
+ "mdurl": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
+ "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4="
+ },
"mem": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz",
@@ -15881,8 +15917,7 @@
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
- "dev": true
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
},
"sshpk": {
"version": "1.16.1",
@@ -17320,6 +17355,11 @@
"resolved": "https://registry.npmjs.org/typo-js/-/typo-js-1.1.0.tgz",
"integrity": "sha512-W3kLbx+ML9PBl5Bzso/lTvVxk4BCveSNAtQeht59FEtxCdGThmn6wSHA4Xq3eQYAK24NHdisMM4JmsK0GFy/pg=="
},
+ "uc.micro": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
+ "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
+ },
"unherit": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.1.tgz",
diff --git a/package.json b/package.json
index d9b638347..8debbbfa5 100644
--- a/package.json
+++ b/package.json
@@ -40,6 +40,8 @@
"@nextcloud/vue": "^1.5.0",
"blueimp-md5": "^2.13.0",
"dompurify": "^2.0.8",
+ "markdown-it": "^10.0.0",
+ "markdown-it-task-lists": "^2.1.1",
"moment": "^2.24.0",
"nextcloud-vue-collections": "^0.7.2",
"p-queue": "^6.3.0",
diff --git a/src/components/card/CardSidebar.vue b/src/components/card/CardSidebar.vue
index 7335d32ec..8f7acf539 100644
--- a/src/components/card/CardSidebar.vue
+++ b/src/components/card/CardSidebar.vue
@@ -127,9 +127,22 @@
href="https://deck.readthedocs.io/en/latest/Markdown/"
target="_blank"
class="icon icon-info" />
+
+
+ {{ t('deck', 'Edit description') }}
+
+
+ {{ t('deck', 'View description') }}
+
+
-
-
+
@@ -168,6 +181,11 @@ import { CollectionList } from 'nextcloud-vue-collections'
import CardSidebarTabAttachments from './CardSidebarTabAttachments'
import CardSidebarTabComments from './CardSidebarTabComments'
import CardSidebarTabActivity from './CardSidebarTabActivity'
+import MarkdownIt from 'markdown-it'
+import MarkdownItTaskLists from 'markdown-it-task-lists'
+
+const markdownIt = new MarkdownIt()
+markdownIt.use(MarkdownItTaskLists, { enabled: true, label: true, labelAfter: true })
const capabilities = window.OC.getCapabilities()
@@ -202,8 +220,10 @@ export default {
addedLabelToCard: null,
copiedCard: null,
allLabels: null,
- desc: null,
+
saving: false,
+ markdownIt: null,
+ descriptionEditing: false,
mdeConfig: {
autoDownloadFontAwesome: false,
spellChecker: false,
@@ -265,26 +285,13 @@ export default {
this.saving = false
},
},
+ renderedDescription() {
+ return markdownIt.render(this.copiedCard.description)
+ },
},
watch: {
- 'currentCard': {
- immediate: true,
- handler() {
- if (!this.currentCard) {
- return
- }
- this.copiedCard = JSON.parse(JSON.stringify(this.currentCard))
- this.allLabels = this.currentCard.labels
-
- if (this.currentCard.assignedUsers && this.currentCard.assignedUsers.length > 0) {
- this.assignedUsers = this.currentCard.assignedUsers.map((item) => item.participant)
- } else {
- this.assignedUsers = []
- }
-
- this.desc = this.currentCard.description
- this.updateRelativeTimestamps()
- },
+ currentCard() {
+ this.initialize()
},
},
created() {
@@ -293,7 +300,57 @@ export default {
destroyed() {
clearInterval(this.updateRelativeTimestamps)
},
+ mounted() {
+ this.initialize()
+ },
methods: {
+ initialize() {
+ if (!this.currentCard) {
+ return
+ }
+
+ this.copiedCard = JSON.parse(JSON.stringify(this.currentCard))
+ this.allLabels = this.currentCard.labels
+
+ if (this.currentCard.assignedUsers && this.currentCard.assignedUsers.length > 0) {
+ this.assignedUsers = this.currentCard.assignedUsers.map((item) => item.participant)
+ } else {
+ this.assignedUsers = []
+ }
+
+ this.desc = this.currentCard.description
+ this.updateRelativeTimestamps()
+ },
+ showEditor() {
+ if (!this.canEdit) {
+ return
+ }
+ this.descriptionEditing = true
+ },
+ hideEditor() {
+ this.descriptionEditing = false
+ },
+ clickedPreview(e) {
+ if (e.target.getAttribute('type') === 'checkbox') {
+ const clickedIndex = [...document.querySelector('#description-preview').querySelectorAll('input')].findIndex((li) => li.id === e.target.id)
+ const reg = /\[(X|\s|_|-)\]/ig
+ let nth = 0
+ const updatedDescription = this.copiedCard.description.replace(reg, (match, i, original) => {
+ let result = match
+ if ('' + nth++ === '' + clickedIndex) {
+ if (match.match(/^\[\s\]/i)) {
+ result = match.replace(/\[\s\]/i, '[x]')
+ }
+ if (match.match(/^\[x\]/i)) {
+ result = match.replace(/\[x\]/i, '[ ]')
+ }
+ return result
+ }
+ return match
+ })
+ this.updateDescription(updatedDescription)
+ }
+ },
updateRelativeTimestamps() {
this.lastModifiedRelative = OC.Util.relativeModifiedDate(this.currentCard.lastModified * 1000)
this.lastCreatedRemative = OC.Util.relativeModifiedDate(this.currentCard.createdAt * 1000)
@@ -377,6 +434,8 @@ export default {
@import "~easymde/dist/easymde.min.css";
.vue-easymde, .CodeMirror {
border: none;
+ margin: 0;
+ padding: 0;
}
.editor-preview,
.editor-statusbar {
@@ -398,11 +457,16 @@ export default {
.icon-info {
display: inline-block;
- width: 16px;
+ width: 32px;
height: 16px;
float: right;
opacity: .7;
}
+
+ .icon-toggle, .icon-rename {
+ float: right;
+ margin-top: -14px;
+ }
}
aside::v-deep section {
@@ -469,4 +533,13 @@ export default {
.multiselect.multiselect--active::v-deep .multiselect__tags-wrap {
z-index: 0;
}
+
+ #description-preview {
+ min-height: 100px;
+
+ &::v-deep input {
+ min-height: auto;
+ }
+ }
+