diff --git a/package-lock.json b/package-lock.json index 6ac9cde21..354169b04 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3305,18 +3305,18 @@ } }, "@nextcloud/auth": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@nextcloud/auth/-/auth-0.3.1.tgz", - "integrity": "sha512-kx5VfB2SWG+BNudoggnjQrmxr559rCDANVLnaDDKmCujToxv0l3kNMTBUUcYhSvv8dyYaD/ZTaXBUON9ZLm9lw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@nextcloud/auth/-/auth-1.2.1.tgz", + "integrity": "sha512-54g9YPQBFJ+upYMfk5aZhTispuORY/D2R6WdSesJO/hirob7jSpQoUcWuURQj2tssuxADDSgD1rUAiBnbCe1OQ==", "requires": { - "@nextcloud/event-bus": "^0.2.0", - "core-js": "3.2.1" + "@nextcloud/event-bus": "^1.1.2", + "core-js": "3.6.1" }, "dependencies": { "core-js": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.2.1.tgz", - "integrity": "sha512-Qa5XSVefSVPRxy2XfUC13WbvqkxhkwB3ve+pgCQveNgYzbM/UxZeu1dcOX/xr4UmfUd+muuvsaxilQzCyUurMw==" + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.1.tgz", + "integrity": "sha512-186WjSik2iTGfDjfdCZAxv2ormxtKgemjC3SI6PL31qOA0j5LhTDVjHChccoc7brwLvpvLPiMyRlcO88C4l1QQ==" } } }, @@ -3334,6 +3334,30 @@ "core-js": "^3.2.1" }, "dependencies": { + "@nextcloud/auth": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@nextcloud/auth/-/auth-0.3.1.tgz", + "integrity": "sha512-kx5VfB2SWG+BNudoggnjQrmxr559rCDANVLnaDDKmCujToxv0l3kNMTBUUcYhSvv8dyYaD/ZTaXBUON9ZLm9lw==", + "requires": { + "@nextcloud/event-bus": "^0.2.0", + "core-js": "3.2.1" + }, + "dependencies": { + "core-js": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.2.1.tgz", + "integrity": "sha512-Qa5XSVefSVPRxy2XfUC13WbvqkxhkwB3ve+pgCQveNgYzbM/UxZeu1dcOX/xr4UmfUd+muuvsaxilQzCyUurMw==" + } + } + }, + "@nextcloud/event-bus": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@nextcloud/event-bus/-/event-bus-0.2.1.tgz", + "integrity": "sha512-yerEPTA5lnJ1JV8qYK6sHMWW8m6fxuMEtptVgv7WnGCy2l5rvxDh9vqwk72qX/Z9i2OrC7Jy382TMYbke8b2Qw==", + "requires": { + "core-js": "^3.1.4" + } + }, "core-js": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.5.0.tgz", @@ -3348,17 +3372,29 @@ "dev": true }, "@nextcloud/event-bus": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@nextcloud/event-bus/-/event-bus-0.2.1.tgz", - "integrity": "sha512-yerEPTA5lnJ1JV8qYK6sHMWW8m6fxuMEtptVgv7WnGCy2l5rvxDh9vqwk72qX/Z9i2OrC7Jy382TMYbke8b2Qw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@nextcloud/event-bus/-/event-bus-1.1.2.tgz", + "integrity": "sha512-E+j71+2LkqEdRjKLrmCKS/fEeI/NxSfthvDH2YkxIK0uH4ZSC+nlzmrNOr0Jby3z0qOgA8PH7+vSLU3D8qdTzw==", "requires": { - "core-js": "^3.1.4" + "@types/semver": "^6.2.0", + "core-js": "^3.6.2", + "semver": "^6.3.0" }, "dependencies": { + "@types/semver": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-6.2.0.tgz", + "integrity": "sha512-1OzrNb4RuAzIT7wHSsgZRlMBlNsJl+do6UblR7JMW4oB7bbR+uBEYtUh7gEc/jM84GGilh68lSOokyM/zNUlBA==" + }, "core-js": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.3.2.tgz", - "integrity": "sha512-S1FfZpeBchkhyoY76YAdFzKS4zz9aOK7EeFaNA2aJlyXyA+sgqz6xdxmLPGXEAf0nF44MVN1kSjrA9Kt3ATDQg==" + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.4.tgz", + "integrity": "sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw==" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, diff --git a/package.json b/package.json index 52a5a0b3f..b573a7c23 100644 --- a/package.json +++ b/package.json @@ -28,18 +28,19 @@ "dependencies": { "@babel/polyfill": "^7.8.3", "@babel/runtime": "^7.8.3", + "@nextcloud/auth": "^1.2.1", "@nextcloud/l10n": "^1.0.1", "@nextcloud/router": "^1.0.0", "@nextcloud/vue": "^1.2.7", + "fuse.js": "^3.4.5", "nextcloud-axios": "^0.2.1", "nextcloud-server": "^0.15.10", "nextcloud-vue-collections": "^0.7.1", - "url-search-params-polyfill": "^7.0.1", - "vue": "^2.6.11", - "fuse.js": "^3.4.5", "tippy.js": "^4.3.5", "tiptap": "^1.26.3", "tiptap-extensions": "^1.28.3", + "url-search-params-polyfill": "^7.0.1", + "vue": "^2.6.11", "vue-click-outside": "^1.0.7", "vue-color": "^2.7.0", "vue-easymde": "^1.0.1", diff --git a/src/components/ActivityEntry.vue b/src/components/ActivityEntry.vue index ca5017187..84e299056 100644 --- a/src/components/ActivityEntry.vue +++ b/src/components/ActivityEntry.vue @@ -59,6 +59,8 @@ export default { diff --git a/src/components/card/CommentsTabSidebar.vue b/src/components/card/CommentsTabSidebar.vue index 79bf9cc3e..5aa091564 100644 --- a/src/components/card/CommentsTabSidebar.vue +++ b/src/components/card/CommentsTabSidebar.vue @@ -1,28 +1,21 @@ @@ -44,16 +36,20 @@ -

{{ comment.id }}

- -
- - - - +
+
+
+

Keine Kommentare bisher. Beginne die Diskussion!

+
@@ -64,25 +60,21 @@ import { Editor, EditorContent } from 'tiptap' import { Mention } from 'tiptap-extensions' import { mapState } from 'vuex' -import { Avatar } from 'nextcloud-vue' -import { Actions } from 'nextcloud-vue/dist/Components/Actions' -import { ActionButton } from 'nextcloud-vue/dist/Components/ActionButton' +import { Avatar } from '@nextcloud/vue' import CommentItem from './CommentItem' export default { name: 'CommentsTabSidebar', components: { Avatar, - Actions, - ActionButton, CommentItem, - EditorContent + EditorContent, }, props: { card: { type: Object, - default: undefined - } + default: undefined, + }, }, data() { return { @@ -100,7 +92,7 @@ export default { }, // is called when a suggestion starts onEnter: ({ - items, query, range, command, virtualNode + items, query, range, command, virtualNode, }) => { this.query = query this.filteredUsers = items @@ -113,7 +105,7 @@ export default { }, // is called when a suggestion has changed onChange: ({ - items, query, range, virtualNode + items, query, range, virtualNode, }) => { this.query = query this.filteredUsers = items @@ -159,30 +151,30 @@ export default { } const fuse = new Fuse(items, { threshold: 0.2, - keys: ['uid', 'displayname'] + keys: ['uid', 'displayname'], }) return fuse.search(query) - } - }) + }, + }), ], content: '', onUpdate: ({ getHTML }) => { this.newComment = getHTML().replace(/(

|<\/p>)/g, '') - } + }, }), query: null, suggestionRange: null, filteredUsers: [], navigatedUserIndex: 0, insertMention: () => {}, - observer: null + observer: null, } }, computed: { ...mapState({ comments: state => state.comment.comments, - currentBoard: state => state.currentBoard + currentBoard: state => state.currentBoard, }), hasResults() { @@ -190,7 +182,7 @@ export default { }, showSuggestions() { return this.query || this.hasResults - } + }, }, watch: { @@ -198,8 +190,8 @@ export default { immediate: true, handler() { this.loadComments() - } - } + }, + }, }, created() { }, @@ -214,13 +206,14 @@ export default { }) }, createComment() { - let commentObj = { + const commentObj = { cardId: this.card.id, - comment: this.newComment + comment: this.newComment, } this.$store.dispatch('createComment', commentObj) this.loadComments() this.newComment = '' + this.editor.setContent('') }, loadMore() { this.offset = this.offset + this.limit @@ -250,8 +243,8 @@ export default { range: this.suggestionRange, attrs: { id: user.uid, - label: user.displayname - } + label: user.displayname, + }, }) this.editor.focus() }, @@ -268,7 +261,7 @@ export default { placement: 'bottom-start', inertia: true, duration: [400, 200], - showOnInit: true + showOnInit: true, }) // we have to update tippy whenever the DOM is updated if (MutationObserver) { @@ -278,7 +271,7 @@ export default { this.observer.observe(this.$refs.suggestions, { childList: true, subtree: true, - characterData: true + characterData: true, }) } }, @@ -290,30 +283,11 @@ export default { if (this.observer) { this.observer.disconnect() } - } - } + }, + }, } diff --git a/src/helpers/xml.js b/src/helpers/xml.js index de5b0ad99..3c40af3e0 100644 --- a/src/helpers/xml.js +++ b/src/helpers/xml.js @@ -19,7 +19,7 @@ const xmlToJson = (xml) => { obj[nodeName] = xmlToJson(item) } else { if (typeof obj[nodeName].push === 'undefined') { - var old = obj[nodeName] + const old = obj[nodeName] obj[nodeName] = [] obj[nodeName].push(old) } @@ -38,42 +38,41 @@ const parseXml = (xml) => { } return dom } + +const commentToObject = (tag) => { + return { + cardId: tag['d:prop']['oc:objectId']['#text'], + id: tag['d:prop']['oc:id']['#text'], + actorId: tag['d:prop']['oc:actorId']['#text'], + actorDisplayName: tag['d:prop']['oc:actorDisplayName']['#text'], + creationDateTime: tag['d:prop']['oc:creationDateTime']['#text'], + message: tag['d:prop']['oc:message']['#text'], + } +} + +// FIXME: make this generic and not depending on comments const xmlToTagList = (xml) => { - let json = xmlToJson(parseXml(xml)) - let list = json['d:multistatus']['d:response'] + const json = xmlToJson(parseXml(xml)) + const list = json['d:multistatus']['d:response'] // no element if (list === undefined) { return [] } - let result = [] + const result = [] // one element if (Array.isArray(list) === false) { - let tag = list['d:propstat'] - result.push({ - cardId: tag['d:prop']['oc:objectId']['#text'], - id: tag['d:prop']['oc:id']['#text'], - uId: tag['d:prop']['oc:actorId']['#text'], - creationDateTime: tag['d:prop']['oc:creationDateTime']['#text'], - message: tag['d:prop']['oc:message']['#text'] - }) + result.push(commentToObject(list['d:propstat'])) // two or more elements } else { - for (let index in list) { - let tag = list[index]['d:propstat'] - if (tag['d:status']['#text'] !== 'HTTP/1.1 200 OK') { + for (const index in list) { + if (list[index]['d:propstat']['d:status']['#text'] !== 'HTTP/1.1 200 OK') { continue } - result.push({ - cardId: tag['d:prop']['oc:objectId']['#text'], - id: tag['d:prop']['oc:id']['#text'], - uId: tag['d:prop']['oc:actorId']['#text'], - creationDateTime: tag['d:prop']['oc:creationDateTime']['#text'], - message: tag['d:prop']['oc:message']['#text'] - }) + result.push(commentToObject(list[index]['d:propstat'])) } } return result diff --git a/src/services/CommentApi.js b/src/services/CommentApi.js index aaa35b5d3..111fa275e 100644 --- a/src/services/CommentApi.js +++ b/src/services/CommentApi.js @@ -38,7 +38,7 @@ export class CommentApi { ${card.limit} ${card.offset} - ` + `, }).then( (response) => { return Promise.resolve(response.data) @@ -56,19 +56,19 @@ export class CommentApi { return axios({ method: 'POST', url: this.url(`${commentObj.cardId}`), - data: { actorType: 'users', message: `${commentObj.comment}`, verb: 'comment' } + data: { actorType: 'users', message: `${commentObj.comment}`, verb: 'comment' }, }).then( (response) => { - let header = response.headers['content-location'] - let headerArray = header.split('/') - let id = headerArray[headerArray.length - 1] + const header = response.headers['content-location'] + const headerArray = header.split('/') + const id = headerArray[headerArray.length - 1] - let ret = { + const ret = { cardId: (commentObj.cardId).toString(), id: id, uId: getCurrentUser().uid, creationDateTime: (new Date()).toString(), - message: commentObj.comment + message: commentObj.comment, } return Promise.resolve(ret) }, @@ -92,7 +92,7 @@ export class CommentApi { ${data.comment} - ` + `, }).then( (response) => { return Promise.resolve(response.data) @@ -109,7 +109,7 @@ export class CommentApi { deleteComment(data) { return axios({ method: 'DELETE', - url: this.url(`${data.cardId}/${data.commentId}`) + url: this.url(`${data.cardId}/${data.commentId}`), }).then( (response) => { return Promise.resolve(response.data) diff --git a/src/store/comment.js b/src/store/comment.js index a1c742cef..0aac6239e 100644 --- a/src/store/comment.js +++ b/src/store/comment.js @@ -28,7 +28,7 @@ const apiClient = new CommentApi() export default { state: { - comments: {} + comments: {}, }, mutations: { addComments(state, commentObj) { @@ -47,26 +47,26 @@ export default { state.comments[newComment.cardId].push(newComment) }, updateComment(state, comment) { - let existingIndex = state.comments[comment.cardId].findIndex(_comment => _comment.id === comment.commentId) + const existingIndex = state.comments[comment.cardId].findIndex(_comment => _comment.id === comment.commentId) if (existingIndex !== -1) { state.comments[comment.cardId][existingIndex].message = comment.comment } }, deleteComment(state, comment) { - let existingIndex = state.comments[comment.cardId].findIndex(_comment => _comment.id === comment.commentId) + const existingIndex = state.comments[comment.cardId].findIndex(_comment => _comment.id === comment.commentId) if (existingIndex !== -1) { state.comments[comment.cardId].splice(existingIndex, 1) } - } + }, }, actions: { listComments({ commit }, card) { apiClient.listComments(card) .then((comments) => { const commentsJson = xmlToTagList(comments) - let returnObj = { + const returnObj = { cardId: card.id, - comments: commentsJson + comments: commentsJson, } commit('addComments', returnObj) }) @@ -88,6 +88,6 @@ export default { .then((retVal) => { commit('updateComment', data) }) - } - } + }, + }, } diff --git a/src/store/main.js b/src/store/main.js index 63da326a0..fa4fa2168 100644 --- a/src/store/main.js +++ b/src/store/main.js @@ -95,7 +95,7 @@ export default new Vuex.Store({ }, currentBoardLabels: state => { return state.currentBoard ? state.currentBoard.labels : [] - } + }, }, mutations: { toggleShowArchived(state) {