Merge pull request #1418 from nextcloud/dependabot/npm_and_yarn/vue/eslint-plugin-node-11.0.0

Bump eslint-plugin-node from 8.0.1 to 11.0.0
This commit is contained in:
Julius Härtl
2020-01-05 19:04:32 +01:00
committed by GitHub
37 changed files with 597 additions and 564 deletions

View File

@@ -1,67 +1,8 @@
module.exports = { module.exports = {
root: true,
env: {
browser: true,
es6: true,
node: true,
jest: true
},
globals: {
t: true,
n: true,
OC: true,
OCA: true,
Vue: true,
VueRouter: true
},
parserOptions: {
parser: 'babel-eslint',
ecmaVersion: 6
},
extends: [ extends: [
'eslint:recommended', 'nextcloud'
'plugin:node/recommended',
'plugin:vue/essential',
'plugin:vue/recommended',
'standard'
], ],
plugins: ['vue', 'node'],
rules: { rules: {
// space before function () 'valid-jsdoc': ['warn'],
'space-before-function-paren': ['error', 'never'],
// curly braces always space
'object-curly-spacing': ['error', 'always'],
// stay consistent with array brackets
'array-bracket-newline': ['error', 'consistent'],
// 1tbs brace style
'brace-style': 'error',
// tabs only
indent: ['error', 'tab'],
'no-tabs': 0,
'vue/html-indent': ['error', 'tab'],
// only debug console
'no-console': ['warn', { allow: ['error', 'warn', 'debug'] }],
// classes blocks
'padded-blocks': ['error', { classes: 'always' }],
// always have the operator in front
'operator-linebreak': ['error', 'before'],
// ternary on multiline
'multiline-ternary': ['error', 'always-multiline'],
// es6 import/export and require
'node/no-unpublished-require': ['off'],
'node/no-unsupported-features/es-syntax': ['off'],
// space before self-closing elements
'vue/html-closing-bracket-spacing': 'error',
// code spacing with attributes
'vue/max-attributes-per-line': [
'error',
{
singleline: 3,
multiline: {
max: 3,
allowFirstLine: true
}
}
]
} }
} }

97
package-lock.json generated
View File

@@ -6976,6 +6976,12 @@
} }
} }
}, },
"eslint-config-nextcloud": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/eslint-config-nextcloud/-/eslint-config-nextcloud-0.1.1.tgz",
"integrity": "sha512-/1VAkt7Y/m63eZfBiYkSzZMwQtmz0DFXuJnLebrzIY1GtpIj/Y3c//j4ZDiH5o0vbdn9laIc2Mb/01DIjzvt3g==",
"dev": true
},
"eslint-config-standard": { "eslint-config-standard": {
"version": "12.0.0", "version": "12.0.0",
"resolved": "http://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-12.0.0.tgz", "resolved": "http://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-12.0.0.tgz",
@@ -7146,19 +7152,34 @@
} }
}, },
"eslint-plugin-es": { "eslint-plugin-es": {
"version": "1.4.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-1.4.0.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.0.tgz",
"integrity": "sha512-XfFmgFdIUDgvaRAlaXUkxrRg5JSADoRC8IkKLc/cISeR3yHVMefFHQZpcyXXEUUPHfy5DwviBcrfqlyqEwlQVw==", "integrity": "sha512-6/Jb/J/ZvSebydwbBJO1R9E5ky7YeElfK56Veh7e4QGFHCXoIXGH9HhVz+ibJLM3XJ1XjP+T7rKBLUa/Y7eIng==",
"dev": true, "dev": true,
"requires": { "requires": {
"eslint-utils": "^1.3.0", "eslint-utils": "^2.0.0",
"regexpp": "^2.0.1" "regexpp": "^3.0.0"
}, },
"dependencies": { "dependencies": {
"eslint-utils": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz",
"integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==",
"dev": true,
"requires": {
"eslint-visitor-keys": "^1.1.0"
}
},
"eslint-visitor-keys": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz",
"integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==",
"dev": true
},
"regexpp": { "regexpp": {
"version": "2.0.1", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.0.0.tgz",
"integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", "integrity": "sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g==",
"dev": true "dev": true
} }
} }
@@ -7261,24 +7282,54 @@
} }
} }
}, },
"eslint-plugin-node": { "eslint-plugin-nextcloud": {
"version": "8.0.1", "version": "0.3.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-8.0.1.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-nextcloud/-/eslint-plugin-nextcloud-0.3.0.tgz",
"integrity": "sha512-ZjOjbjEi6jd82rIpFSgagv4CHWzG9xsQAVp1ZPlhRnnYxcTgENUVBvhYmkQ7GvT1QFijUSo69RaiOJKhMu6i8w==", "integrity": "sha512-LUD2qdirGL0BRt4uaMDGxen17mWVq9JwuGDt7P7Celz7bzdu0X48RrS8mhXn9e0w78+nYN5kPoULG2Bw04r4HA==",
"dev": true, "dev": true,
"requires": { "requires": {
"eslint-plugin-es": "^1.3.1", "requireindex": "~1.2.0"
"eslint-utils": "^1.3.1", }
"ignore": "^5.0.2", },
"eslint-plugin-node": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.0.0.tgz",
"integrity": "sha512-chUs/NVID+sknFiJzxoN9lM7uKSOEta8GC8365hw1nDfwIPIjjpRSwwPvQanWv8dt/pDe9EV4anmVSwdiSndNg==",
"dev": true,
"requires": {
"eslint-plugin-es": "^3.0.0",
"eslint-utils": "^2.0.0",
"ignore": "^5.1.1",
"minimatch": "^3.0.4", "minimatch": "^3.0.4",
"resolve": "^1.8.1", "resolve": "^1.10.1",
"semver": "^5.5.0" "semver": "^6.1.0"
}, },
"dependencies": { "dependencies": {
"eslint-utils": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz",
"integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==",
"dev": true,
"requires": {
"eslint-visitor-keys": "^1.1.0"
}
},
"eslint-visitor-keys": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz",
"integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==",
"dev": true
},
"ignore": { "ignore": {
"version": "5.1.2", "version": "5.1.4",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.2.tgz", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz",
"integrity": "sha512-vdqWBp7MyzdmHkkRWV5nY+PfGRbYbahfuvsBCh277tq+w9zyNi7h5CYJCK0kmzti9kU+O/cB7sE8HvKv6aXAKQ==", "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==",
"dev": true
},
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true "dev": true
} }
} }
@@ -15196,6 +15247,12 @@
"integrity": "sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4=", "integrity": "sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4=",
"dev": true "dev": true
}, },
"requireindex": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz",
"integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==",
"dev": true
},
"resolve": { "resolve": {
"version": "1.12.0", "version": "1.12.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz",

View File

@@ -62,11 +62,13 @@
"babel-loader": "^8.0.6", "babel-loader": "^8.0.6",
"css-loader": "^3.4.1", "css-loader": "^3.4.1",
"eslint": "^6.8.0", "eslint": "^6.8.0",
"eslint-config-nextcloud": "^0.1.1",
"eslint-config-standard": "^12.0.0", "eslint-config-standard": "^12.0.0",
"eslint-friendly-formatter": "^4.0.1", "eslint-friendly-formatter": "^4.0.1",
"eslint-loader": "^3.0.3", "eslint-loader": "^3.0.3",
"eslint-plugin-import": "^2.19.1", "eslint-plugin-import": "^2.19.1",
"eslint-plugin-node": "^8.0.1", "eslint-plugin-nextcloud": "^0.3.0",
"eslint-plugin-node": "^11.0.0",
"eslint-plugin-promise": "^4.2.1", "eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1", "eslint-plugin-standard": "^4.0.1",
"eslint-plugin-vue": "^6.1.2", "eslint-plugin-vue": "^6.1.2",

View File

@@ -41,7 +41,7 @@ const boardApi = new BoardApi()
export default { export default {
name: 'App', name: 'App',
components: { components: {
AppNavigation AppNavigation,
}, },
data: function() { data: function() {
return { return {
@@ -54,19 +54,19 @@ export default {
action: () => { action: () => {
}, },
reset: () => { reset: () => {
} },
}, },
action: () => { action: () => {
this.addButton.classes.push('editing') this.addButton.classes.push('editing')
} },
} },
} }
}, },
computed: { computed: {
...mapState({ ...mapState({
navShown: state => state.navShown, navShown: state => state.navShown,
sidebarShownState: state => state.sidebarShown, sidebarShownState: state => state.sidebarShown,
currentBoard: state => state.currentBoard currentBoard: state => state.currentBoard,
}), }),
// TODO: properly handle sidebar showing for route subview and board sidebar // TODO: properly handle sidebar showing for route subview and board sidebar
sidebarRouterView() { sidebarRouterView() {
@@ -75,17 +75,17 @@ export default {
}, },
sidebarShown() { sidebarShown() {
return this.sidebarRouterView || this.sidebarShownState return this.sidebarRouterView || this.sidebarShownState
} },
}, },
provide: function() { provide: function() {
return { return {
boardApi: boardApi boardApi: boardApi,
} }
}, },
created: function() { created: function() {
this.$store.dispatch('loadBoards') this.$store.dispatch('loadBoards')
this.$store.dispatch('loadSharees') this.$store.dispatch('loadSharees')
} },
} }
</script> </script>

View File

@@ -25,10 +25,10 @@
<div id="modal-inner" :class="{ 'icon-loading': loading }"> <div id="modal-inner" :class="{ 'icon-loading': loading }">
<h1>{{ t('deck', 'Select the board to link to a project') }}</h1> <h1>{{ t('deck', 'Select the board to link to a project') }}</h1>
<ul v-if="!loading"> <ul v-if="!loading">
<li v-for="board in availableBoards" :key="board.id" <li v-for="board in availableBoards"
:key="board.id"
:class="{'selected': (selectedBoard === board.id) }" :class="{'selected': (selectedBoard === board.id) }"
@click="selectedBoard=board.id" @click="selectedBoard=board.id">
>
<span :style="{ 'backgroundColor': '#' + board.color }" class="board-bullet" /> <span :style="{ 'backgroundColor': '#' + board.color }" class="board-bullet" />
<span>{{ board.title }}</span> <span>{{ board.title }}</span>
</li> </li>
@@ -78,22 +78,22 @@ import { Modal } from '@nextcloud/vue/dist/Components/Modal'
import axios from 'nextcloud-axios' import axios from 'nextcloud-axios'
export default { export default {
name: 'CollaborationView', name: 'BoardSelector',
components: { components: {
Modal Modal,
}, },
data() { data() {
return { return {
boards: [], boards: [],
selectedBoard: null, selectedBoard: null,
loading: true, loading: true,
currentBoard: null currentBoard: null,
} }
}, },
computed: { computed: {
availableBoards() { availableBoards() {
return this.boards.filter((board) => ('' + board.id !== '' + this.currentBoard)) return this.boards.filter((board) => ('' + board.id !== '' + this.currentBoard))
} },
}, },
beforeMount() { beforeMount() {
this.fetchBoards() this.fetchBoards()
@@ -111,8 +111,8 @@ export default {
}, },
select() { select() {
this.$root.$emit('select', this.selectedBoard) this.$root.$emit('select', this.selectedBoard)
} },
} },
} }
</script> </script>

View File

@@ -23,14 +23,16 @@
<template> <template>
<Modal :title="t('deck', 'Select the card to link to a project')" @close="close"> <Modal :title="t('deck', 'Select the card to link to a project')" @close="close">
<div id="modal-inner" :class="{ 'icon-loading': loading }"> <div id="modal-inner" :class="{ 'icon-loading': loading }">
<Multiselect v-model="selectedBoard" :placeholder="t('deck', 'Select a board')" :options="boards" <Multiselect v-model="selectedBoard"
:placeholder="t('deck', 'Select a board')"
:options="boards"
label="title" label="title"
@select="fetchCardsFromBoard" @select="fetchCardsFromBoard" />
/>
<Multiselect v-model="selectedCard" :placeholder="t('deck', 'Select a card')" :options="cardsFromBoard" <Multiselect v-model="selectedCard"
label="title" :placeholder="t('deck', 'Select a card')"
/> :options="cardsFromBoard"
label="title" />
<button :disabled="!isBoardAndStackChoosen" class="primary" @click="select"> <button :disabled="!isBoardAndStackChoosen" class="primary" @click="select">
{{ t('deck', 'Link to card') }} {{ t('deck', 'Link to card') }}
@@ -48,10 +50,10 @@ import { Multiselect } from '@nextcloud/vue/dist/Components/Multiselect'
import axios from 'nextcloud-axios' import axios from 'nextcloud-axios'
export default { export default {
name: 'CollaborationView', name: 'CardSelector',
components: { components: {
Modal, Modal,
Multiselect Multiselect,
}, },
data() { data() {
return { return {
@@ -59,7 +61,7 @@ export default {
selectedBoard: '', selectedBoard: '',
cardsFromBoard: [], cardsFromBoard: [],
selectedCard: '', selectedCard: '',
loading: true loading: true,
} }
}, },
computed: { computed: {
@@ -68,7 +70,7 @@ export default {
return false return false
} }
return true return true
} },
}, },
beforeMount() { beforeMount() {
this.fetchBoards() this.fetchBoards()
@@ -83,8 +85,8 @@ export default {
async fetchCardsFromBoard(board) { async fetchCardsFromBoard(board) {
try { try {
this.cardsFromBoard = [] this.cardsFromBoard = []
let url = OC.generateUrl('/apps/deck/stacks/' + board.id) const url = OC.generateUrl('/apps/deck/stacks/' + board.id)
let response = await axios.get(url) const response = await axios.get(url)
response.data.forEach(stack => { response.data.forEach(stack => {
this.cardsFromBoard.push(...stack.cards) this.cardsFromBoard.push(...stack.cards)
}) })
@@ -99,8 +101,8 @@ export default {
select() { select() {
this.$root.$emit('select', this.selectedCard.id) this.$root.$emit('select', this.selectedCard.id)
} },
} },
} }
</script> </script>

View File

@@ -36,23 +36,23 @@ export default {
props: { props: {
activity: { activity: {
type: Object, type: Object,
default: null default: null,
} },
}, },
methods: { methods: {
getTime(timestamp) { getTime(timestamp) {
return OC.Util.relativeModifiedDate(timestamp) return OC.Util.relativeModifiedDate(timestamp)
}, },
parseMessage(activity) { parseMessage(activity) {
let subject = activity.subject_rich[0] const subject = activity.subject_rich[0]
let parameters = activity.subject_rich[1] const parameters = activity.subject_rich[1]
if (parameters.after && typeof parameters.after.id === 'string' && parameters.after.id.startsWith('dt:')) { if (parameters.after && typeof parameters.after.id === 'string' && parameters.after.id.startsWith('dt:')) {
let dateTime = parameters.after.id.substr(3) const dateTime = parameters.after.id.substr(3)
parameters.after.name = window.moment(dateTime).format('L LTS') parameters.after.name = window.moment(dateTime).format('L LTS')
} }
return OCA.Activity.RichObjectStringParser.parseMessage(subject, parameters) return OCA.Activity.RichObjectStringParser.parseMessage(subject, parameters)
} },
} },
} }
</script> </script>

View File

@@ -22,23 +22,20 @@
<template> <template>
<div> <div>
<collection-list v-if="boardId" :id="boardId" :name="boardTitle" <CollectionList v-if="boardId"
type="deck" :id="boardId"
/> :name="boardTitle"
type="deck" />
</div> </div>
</template> </template>
<script> <script>
import { CollectionList } from 'nextcloud-vue-collections' import { CollectionList } from 'nextcloud-vue-collections'
import Vue from 'vue'
import PopoverMenu from '@nextcloud/vue/dist/Components/PopoverMenu'
Vue.component('popover-menu', PopoverMenu)
export default { export default {
name: 'CollaborationView', name: 'CollaborationView',
components: { components: {
CollectionList: CollectionList CollectionList: CollectionList,
}, },
computed: { computed: {
boardId() { boardId() {
@@ -52,7 +49,7 @@ export default {
return '' + this.$root.model.title return '' + this.$root.model.title
} }
return '' return ''
} },
} },
} }
</script> </script>

View File

@@ -26,9 +26,10 @@
<Compact v-model="color" :palette="defaultColors" @input="updateColor" /> <Compact v-model="color" :palette="defaultColors" @input="updateColor" />
<div :style="{'background-color': color.hex}" class="custom-color-button icon-colorpicker" @click.prevent="showFullPicker=!showFullPicker" /> <div :style="{'background-color': color.hex}" class="custom-color-button icon-colorpicker" @click.prevent="showFullPicker=!showFullPicker" />
</div> </div>
<Chrome v-if="showFullPicker" v-model="color" :palette="defaultColors" <Chrome v-if="showFullPicker"
@input="updateColor" v-model="color"
/> :palette="defaultColors"
@input="updateColor" />
</div> </div>
</template> </template>
@@ -41,22 +42,22 @@ export default {
name: 'ColorPicker', name: 'ColorPicker',
components: { components: {
Compact, Compact,
Chrome Chrome,
}, },
directives: { directives: {
ClickOutside ClickOutside,
}, },
props: { props: {
value: { value: {
type: [String, Object], type: [String, Object],
default: null default: null,
} },
}, },
data() { data() {
return { return {
color: { hex: this.value }, color: { hex: this.value },
defaultColors: ['#31CC7C', '#317CCC', '#FF7A66', '#F1DB50', '#7C31CC', '#CC317C', '#3A3B3D', '#CACBCD'], defaultColors: ['#31CC7C', '#317CCC', '#FF7A66', '#F1DB50', '#7C31CC', '#CC317C', '#3A3B3D', '#CACBCD'],
showFullPicker: false showFullPicker: false,
} }
}, },
methods: { methods: {
@@ -65,8 +66,8 @@ export default {
}, },
hidePicker() { hidePicker() {
this.showFullPicker = false this.showFullPicker = false
} },
} },
} }
</script> </script>

View File

@@ -39,25 +39,31 @@
<div id="stack-add"> <div id="stack-add">
<form @submit.prevent="clickAddNewStack()"> <form @submit.prevent="clickAddNewStack()">
<label for="new-stack-input-main" class="hidden-visually">Add a new stack</label> <label for="new-stack-input-main" class="hidden-visually">Add a new stack</label>
<input id="new-stack-input-main" v-model="newStackTitle" type="text" <input id="new-stack-input-main"
v-model="newStackTitle"
type="text"
class="no-close" class="no-close"
placeholder="Add a new stack" required placeholder="Add a new stack"
> required>
<input v-tooltip="t('deck', 'clickAddNewStack')" class="icon-confirm" type="submit" <input v-tooltip="t('deck', 'clickAddNewStack')"
value="" class="icon-confirm"
> type="submit"
value="">
</form> </form>
</div> </div>
<div class="board-action-buttons"> <div class="board-action-buttons">
<button :style="archivStyle" title="Show archived cards" class="icon icon-archive" <button :style="archivStyle"
@click="toggleShowArchived" title="Show archived cards"
/> class="icon icon-archive"
<button :class="[(compactMode ? 'icon-toggle-compact-collapsed' : 'icon-toggle-compact-expanded')]" title="Toggle compact mode" class="icon" @click="toggleShowArchived" />
@click="toggleCompactMode" <button :class="[(compactMode ? 'icon-toggle-compact-collapsed' : 'icon-toggle-compact-expanded')]"
/> title="Toggle compact mode"
<router-link v-tooltip="t('deck', 'Board settings')" :to="{name: 'board.details'}" class="icon-settings-dark" class="icon"
tag="button" @click="toggleCompactMode" />
/> <router-link v-tooltip="t('deck', 'Board settings')"
:to="{name: 'board.details'}"
class="icon-settings-dark"
tag="button" />
</div> </div>
</div> </div>
</div> </div>
@@ -71,19 +77,19 @@ export default {
board: { board: {
type: Object, type: Object,
required: false, required: false,
default: null default: null,
} },
}, },
data() { data() {
return { return {
newStackTitle: '', newStackTitle: '',
stack: '', stack: '',
showArchived: false showArchived: false,
} }
}, },
computed: { computed: {
...mapState({ ...mapState({
compactMode: state => state.compactMode compactMode: state => state.compactMode,
}), }),
archivStyle() { archivStyle() {
@@ -91,7 +97,7 @@ export default {
return 'opacity: 1.0' return 'opacity: 1.0'
} }
return 'opacity: 0.3' return 'opacity: 0.3'
} },
}, },
methods: { methods: {
toggleNav() { toggleNav() {
@@ -112,8 +118,8 @@ export default {
this.$store.dispatch('createStack', this.stack) this.$store.dispatch('createStack', this.stack)
this.newStackTitle = '' this.newStackTitle = ''
this.stack = null this.stack = null
} },
} },
} }
</script> </script>

View File

@@ -26,7 +26,7 @@
<script> <script>
export default { export default {
name: 'List' name: 'List',
} }
</script> </script>

View File

@@ -30,8 +30,8 @@ export default {
methods: { methods: {
closeSidebar() { closeSidebar() {
this.$router.push({ name: 'board' }) this.$router.push({ name: 'board' })
} },
} },
} }
</script> </script>

View File

@@ -24,11 +24,11 @@
<div> <div>
<Controls :board="board" /> <Controls :board="board" />
<div v-if="board" class="board"> <div v-if="board" class="board">
<container lock-axix="y" orientation="horizontal" @drop="onDropStack"> <Container lock-axix="y" orientation="horizontal" @drop="onDropStack">
<draggable v-for="stack in stacksByBoard" :key="stack.id" class="stack"> <Draggable v-for="stack in stacksByBoard" :key="stack.id" class="stack">
<stack :stack="stack" /> <Stack :stack="stack" />
</draggable> </Draggable>
</container> </Container>
</div> </div>
<div v-else class="emptycontent"> <div v-else class="emptycontent">
<div class="icon icon-deck" /> <div class="icon icon-deck" />
@@ -51,30 +51,30 @@ export default {
Controls, Controls,
Container, Container,
Draggable, Draggable,
Stack Stack,
}, },
inject: [ inject: [
'boardApi' 'boardApi',
], ],
props: { props: {
id: { id: {
type: Number, type: Number,
default: null default: null,
} },
}, },
data: function() { data: function() {
return { return {
loading: true loading: true,
} }
}, },
computed: { computed: {
...mapState({ ...mapState({
board: state => state.currentBoard, board: state => state.currentBoard,
showArchived: state => state.showArchived showArchived: state => state.showArchived,
}), }),
stacksByBoard() { stacksByBoard() {
return this.$store.getters.stacksByBoard(this.board.id) return this.$store.getters.stacksByBoard(this.board.id)
} },
/* cardsByStack() { /* cardsByStack() {
return (id) => this.$store.getters.cardsByStack(id) return (id) => this.$store.getters.cardsByStack(id)
} */ } */
@@ -83,7 +83,7 @@ export default {
id: 'fetchData', id: 'fetchData',
showArchived() { showArchived() {
this.fetchData() this.fetchData()
} },
}, },
created() { created() {
this.fetchData() this.fetchData()
@@ -118,17 +118,17 @@ export default {
} }
}, */ }, */
createStack() { createStack() {
let newStack = { const newStack = {
title: 'FooBar', title: 'FooBar',
boardId: this.id, boardId: this.id,
order: this.stacksByBoard().length order: this.stacksByBoard().length,
} }
this.$store.dispatch('createStack', newStack) this.$store.dispatch('createStack', newStack)
} },
/* deleteStack(stack) { /* deleteStack(stack) {
this.$store.dispatch('deleteStack', stack) this.$store.dispatch('deleteStack', stack)
} */ } */
} },
} }
</script> </script>

View File

@@ -21,11 +21,10 @@
--> -->
<template> <template>
<app-sidebar v-if="board != null" <AppSidebar v-if="board != null"
:actions="[]" :actions="[]"
:title="board.title" :title="board.title"
@close="closeSidebar" @close="closeSidebar">
>
<AppSidebarTab :order="0" name="Sharing" icon="icon-shared"> <AppSidebarTab :order="0" name="Sharing" icon="icon-shared">
<SharingTabSidebar :board="board" /> <SharingTabSidebar :board="board" />
</AppSidebarTab> </AppSidebarTab>
@@ -41,7 +40,7 @@
<AppSidebarTab :order="3" name="Timeline" icon="icon-activity"> <AppSidebarTab :order="3" name="Timeline" icon="icon-activity">
<TimelineTabSidebar :board="board" /> <TimelineTabSidebar :board="board" />
</AppSidebarTab> </AppSidebarTab>
</app-sidebar> </AppSidebar>
</template> </template>
<script> <script>
@@ -61,24 +60,24 @@ export default {
SharingTabSidebar, SharingTabSidebar,
TagsTabSidebar, TagsTabSidebar,
DeletedTabSidebar, DeletedTabSidebar,
TimelineTabSidebar TimelineTabSidebar,
}, },
props: { props: {
id: { id: {
type: Number, type: Number,
required: true required: true,
} },
}, },
computed: { computed: {
...mapState({ ...mapState({
board: state => state.currentBoard, board: state => state.currentBoard,
labels: state => state.labels labels: state => state.labels,
}) }),
}, },
methods: { methods: {
closeSidebar() { closeSidebar() {
this.$router.push({ name: 'board' }) this.$router.push({ name: 'board' })
} },
} },
} }
</script> </script>

View File

@@ -8,8 +8,7 @@
<button <button
:title="t('settings', 'Undo')" :title="t('settings', 'Undo')"
class="app-navigation-entry-deleted-button icon-history" class="app-navigation-entry-deleted-button icon-history"
@click="stackUndoDelete(deletedStack)" @click="stackUndoDelete(deletedStack)" />
/>
<!-- <span class="live-relative-timestamp" data-timestamp="{{ deletedStack.deletedAt*1000 }}">{{deletedStack.deletedAt | relativeDateFilter }}</span> <!-- <span class="live-relative-timestamp" data-timestamp="{{ deletedStack.deletedAt*1000 }}">{{deletedStack.deletedAt | relativeDateFilter }}</span>
<a @click="stackUndoDelete(deletedStack)"><span class="icon icon-history"></span></a> --> <a @click="stackUndoDelete(deletedStack)"><span class="icon icon-history"></span></a> -->
@@ -24,8 +23,7 @@
<button <button
:title="t('settings', 'Undo')" :title="t('settings', 'Undo')"
class="app-navigation-entry-deleted-button icon-history" class="app-navigation-entry-deleted-button icon-history"
@click="cardUndoDelete(deletedCard)" @click="cardUndoDelete(deletedCard)" />
/>
</li> </li>
<!-- <li ng-repeat="deletedCard in cardservice.deleted"> <!-- <li ng-repeat="deletedCard in cardservice.deleted">
@@ -50,21 +48,21 @@ export default {
props: { props: {
board: { board: {
type: Object, type: Object,
default: undefined default: undefined,
} },
}, },
data() { data() {
return { return {
isLoading: false, isLoading: false,
copiedDeletedStack: null, copiedDeletedStack: null,
copiedDeletedCard: null copiedDeletedCard: null,
} }
}, },
computed: { computed: {
...mapState({ ...mapState({
deletedStacks: state => state.stack.deletedStacks, deletedStacks: state => state.stack.deletedStacks,
deletedCards: state => state.stack.deletedCards deletedCards: state => state.stack.deletedCards,
}) }),
}, },
created() { created() {
@@ -88,8 +86,8 @@ export default {
this.copiedDeletedCard.deletedAt = 0 this.copiedDeletedCard.deletedAt = 0
this.$store.dispatch('cardUndoDelete', this.copiedDeletedCard) this.$store.dispatch('cardUndoDelete', this.copiedDeletedCard)
this.getData() this.getData()
} },
} },
} }
</script> </script>

View File

@@ -1,27 +1,25 @@
<template> <template>
<div> <div>
<multiselect <Multiselect
v-model="addAcl" v-model="addAcl"
:options="formatedSharees" :options="formatedSharees"
:user-select="true" :user-select="true"
label="displayName" label="displayName"
track-by="user" track-by="user"
@input="clickAddAcl" @input="clickAddAcl"
@search-change="asyncFind" @search-change="asyncFind" />
/>
<ul <ul
id="shareWithList" id="shareWithList"
class="shareWithList" class="shareWithList">
>
<li> <li>
<avatar :user="board.owner.uid" /> <Avatar :user="board.owner.uid" />
<span class="has-tooltip username"> <span class="has-tooltip username">
{{ board.owner.displayname }} {{ board.owner.displayname }}
</span> </span>
</li> </li>
<li v-for="acl in board.acl" :key="acl.participant.uid"> <li v-for="acl in board.acl" :key="acl.participant.uid">
<avatar v-if="acl.type===0" :user="acl.participant.uid" /> <Avatar v-if="acl.type===0" :user="acl.participant.uid" />
<div v-if="acl.type===1" class="avatardiv icon icon-group" /> <div v-if="acl.type===1" class="avatardiv icon icon-group" />
<div v-if="acl.type===7" class="avatardiv icon icon-circles" /> <div v-if="acl.type===7" class="avatardiv icon icon-circles" />
<span class="has-tooltip username"> <span class="has-tooltip username">
@@ -47,9 +45,10 @@
</li> </li>
</ul> </ul>
<collection-list v-if="board.id" :id="`${board.id}`" :name="board.title" <CollectionList v-if="board.id"
type="deck" :id="`${board.id}`"
/> :name="board.title"
type="deck" />
</div> </div>
</template> </template>
@@ -70,32 +69,32 @@ export default {
ActionButton, ActionButton,
ActionCheckbox, ActionCheckbox,
Multiselect, Multiselect,
CollectionList CollectionList,
}, },
props: { props: {
board: { board: {
type: Object, type: Object,
default: undefined default: undefined,
} },
}, },
data() { data() {
return { return {
isLoading: false, isLoading: false,
addAcl: null, addAcl: null,
addAclForAPI: null addAclForAPI: null,
} }
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
sharees: 'sharees' sharees: 'sharees',
}), }),
formatedSharees() { formatedSharees() {
return this.unallocatedSharees.map(item => { return this.unallocatedSharees.map(item => {
let sharee = { const sharee = {
user: item.label, user: item.label,
displayName: item.label, displayName: item.label,
icon: 'icon-user' icon: 'icon-user',
} }
if (item.value.shareType === 1) { if (item.value.shareType === 1) {
@@ -113,7 +112,7 @@ export default {
}, },
unallocatedSharees() { unallocatedSharees() {
return this.sharees.filter((sharee) => { return this.sharees.filter((sharee) => {
let foundIndex = this.board.acl.findIndex((acl) => { const foundIndex = this.board.acl.findIndex((acl) => {
return acl.participant.uid === sharee.value.shareWith return acl.participant.uid === sharee.value.shareWith
}) })
if (foundIndex === -1) { if (foundIndex === -1) {
@@ -121,7 +120,7 @@ export default {
} }
return false return false
}) })
} },
}, },
methods: { methods: {
asyncFind(query) { asyncFind(query) {
@@ -136,7 +135,7 @@ export default {
participant: this.addAcl.value.shareWith, participant: this.addAcl.value.shareWith,
permissionEdit: false, permissionEdit: false,
permissionShare: false, permissionShare: false,
permissionManage: false permissionManage: false,
} }
this.$store.dispatch('addAclToCurrentBoard', this.addAclForAPI) this.$store.dispatch('addAclToCurrentBoard', this.addAclForAPI)
}, },
@@ -157,8 +156,8 @@ export default {
}, },
clickDeleteAcl(acl) { clickDeleteAcl(acl) {
this.$store.dispatch('deleteAclFromCurrentBoard', acl) this.$store.dispatch('deleteAclFromCurrentBoard', acl)
} },
} },
} }
</script> </script>
<style scoped> <style scoped>

View File

@@ -30,9 +30,10 @@
</h3> </h3>
<form v-else @submit.prevent="finishedEdit(stack)"> <form v-else @submit.prevent="finishedEdit(stack)">
<input v-model="copiedStack.title" type="text" autofocus> <input v-model="copiedStack.title" type="text" autofocus>
<input v-tooltip="t('deck', 'Add a new stack')" class="icon-confirm" type="submit" <input v-tooltip="t('deck', 'Add a new stack')"
value="" class="icon-confirm"
> type="submit"
value="">
</form> </form>
</transition> </transition>
<Actions> <Actions>
@@ -42,23 +43,24 @@
</Actions> </Actions>
</div> </div>
<container :get-child-payload="payloadForCard(stack.id)" group-name="stack" @drop="($event) => onDropCard(stack.id, $event)"> <Container :get-child-payload="payloadForCard(stack.id)" group-name="stack" @drop="($event) => onDropCard(stack.id, $event)">
<draggable v-for="card in cardsByStack(stack.id)" :key="card.id"> <Draggable v-for="card in cardsByStack(stack.id)" :key="card.id">
<card-item v-if="card" :id="card.id" /> <CardItem v-if="card" :id="card.id" />
</draggable> </Draggable>
</container> </Container>
<form class="stack--card-add" @submit.prevent="clickAddCard()"> <form class="stack--card-add" @submit.prevent="clickAddCard()">
<label for="new-stack-input-main" class="hidden-visually">Add a new card</label> <label for="new-stack-input-main" class="hidden-visually">Add a new card</label>
<input id="new-stack-input-main" v-model="newCardTitle" type="text" <input id="new-stack-input-main"
v-model="newCardTitle"
type="text"
class="no-close" class="no-close"
placeholder="Add a new card" required placeholder="Add a new card"
> required>
<input class="icon-confirm" <input class="icon-confirm"
type="submit" type="submit"
value="" value="">
>
</form> </form>
</div> </div>
</template> </template>
@@ -77,26 +79,26 @@ export default {
ActionButton, ActionButton,
CardItem, CardItem,
Container, Container,
Draggable Draggable,
}, },
props: { props: {
stack: { stack: {
type: Object, type: Object,
default: undefined default: undefined,
} },
}, },
data() { data() {
return { return {
editing: false, editing: false,
copiedStack: '', copiedStack: '',
newCardTitle: '' newCardTitle: '',
} }
}, },
computed: { computed: {
cardsByStack() { cardsByStack() {
return (id) => this.$store.getters.cardsByStack(id) return (id) => this.$store.getters.cardsByStack(id)
} },
}, },
methods: { methods: {
@@ -138,15 +140,15 @@ export default {
this.editing = false this.editing = false
}, },
clickAddCard() { clickAddCard() {
let newCard = { const newCard = {
title: this.newCardTitle, title: this.newCardTitle,
stackId: this.stack.id, stackId: this.stack.id,
boardId: this.stack.boardId boardId: this.stack.boardId,
} }
this.$store.dispatch('addCard', newCard) this.$store.dispatch('addCard', newCard)
this.newCardTitle = '' this.newCardTitle = ''
} },
} },
} }
</script> </script>

View File

@@ -5,12 +5,15 @@
<template v-if="editingLabelId === label.id"> <template v-if="editingLabelId === label.id">
<form class="label-form" @submit.prevent="updateLabel(label)"> <form class="label-form" @submit.prevent="updateLabel(label)">
<input v-model="editingLabel.title" type="text"> <input v-model="editingLabel.title" type="text">
<input v-tooltip="{content: missingDataLabel, show: !editLabelObjValidated, trigger: 'manual' }" :disabled="!editLabelObjValidated" type="submit" <input v-tooltip="{content: missingDataLabel, show: !editLabelObjValidated, trigger: 'manual' }"
value="" class="icon-confirm" :disabled="!editLabelObjValidated"
> type="submit"
<input v-tooltip="t('deck', 'Cancel')" value="" value=""
class="icon-close" @click="editingLabelId = null" class="icon-confirm">
> <input v-tooltip="t('deck', 'Cancel')"
value=""
class="icon-close"
@click="editingLabelId = null">
</form> </form>
<ColorPicker :value="'#' + editingLabel.color" @input="updateColor" /> <ColorPicker :value="'#' + editingLabel.color" @input="updateColor" />
</template> </template>
@@ -27,13 +30,15 @@
<template> <template>
<form class="label-form" @submit.prevent="clickAddLabel"> <form class="label-form" @submit.prevent="clickAddLabel">
<input v-model="addLabelObj.title" type="text"> <input v-model="addLabelObj.title" type="text">
<input v-tooltip="{content: missingDataLabel, show: !addLabelObjValidated, trigger: 'manual' }" :disabled="!addLabelObjValidated" <input v-tooltip="{content: missingDataLabel, show: !addLabelObjValidated, trigger: 'manual' }"
:disabled="!addLabelObjValidated"
type="submit" type="submit"
value="" class="icon-confirm" value=""
> class="icon-confirm">
<input v-tooltip="t('deck', 'Cancel')" value="" <input v-tooltip="t('deck', 'Cancel')"
class="icon-close" @click="addLabel=false" value=""
> class="icon-close"
@click="addLabel=false">
</form> </form>
<ColorPicker :value="'#' + addLabelObj.color" @input="updateColor" /> <ColorPicker :value="'#' + addLabelObj.color" @input="updateColor" />
</template> </template>
@@ -54,7 +59,7 @@ import ColorPicker from '../ColorPicker'
export default { export default {
name: 'TagsTabSidebar', name: 'TagsTabSidebar',
components: { components: {
ColorPicker ColorPicker,
}, },
mixins: [Color], mixins: [Color],
data() { data() {
@@ -64,12 +69,12 @@ export default {
addLabelObj: null, addLabelObj: null,
addLabel: false, addLabel: false,
missingDataLabel: t('deck', 'title and color value must be provided'), missingDataLabel: t('deck', 'title and color value must be provided'),
defaultColors: ['#31CC7C', '#317CCC', '#FF7A66', '#F1DB50', '#7C31CC', '#CC317C', '#3A3B3D', '#CACBCD'] defaultColors: ['#31CC7C', '#317CCC', '#FF7A66', '#F1DB50', '#7C31CC', '#CC317C', '#3A3B3D', '#CACBCD'],
} }
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
labels: 'currentBoardLabels' labels: 'currentBoardLabels',
}), }),
addLabelObjValidated() { addLabelObjValidated() {
if (this.addLabelObj.title === '') { if (this.addLabelObj.title === '') {
@@ -92,7 +97,7 @@ export default {
} }
return true return true
} },
}, },
methods: { methods: {
@@ -122,8 +127,8 @@ export default {
this.$store.dispatch('addLabelToCurrentBoard', this.addLabelObj) this.$store.dispatch('addLabelToCurrentBoard', this.addLabelObj)
this.addLabel = false this.addLabel = false
this.addLabelObj = null this.addLabelObj = null
} },
} },
} }
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

View File

@@ -2,9 +2,10 @@
<div> <div>
<div v-if="isLoading" class="icon icon-loading" /> <div v-if="isLoading" class="icon icon-loading" />
<ActivityEntry v-for="entry in boardActivity" v-else :key="entry.activity_id" <ActivityEntry v-for="entry in boardActivity"
:activity="entry" v-else
/> :key="entry.activity_id"
:activity="entry" />
<button v-if="activityLoadMore" @click="loadMore"> <button v-if="activityLoadMore" @click="loadMore">
Load More Load More
</button> </button>
@@ -18,13 +19,13 @@ import ActivityEntry from '../ActivityEntry'
export default { export default {
name: 'TimelineTabSidebar', name: 'TimelineTabSidebar',
components: { components: {
ActivityEntry ActivityEntry,
}, },
props: { props: {
board: { board: {
type: Object, type: Object,
default: undefined default: undefined,
} },
}, },
data() { data() {
return { return {
@@ -32,15 +33,15 @@ export default {
params: { params: {
type: 'deck', type: 'deck',
since: 0, since: 0,
object_id: this.board.id object_id: this.board.id,
} },
} }
}, },
computed: { computed: {
...mapState({ ...mapState({
boardActivity: 'activity', boardActivity: 'activity',
activityLoadMore: 'activityLoadMore' activityLoadMore: 'activityLoadMore',
}) }),
}, },
created() { created() {
this.loadBoardActivity() this.loadBoardActivity()
@@ -53,12 +54,12 @@ export default {
}) })
}, },
loadMore() { loadMore() {
let array = Object.values(this.boardActivity) const array = Object.values(this.boardActivity)
let aId = (array[array.length - 1].activity_id) const aId = (array[array.length - 1].activity_id)
this.params.since = aId this.params.since = aId
this.loadBoardActivity() this.loadBoardActivity()
} },
} },
} }
</script> </script>

View File

@@ -23,8 +23,9 @@
<template> <template>
<router-link :id="`board-${board.id}`" <router-link :id="`board-${board.id}`"
:title="board.title" :title="board.title"
:to="routeTo" class="board-list-row" tag="div" :to="routeTo"
> class="board-list-row"
tag="div">
<div class="board-list-bullet-cell"> <div class="board-list-bullet-cell">
<div :style="{ 'background-color': `#${board.color}` }" class="board-list-bullet" /> <div :style="{ 'background-color': `#${board.color}` }" class="board-list-bullet" />
</div> </div>
@@ -32,10 +33,11 @@
{{ board.title }} {{ board.title }}
</div> </div>
<div class="board-list-avatars-cell"> <div class="board-list-avatars-cell">
<avatar :user="board.owner.uid" class="board-list-avatar" /> <Avatar :user="board.owner.uid" class="board-list-avatar" />
<avatar v-for="user in limitedAcl" :key="user.id" :user="user.participant.uid" <Avatar v-for="user in limitedAcl"
class="board-list-avatar" :key="user.id"
/> :user="user.participant.uid"
class="board-list-avatar" />
<div v-if="board.acl.length > 5" v-tooltip="otherAcl" class="avatardiv popovermenu-wrapper board-list-avatar icon-more" /> <div v-if="board.acl.length > 5" v-tooltip="otherAcl" class="avatardiv popovermenu-wrapper board-list-avatar icon-more" />
</div> </div>
<div class="board-list-actions-cell" /> <div class="board-list-actions-cell" />
@@ -48,19 +50,19 @@ import { Avatar } from '@nextcloud/vue/dist/Components/Avatar'
export default { export default {
name: 'BoardItem', name: 'BoardItem',
components: { components: {
Avatar Avatar,
}, },
props: { props: {
board: { board: {
type: Object, type: Object,
default: () => { return {} } default: () => { return {} },
} },
}, },
computed: { computed: {
routeTo: function() { routeTo: function() {
return { return {
name: 'board', name: 'board',
params: { id: this.board.id } params: { id: this.board.id },
} }
}, },
limitedAcl() { limitedAcl() {
@@ -68,8 +70,8 @@ export default {
}, },
otherAcl() { otherAcl() {
return [...this.board.acl].splice(6).map((item) => item.participant.displayname || item.participant).join(', ') return [...this.board.acl].splice(6).map((item) => item.participant.displayname || item.participant).join(', ')
} },
} },
} }
</script> </script>

View File

@@ -48,27 +48,27 @@ import Controls from '../Controls'
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
export default { export default {
name: 'Main', name: 'Boards',
components: { components: {
BoardItem, BoardItem,
Controls Controls,
}, },
props: { props: {
navFilter: { navFilter: {
type: String, type: String,
default: '' default: '',
} },
}, },
computed: { computed: {
...mapGetters([ ...mapGetters([
'filteredBoards' 'filteredBoards',
]) ]),
}, },
watch: { watch: {
navFilter: function(value) { navFilter: function(value) {
this.$store.commit('setBoardFilter', value) this.$store.commit('setBoardFilter', value)
} },
} },
} }
</script> </script>

View File

@@ -21,12 +21,11 @@
--> -->
<template> <template>
<app-sidebar v-if="currentCard !== null && copiedCard !== null" <AppSidebar v-if="currentCard !== null && copiedCard !== null"
:actions="toolbarActions" :actions="toolbarActions"
:title="currentCard.title" :title="currentCard.title"
:subtitle="subtitle" :subtitle="subtitle"
@close="closeSidebar" @close="closeSidebar">
>
<template #action /> <template #action />
<AppSidebarTab :order="0" name="Details" icon="icon-home"> <AppSidebarTab :order="0" name="Details" icon="icon-home">
<div class="section-wrapper"> <div class="section-wrapper">
@@ -34,10 +33,14 @@
<span class="hidden-visually">{{ t('deck', 'Tags') }}</span> <span class="hidden-visually">{{ t('deck', 'Tags') }}</span>
</div> </div>
<div class="section-details"> <div class="section-details">
<multiselect v-model="allLabels" :multiple="true" :options="currentBoard.labels" <Multiselect v-model="allLabels"
:taggable="true" label="title" :multiple="true"
track-by="id" @select="addLabelToCard" @remove="removeLabelFromCard" :options="currentBoard.labels"
> :taggable="true"
label="title"
track-by="id"
@select="addLabelToCard"
@remove="removeLabelFromCard">
<template #option="scope"> <template #option="scope">
<div :style="{ backgroundColor: '#' + scope.option.color, color: textColor(scope.option.color)}" class="tag"> <div :style="{ backgroundColor: '#' + scope.option.color, color: textColor(scope.option.color)}" class="tag">
{{ scope.option.title }} {{ scope.option.title }}
@@ -48,7 +51,7 @@
{{ scope.option.title }} {{ scope.option.title }}
</div> </div>
</template> </template>
</multiselect> </Multiselect>
</div> </div>
</div> </div>
@@ -57,16 +60,18 @@
<span class="hidden-visually">{{ t('deck', 'Assign to users') }}</span> <span class="hidden-visually">{{ t('deck', 'Assign to users') }}</span>
</div> </div>
<div class="section-details"> <div class="section-details">
<multiselect v-model="assignedUsers" :multiple="true" :options="assignableUsers" <Multiselect v-model="assignedUsers"
:multiple="true"
:options="assignableUsers"
label="displayname" label="displayname"
track-by="primaryKey" track-by="primaryKey"
@select="assignUserToCard" @remove="removeUserFromCard" @select="assignUserToCard"
> @remove="removeUserFromCard">
<template #option="scope"> <template #option="scope">
<avatar :user="scope.option.primaryKey" /> <Avatar :user="scope.option.primaryKey" />
<span class="avatarLabel">{{ scope.option.displayname }} </span> <span class="avatarLabel">{{ scope.option.displayname }} </span>
</template> </template>
</multiselect> </Multiselect>
</div> </div>
</div> </div>
@@ -75,9 +80,12 @@
<span class="hidden-visually">{{ t('deck', 'Due date') }}</span> <span class="hidden-visually">{{ t('deck', 'Due date') }}</span>
</div> </div>
<div class="section-details"> <div class="section-details">
<DatetimePicker v-model="copiedCard.duedate" type="datetime" lang="en" <DatetimePicker v-model="copiedCard.duedate"
format="YYYY-MM-DD HH:mm" confirm @change="setDue()" type="datetime"
/> lang="en"
format="YYYY-MM-DD HH:mm"
confirm
@change="setDue()" />
<Actions> <Actions>
<ActionButton v-if="copiedCard.duedate" icon="icon-delete" @click="removeDue()"> <ActionButton v-if="copiedCard.duedate" icon="icon-delete" @click="removeDue()">
{{ t('deck', 'Remove due date') }} {{ t('deck', 'Remove due date') }}
@@ -87,9 +95,10 @@
</div> </div>
<div class="section-wrapper"> <div class="section-wrapper">
<collection-list v-if="currentCard.id" :id="`${currentCard.id}`" :name="currentCard.title" <CollectionList v-if="currentCard.id"
type="deck-card" :id="`${currentCard.id}`"
/> :name="currentCard.title"
type="deck-card" />
</div> </div>
<h5>Description</h5> <h5>Description</h5>
@@ -103,14 +112,15 @@
</AppSidebarTab> </AppSidebarTab>
<AppSidebarTab :order="2" name="Timeline" icon="icon-activity"> <AppSidebarTab :order="2" name="Timeline" icon="icon-activity">
<div v-if="isLoading" class="icon icon-loading" /> <div v-if="isLoading" class="icon icon-loading" />
<ActivityEntry v-for="entry in cardActivity" v-else :key="entry.activity_id" <ActivityEntry v-for="entry in cardActivity"
:activity="entry" v-else
/> :key="entry.activity_id"
:activity="entry" />
<button v-if="activityLoadMore" @click="loadMore"> <button v-if="activityLoadMore" @click="loadMore">
Load More Load More
</button> </button>
</AppSidebarTab> </AppSidebarTab>
</app-sidebar> </AppSidebar>
</template> </template>
<script> <script>
@@ -139,16 +149,16 @@ export default {
Actions, Actions,
ActionButton, ActionButton,
Avatar, Avatar,
CollectionList CollectionList,
}, },
mixins: [ mixins: [
Color Color,
], ],
props: { props: {
id: { id: {
type: Number, type: Number,
required: true required: true,
} },
}, },
data() { data() {
return { return {
@@ -163,7 +173,7 @@ export default {
spellChecker: false, spellChecker: false,
autofocus: true, autofocus: true,
autosave: { enabled: true, uniqueId: 'unique' }, autosave: { enabled: true, uniqueId: 'unique' },
toolbar: false toolbar: false,
}, },
lastModifiedRelative: null, lastModifiedRelative: null,
lastCreatedRemative: null, lastCreatedRemative: null,
@@ -171,8 +181,8 @@ export default {
type: 'filter', type: 'filter',
since: 0, since: 0,
object_type: 'deck_card', object_type: 'deck_card',
object_id: this.id object_id: this.id,
} },
} }
}, },
computed: { computed: {
@@ -180,7 +190,7 @@ export default {
currentBoard: state => state.currentBoard, currentBoard: state => state.currentBoard,
assignableUsers: state => state.assignableUsers, assignableUsers: state => state.assignableUsers,
cardActivity: 'activity', cardActivity: 'activity',
activityLoadMore: 'activityLoadMore' activityLoadMore: 'activityLoadMore',
}), }),
currentCard() { currentCard() {
return this.$store.getters.cardById(this.id) return this.$store.getters.cardById(this.id)
@@ -195,17 +205,17 @@ export default {
}, },
icon: 'icon-archive-dark', icon: 'icon-archive-dark',
text: t('deck', 'Assign to me') text: t('deck', 'Assign to me'),
}, },
{ {
action: () => { action: () => {
}, },
icon: 'icon-archive', icon: 'icon-archive',
text: t('deck', (this.showArchived ? 'Unarchive card' : 'Archive card')) text: t('deck', (this.showArchived ? 'Unarchive card' : 'Archive card')),
} },
] ]
} },
}, },
watch: { watch: {
'currentCard': { 'currentCard': {
@@ -223,12 +233,12 @@ export default {
this.params.object_id = this.id this.params.object_id = this.id
this.loadCardActivity() this.loadCardActivity()
} },
}, },
'copiedCard.description': function() { 'copiedCard.description': function() {
this.saveDesc() this.saveDesc()
} },
}, },
created() { created() {
setInterval(this.updateRelativeTimestamps, 10000) setInterval(this.updateRelativeTimestamps, 10000)
@@ -269,25 +279,25 @@ export default {
addLabelToCard(newLabel) { addLabelToCard(newLabel) {
this.copiedCard.labels.push(newLabel) this.copiedCard.labels.push(newLabel)
let data = { const data = {
card: this.copiedCard, card: this.copiedCard,
labelId: newLabel.id labelId: newLabel.id,
} }
this.$store.dispatch('addLabel', data) this.$store.dispatch('addLabel', data)
}, },
removeLabelFromCard(removedLabel) { removeLabelFromCard(removedLabel) {
let removeIndex = this.copiedCard.labels.findIndex((label) => { const removeIndex = this.copiedCard.labels.findIndex((label) => {
return label.id === removedLabel.id return label.id === removedLabel.id
}) })
if (removeIndex !== -1) { if (removeIndex !== -1) {
this.copiedCard.labels.splice(removeIndex, 1) this.copiedCard.labels.splice(removeIndex, 1)
} }
let data = { const data = {
card: this.copiedCard, card: this.copiedCard,
labelId: removedLabel.id labelId: removedLabel.id,
} }
this.$store.dispatch('removeLabel', data) this.$store.dispatch('removeLabel', data)
}, },
@@ -298,17 +308,17 @@ export default {
}) })
}, },
loadMore() { loadMore() {
let array = Object.values(this.cardActivity) const array = Object.values(this.cardActivity)
let aId = (array[array.length - 1].activity_id) const aId = (array[array.length - 1].activity_id)
this.params.since = aId this.params.since = aId
this.loadCardActivity() this.loadCardActivity()
}, },
clickAddNewAttachmment() { clickAddNewAttachmment() {
} },
} },
} }
</script> </script>

View File

@@ -24,13 +24,15 @@
<div class="avatars"> <div class="avatars">
<div class="avatar-list" @click.stop="popoverVisible=!popoverVisible"> <div class="avatar-list" @click.stop="popoverVisible=!popoverVisible">
<div v-if="popover.length > 0" class="avatardiv icon-more" /> <div v-if="popover.length > 0" class="avatardiv icon-more" />
<avatar v-for="user in firstUsers" :key="user.id" <Avatar v-for="user in firstUsers"
:url="avatarUrl(user)" :disable-tooltip="true" :size="32" :key="user.id"
/> :url="avatarUrl(user)"
:disable-tooltip="true"
:size="32" />
</div> </div>
<div v-show="popoverVisible" class="popovermenu menu-right"> <div v-show="popoverVisible" class="popovermenu menu-right">
<popover-menu :menu="popover" /> <PopoverMenu :menu="popover" />
<slot /> <slot />
</div> </div>
</div> </div>
@@ -44,20 +46,20 @@ export default {
name: 'AvatarList', name: 'AvatarList',
components: { components: {
Avatar, Avatar,
PopoverMenu PopoverMenu,
}, },
directives: { directives: {
tooltip: Tooltip tooltip: Tooltip,
}, },
props: { props: {
users: { users: {
type: Array, type: Array,
default: () => { return {} } default: () => { return {} },
} },
}, },
data() { data() {
return { return {
popoverVisible: false popoverVisible: false,
} }
}, },
computed: { computed: {
@@ -71,7 +73,7 @@ export default {
const avatarUrl = OC.generateUrl('/avatar/{user}/{size}', const avatarUrl = OC.generateUrl('/avatar/{user}/{size}',
{ {
user: user, user: user,
size: size size: size,
}) })
return window.location.protocol + '//' + window.location.host + avatarUrl return window.location.protocol + '//' + window.location.host + avatarUrl
} }
@@ -82,13 +84,13 @@ export default {
return { return {
href: '#', href: '#',
icon: this.avatarUrl(session), icon: this.avatarUrl(session),
text: session.participant.displayname text: session.participant.displayname,
} }
}) }),
] ]
} },
} },
} }
</script> </script>

View File

@@ -34,7 +34,7 @@
<div v-if="card.attachments" class="card-files icon icon-files-dark" /> <div v-if="card.attachments" class="card-files icon icon-files-dark" />
<avatar-list :users="card.assignedUsers" /> <AvatarList :users="card.assignedUsers" />
</div> </div>
</template> </template>
<script> <script>
@@ -46,13 +46,13 @@ export default {
props: { props: {
id: { id: {
type: Number, type: Number,
default: null default: null,
} },
}, },
data() { data() {
return { return {
dueTime: null, dueTime: null,
dueIcon: null dueIcon: null,
} }
}, },
computed: { computed: {
@@ -67,7 +67,7 @@ export default {
}, },
card() { card() {
return this.$store.getters.cardById(this.id) return this.$store.getters.cardById(this.id)
} },
}, },
created() { created() {
this.updateDueTime() this.updateDueTime()
@@ -88,7 +88,7 @@ export default {
this.dueTime = OC.Util.relativeModifiedDate(this.card.duedate) this.dueTime = OC.Util.relativeModifiedDate(this.card.duedate)
let timeInHours = Math.round((Date.parse(this.card.duedate) - Date.now()) / 1000 / 60 / 60 / 24) const timeInHours = Math.round((Date.parse(this.card.duedate) - Date.now()) / 1000 / 60 / 60 / 24)
if (timeInHours >= 1) { if (timeInHours >= 1) {
this.dueIcon = 'icon-calendar-dark due icon next' this.dueIcon = 'icon-calendar-dark due icon next'
} }
@@ -98,8 +98,8 @@ export default {
if (timeInHours < 0) { if (timeInHours < 0) {
this.dueIcon = 'icon-calendar due icon overdue' this.dueIcon = 'icon-calendar due icon overdue'
} }
} },
} },
} }
</script> </script>

View File

@@ -25,9 +25,10 @@
--> -->
<template> <template>
<div :class="{'compact': compactMode, 'current-card': currentCard}" tag="div" class="card" <div :class="{'compact': compactMode, 'current-card': currentCard}"
@click.self="openCard" tag="div"
> class="card"
@click.self="openCard">
<div class="card-upper"> <div class="card-upper">
<h3 v-if="showArchived"> <h3 v-if="showArchived">
{{ card.title }} {{ card.title }}
@@ -38,9 +39,10 @@
<h3 v-else> <h3 v-else>
&nbsp; &nbsp;
</h3> </h3>
<form v-if="editing" v-click-outside="cancelEdit" @keyup.esc="cancelEdit" <form v-if="editing"
@submit.prevent="finishedEdit(card)" v-click-outside="cancelEdit"
> @keyup.esc="cancelEdit"
@submit.prevent="finishedEdit(card)">
<input v-model="copiedCard.title" type="text" autofocus> <input v-model="copiedCard.title" type="text" autofocus>
<input type="button" class="icon-confirm" @click="finishedEdit(card)"> <input type="button" class="icon-confirm" @click="finishedEdit(card)">
</form> </form>
@@ -63,15 +65,17 @@
</ActionButton> </ActionButton>
</Actions> </Actions>
<modal v-if="modalShow" title="Move card to another board" @close="modalShow=false"> <Modal v-if="modalShow" title="Move card to another board" @close="modalShow=false">
<div class="modal__content"> <div class="modal__content">
<Multiselect v-model="selectedBoard" :placeholder="t('deck', 'Select a board')" :options="boards" <Multiselect v-model="selectedBoard"
:placeholder="t('deck', 'Select a board')"
:options="boards"
label="title" label="title"
@select="loadStacksFromBoard" @select="loadStacksFromBoard" />
/> <Multiselect v-model="selectedStack"
<Multiselect v-model="selectedStack" :placeholder="t('deck', 'Select a stack')" :options="stacksFromBoard" :placeholder="t('deck', 'Select a stack')"
label="title" :options="stacksFromBoard"
/> label="title" />
<button :disabled="!isBoardAndStackChoosen" class="primary" @click="moveCard"> <button :disabled="!isBoardAndStackChoosen" class="primary" @click="moveCard">
{{ t('deck', 'Move card') }} {{ t('deck', 'Move card') }}
@@ -80,7 +84,7 @@
{{ t('deck', 'Cancel') }} {{ t('deck', 'Cancel') }}
</button> </button>
</div> </div>
</modal> </Modal>
</div> </div>
<ul class="labels" @click="openCard"> <ul class="labels" @click="openCard">
<li v-for="label in card.labels" :key="label.id" :style="labelStyle(label)"> <li v-for="label in card.labels" :key="label.id" :style="labelStyle(label)">
@@ -88,7 +92,7 @@
</li> </li>
</ul> </ul>
<div v-show="!compactMode" class="card-controls compact-item" @click="openCard"> <div v-show="!compactMode" class="card-controls compact-item" @click="openCard">
<card-badges :id="id" /> <CardBadges :id="id" />
</div> </div>
</div> </div>
</template> </template>
@@ -109,14 +113,14 @@ export default {
name: 'CardItem', name: 'CardItem',
components: { Modal, CardBadges, Actions, ActionButton, Multiselect }, components: { Modal, CardBadges, Actions, ActionButton, Multiselect },
directives: { directives: {
ClickOutside ClickOutside,
}, },
mixins: [Color], mixins: [Color],
props: { props: {
id: { id: {
type: Number, type: Number,
default: null default: null,
} },
}, },
data() { data() {
return { return {
@@ -126,14 +130,14 @@ export default {
modalShow: false, modalShow: false,
selectedBoard: '', selectedBoard: '',
selectedStack: '', selectedStack: '',
stacksFromBoard: [] stacksFromBoard: [],
} }
}, },
computed: { computed: {
...mapState({ ...mapState({
compactMode: state => state.compactMode, compactMode: state => state.compactMode,
showArchived: state => state.showArchived, showArchived: state => state.showArchived,
currentBoard: state => state.currentBoard currentBoard: state => state.currentBoard,
}), }),
card() { card() {
return this.$store.getters.cardById(this.id) return this.$store.getters.cardById(this.id)
@@ -150,7 +154,7 @@ export default {
return (label) => { return (label) => {
return { return {
backgroundColor: '#' + label.color, backgroundColor: '#' + label.color,
color: this.textColor(label.color) color: this.textColor(label.color),
} }
} }
}, },
@@ -162,7 +166,7 @@ export default {
return false return false
} }
return true return true
} },
}, },
methods: { methods: {
openCard() { openCard() {
@@ -202,8 +206,8 @@ export default {
}, },
async loadStacksFromBoard(board) { async loadStacksFromBoard(board) {
try { try {
let url = OC.generateUrl('/apps/deck/stacks/' + board.id) const url = OC.generateUrl('/apps/deck/stacks/' + board.id)
let response = await axios.get(url) const response = await axios.get(url)
this.stacksFromBoard = response.data this.stacksFromBoard = response.data
} catch (err) { } catch (err) {
return err return err
@@ -214,8 +218,8 @@ export default {
this.copiedCard.stackId = this.selectedStack.id this.copiedCard.stackId = this.selectedStack.id
this.$store.dispatch('moveCard', this.copiedCard) this.$store.dispatch('moveCard', this.copiedCard)
this.modalShow = false this.modalShow = false
} },
} },
} }
</script> </script>

View File

@@ -23,41 +23,42 @@
<template> <template>
<div id="app-navigation" :class="{'icon-loading': loading}"> <div id="app-navigation" :class="{'icon-loading': loading}">
<ul id="deck-navigation"> <ul id="deck-navigation">
<app-navigation-board-category <AppNavigationBoardCategory
id="deck-navigation-all" id="deck-navigation-all"
:text="t('deck', 'All boards')" :text="t('deck', 'All boards')"
:boards="noneArchivedBoards" :boards="noneArchivedBoards"
:open-on-add-boards="true" :open-on-add-boards="true"
icon="icon-deck" icon="icon-deck" />
/> <AppNavigationBoardCategory
<app-navigation-board-category
id="deck-navigation-archived" id="deck-navigation-archived"
:text="t('deck', 'Archived boards')" :text="t('deck', 'Archived boards')"
:boards="archivedBoards" :boards="archivedBoards"
icon="icon-archive" icon="icon-archive" />
/> <AppNavigationBoardCategory
<app-navigation-board-category
id="deck-navigation-shared" id="deck-navigation-shared"
:text="t('deck', 'Shared boards')" :text="t('deck', 'Shared boards')"
:boards="sharedBoards" :boards="sharedBoards"
icon="icon-shared" icon="icon-shared" />
/> <AppNavigationAddBoard />
<app-navigation-add-board />
</ul> </ul>
<div v-if="isAdmin" id="app-settings" <div v-if="isAdmin"
v-click-outside="closeMenu" :class="{open: opened}" id="app-settings"
> v-click-outside="closeMenu"
:class="{open: opened}">
<div id="app-settings-header"> <div id="app-settings-header">
<button class="settings-button" @click="toggleMenu"> <button class="settings-button" @click="toggleMenu">
{{ t('deck', 'Settings') }} {{ t('deck', 'Settings') }}
</button> </button>
</div> </div>
<div id="app-settings-content"> <div id="app-settings-content">
<Multiselect v-model="groupLimit" :class="{'icon-loading-small': groupLimitDisabled}" :options="groups" <Multiselect v-model="groupLimit"
:class="{'icon-loading-small': groupLimitDisabled}"
:options="groups"
:multiple="true" :multiple="true"
:disabled="groupLimitDisabled" label="displayname" track-by="id" :disabled="groupLimitDisabled"
@input="updateConfig" label="displayname"
/> track-by="id"
@input="updateConfig" />
<p>{{ t('deck', 'Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them.') }}</p> <p>{{ t('deck', 'Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them.') }}</p>
</div> </div>
</div> </div>
@@ -78,36 +79,36 @@ export default {
components: { components: {
AppNavigationAddBoard, AppNavigationAddBoard,
AppNavigationBoardCategory, AppNavigationBoardCategory,
Multiselect Multiselect,
}, },
directives: { directives: {
ClickOutside ClickOutside,
}, },
props: { props: {
loading: { loading: {
type: Boolean, type: Boolean,
default: false default: false,
} },
}, },
data() { data() {
return { return {
opened: false, opened: false,
groups: [], groups: [],
groupLimit: [], groupLimit: [],
groupLimitDisabled: true groupLimitDisabled: true,
} }
}, },
computed: { computed: {
...mapGetters([ ...mapGetters([
'noneArchivedBoards', 'noneArchivedBoards',
'archivedBoards', 'archivedBoards',
'sharedBoards' 'sharedBoards',
]), ]),
isAdmin() { isAdmin() {
// eslint-disable-next-line // eslint-disable-next-line
//return oc_isadmin //return oc_isadmin
return OC.isUserAdmin() return OC.isUserAdmin()
} },
}, },
beforeMount() { beforeMount() {
if (this.isAdmin) { if (this.isAdmin) {
@@ -121,7 +122,7 @@ export default {
this.groups = response.data.ocs.data.groups.reduce((obj, item) => { this.groups = response.data.ocs.data.groups.reduce((obj, item) => {
obj.push({ obj.push({
id: item, id: item,
displayname: item displayname: item,
}) })
return obj return obj
}, []) }, [])
@@ -140,14 +141,14 @@ export default {
updateConfig() { updateConfig() {
this.groupLimitDisabled = true this.groupLimitDisabled = true
axios.post(OC.generateUrl('apps/deck/config/groupLimit'), { axios.post(OC.generateUrl('apps/deck/config/groupLimit'), {
value: this.groupLimit value: this.groupLimit,
}).then(() => { }).then(() => {
this.groupLimitDisabled = false this.groupLimitDisabled = false
}, (error) => { }, (error) => {
console.error('Error while saving groupLimit', error.response) console.error('Error while saving groupLimit', error.response)
}) })
} },
} },
} }
</script> </script>
<style> <style>

View File

@@ -21,8 +21,8 @@
--> -->
<template> <template>
<li id="deck-navigation-add" <li id="deck-navigation-add"
:title="t('deck', 'Create new board')" :class="[{'icon-loading-small': loading, 'editing': editing}, classes]" :title="t('deck', 'Create new board')"
> :class="[{'icon-loading-small': loading, 'editing': editing}, classes]">
<a class="icon-add" href="#" @click.prevent.stop="startCreateBoard"> <a class="icon-add" href="#" @click.prevent.stop="startCreateBoard">
{{ t('deck', 'Create new board') }} {{ t('deck', 'Create new board') }}
</a> </a>
@@ -32,9 +32,10 @@
<form @submit.prevent.stop="createBoard"> <form @submit.prevent.stop="createBoard">
<input :placeholder="t('deck', 'New board title')" type="text" required> <input :placeholder="t('deck', 'New board title')" type="text" required>
<input type="submit" value="" class="icon-confirm"> <input type="submit" value="" class="icon-confirm">
<input type="submit" value="" class="icon-close" <input type="submit"
@click.stop.prevent="cancelEdit" value=""
> class="icon-close"
@click.stop.prevent="cancelEdit">
</form> </form>
<ColorPicker v-model="color" /> <ColorPicker v-model="color" />
</div> </div>
@@ -53,7 +54,7 @@ export default {
classes: [], classes: [],
editing: false, editing: false,
loading: false, loading: false,
color: '#000000' color: '#000000',
} }
}, },
computed: {}, computed: {},
@@ -67,15 +68,15 @@ export default {
const title = e.currentTarget.childNodes[0].value const title = e.currentTarget.childNodes[0].value
this.$store.dispatch('createBoard', { this.$store.dispatch('createBoard', {
title: title, title: title,
color: this.color.substring(1) color: this.color.substring(1),
}) })
this.editing = false this.editing = false
}, },
cancelEdit(e) { cancelEdit(e) {
this.editing = false this.editing = false
this.item.edit.reset(e) this.item.edit.reset(e)
} },
} },
} }
</script> </script>
<style scoped> <style scoped>

View File

@@ -21,9 +21,10 @@
--> -->
<template> <template>
<router-link :id="`board-${board.id}`" <router-link :id="`board-${board.id}`"
:title="board.title" :class="[{'icon-loading-small': loading, deleted: deleted, editing: editing }, classes]" :title="board.title"
:to="routeTo" tag="li" :class="[{'icon-loading-small': loading, deleted: deleted, editing: editing }, classes]"
> :to="routeTo"
tag="li">
<div :style="{ backgroundColor: `#${board.color}` }" class="app-navigation-entry-bullet" /> <div :style="{ backgroundColor: `#${board.color}` }" class="app-navigation-entry-bullet" />
<a href="#"> <a href="#">
{{ board.title }} {{ board.title }}
@@ -32,9 +33,10 @@
<div v-if="actions.length > 0" class="app-navigation-entry-utils"> <div v-if="actions.length > 0" class="app-navigation-entry-utils">
<ul> <ul>
<li class="app-navigation-entry-utils-menu-button"> <li class="app-navigation-entry-utils-menu-button">
<button v-if="board.acl.length === 0" class="icon-shared" style="opacity: 0.3" <button v-if="board.acl.length === 0"
@click="showSidebar" class="icon-shared"
/> style="opacity: 0.3"
@click="showSidebar" />
<button v-else class="icon-shared" @click="showSidebar" /> <button v-else class="icon-shared" @click="showSidebar" />
</li> </li>
<li class="app-navigation-entry-utils-menu-button"> <li class="app-navigation-entry-utils-menu-button">
@@ -43,7 +45,7 @@
</ul> </ul>
</div> </div>
<div :class="{ 'open': menuOpen }" class="app-navigation-entry-menu"> <div :class="{ 'open': menuOpen }" class="app-navigation-entry-menu">
<popover-menu :menu="actions" /> <PopoverMenu :menu="actions" />
</div> </div>
<!-- undo action --> <!-- undo action -->
@@ -54,8 +56,7 @@
<button <button
:title="t('settings', 'Undo')" :title="t('settings', 'Undo')"
class="app-navigation-entry-deleted-button icon-history" class="app-navigation-entry-deleted-button icon-history"
@click="unDelete" @click="unDelete" />
/>
</div> </div>
<!-- edit entry --> <!-- edit entry -->
@@ -63,9 +64,10 @@
<form @submit.prevent.stop="applyEdit"> <form @submit.prevent.stop="applyEdit">
<input v-model="editTitle" type="text" required> <input v-model="editTitle" type="text" required>
<input type="submit" value="" class="icon-confirm"> <input type="submit" value="" class="icon-confirm">
<input type="submit" value="" class="icon-close" <input type="submit"
@click.stop.prevent="cancelEdit" value=""
> class="icon-close"
@click.stop.prevent="cancelEdit">
</form> </form>
<ColorPicker v-model="editColor" /> <ColorPicker v-model="editColor" />
</div> </div>
@@ -81,16 +83,16 @@ export default {
name: 'AppNavigationBoard', name: 'AppNavigationBoard',
components: { components: {
ColorPicker, ColorPicker,
PopoverMenu PopoverMenu,
}, },
directives: { directives: {
ClickOutside ClickOutside,
}, },
props: { props: {
board: { board: {
type: Object, type: Object,
required: true required: true,
} },
}, },
data() { data() {
return { return {
@@ -101,7 +103,7 @@ export default {
menuOpen: false, menuOpen: false,
undoTimeoutHandle: null, undoTimeoutHandle: null,
editTitle: '', editTitle: '',
editColor: '' editColor: '',
} }
}, },
computed: { computed: {
@@ -112,7 +114,7 @@ export default {
routeTo: function() { routeTo: function() {
return { return {
name: 'board', name: 'board',
params: { id: this.board.id } params: { id: this.board.id },
} }
}, },
actions: function() { actions: function() {
@@ -131,7 +133,7 @@ export default {
this.editing = true this.editing = true
}, },
icon: 'icon-rename', icon: 'icon-rename',
text: t('deck', 'Edit board') text: t('deck', 'Edit board'),
}) })
actions.push({ actions.push({
@@ -150,7 +152,7 @@ export default {
} }
}, },
icon: 'icon-clone', icon: 'icon-clone',
text: t('deck', 'Clone board') text: t('deck', 'Clone board'),
}) })
if (!this.board.archived) { if (!this.board.archived) {
@@ -161,7 +163,7 @@ export default {
this.$store.dispatch('archiveBoard', this.board) this.$store.dispatch('archiveBoard', this.board)
}, },
icon: 'icon-archive', icon: 'icon-archive',
text: t('deck', 'Archive board') text: t('deck', 'Archive board'),
}) })
} else { } else {
actions.push({ actions.push({
@@ -171,7 +173,7 @@ export default {
this.$store.dispatch('unarchiveBoard', this.board) this.$store.dispatch('unarchiveBoard', this.board)
}, },
icon: 'icon-archive', icon: 'icon-archive',
text: t('deck', 'Unarchive board') text: t('deck', 'Unarchive board'),
}) })
} }
@@ -189,7 +191,7 @@ export default {
}) })
}, },
icon: 'icon-delete', icon: 'icon-delete',
text: t('deck', 'Delete board') text: t('deck', 'Delete board'),
}) })
actions.push({ actions.push({
@@ -199,13 +201,13 @@ export default {
this.$router.push(route) this.$router.push(route)
}, },
icon: 'icon-settings-dark', icon: 'icon-settings-dark',
text: t('deck', 'Board details') text: t('deck', 'Board details'),
}) })
} }
return actions return actions
} },
}, },
watch: {}, watch: {},
mounted() { mounted() {
@@ -246,11 +248,11 @@ export default {
const route = this.routeTo const route = this.routeTo
route.name = 'board.details' route.name = 'board.details'
this.$router.push(route) this.$router.push(route)
} },
}, },
inject: [ inject: [
'boardApi' 'boardApi',
] ],
} }
</script> </script>

View File

@@ -20,15 +20,16 @@
- -
--> -->
<template> <template>
<li v-if="boards.length > 0" :id="id" :title="text" <li v-if="boards.length > 0"
:class="{'open': opened, 'collapsible': collapsible }" :id="id"
> :title="text"
:class="{'open': opened, 'collapsible': collapsible }">
<button v-if="collapsible" class="collapse" @click.prevent.stop="toggleCollapse" /> <button v-if="collapsible" class="collapse" @click.prevent.stop="toggleCollapse" />
<a :class="icon" href="#"> <a :class="icon" href="#">
{{ text }} {{ text }}
</a> </a>
<ul v-if="boards.length > 0"> <ul v-if="boards.length > 0">
<app-navigation-board v-for="board in boards" :key="board.id" :board="board" /> <AppNavigationBoard v-for="board in boards" :key="board.id" :board="board" />
</ul> </ul>
</li> </li>
</template> </template>
@@ -40,27 +41,27 @@ import AppNavigationBoard from './AppNavigationBoard'
export default { export default {
name: 'AppNavigationBoardCategory', name: 'AppNavigationBoardCategory',
components: { components: {
AppNavigationBoard AppNavigationBoard,
}, },
directives: { directives: {
ClickOutside ClickOutside,
}, },
props: { props: {
id: { id: {
type: String, type: String,
required: true required: true,
}, },
text: { text: {
type: String, type: String,
required: true required: true,
}, },
icon: { icon: {
type: String, type: String,
required: true required: true,
}, },
boards: { boards: {
type: Array, type: Array,
required: true required: true,
}, },
/** /**
* Control whether the category should be opened when adding boards. * Control whether the category should be opened when adding boards.
@@ -68,31 +69,31 @@ export default {
*/ */
openOnAddBoards: { openOnAddBoards: {
type: Boolean, type: Boolean,
default: false default: false,
} },
}, },
data() { data() {
return { return {
opened: false opened: false,
} }
}, },
computed: { computed: {
collapsible() { collapsible() {
return this.boards.length > 0 return this.boards.length > 0
} },
}, },
watch: { watch: {
boards: function(newVal, prevVal) { boards: function(newVal, prevVal) {
if (this.openOnAddBoards === true && prevVal.length < newVal.length) { if (this.openOnAddBoards === true && prevVal.length < newVal.length) {
this.opened = true this.opened = true
} }
} },
}, },
mounted() {}, mounted() {},
methods: { methods: {
toggleCollapse() { toggleCollapse() {
this.opened = !this.opened this.opened = !this.opened
} },
} },
} }
</script> </script>

View File

@@ -46,7 +46,7 @@ Vue.prototype.OC = OC;
const body = document.getElementById('body-user') const body = document.getElementById('body-user')
body.append(container) body.append(container)
const ComponentVM = new Vue({ const ComponentVM = new Vue({
render: h => h(BoardSelector) render: h => h(BoardSelector),
}) })
ComponentVM.$mount(container) ComponentVM.$mount(container)
ComponentVM.$root.$on('close', () => { ComponentVM.$root.$on('close', () => {
@@ -62,7 +62,7 @@ Vue.prototype.OC = OC;
}) })
}, },
typeString: t('deck', 'Link to a board'), typeString: t('deck', 'Link to a board'),
typeIconClass: 'icon-deck' typeIconClass: 'icon-deck',
}) })
OCP.Collaboration.registerType('deck-card', { OCP.Collaboration.registerType('deck-card', {
@@ -73,7 +73,7 @@ Vue.prototype.OC = OC;
const body = document.getElementById('body-user') const body = document.getElementById('body-user')
body.append(container) body.append(container)
const ComponentVM = new Vue({ const ComponentVM = new Vue({
render: h => h(CardSelector) render: h => h(CardSelector),
}) })
ComponentVM.$mount(container) ComponentVM.$mount(container)
ComponentVM.$root.$on('close', () => { ComponentVM.$root.$on('close', () => {
@@ -89,6 +89,6 @@ Vue.prototype.OC = OC;
}) })
}, },
typeString: t('deck', 'Link to a card'), typeString: t('deck', 'Link to a card'),
typeIconClass: 'icon-deck' typeIconClass: 'icon-deck',
}) })
})(window.OCP)) })(window.OCP))

View File

@@ -39,8 +39,8 @@ sync(store, router)
Vue.mixin({ Vue.mixin({
methods: { methods: {
t: translate, t: translate,
n: translatePlural n: translatePlural,
} },
}) })
Vue.directive('tooltip', Tooltip) Vue.directive('tooltip', Tooltip)
@@ -50,5 +50,5 @@ new Vue({
el: '#content', el: '#content',
router, router,
store, store,
render: h => h(App) render: h => h(App),
}) })

View File

@@ -23,12 +23,12 @@
export default { export default {
methods: { methods: {
hexToRgb(hex) { hexToRgb(hex) {
let result = /^#?([A-Fa-f\d]{2})([A-Fa-f\d]{2})([A-Fa-f\d]{2})$/i.exec(hex) const result = /^#?([A-Fa-f\d]{2})([A-Fa-f\d]{2})([A-Fa-f\d]{2})$/i.exec(hex)
if (result) { if (result) {
return { return {
r: parseInt(result[1], 16), r: parseInt(result[1], 16),
g: parseInt(result[2], 16), g: parseInt(result[2], 16),
b: parseInt(result[3], 16) b: parseInt(result[3], 16),
} }
} }
return null return null
@@ -39,11 +39,11 @@ export default {
const r = rgb.r / 255 const r = rgb.r / 255
const g = rgb.g / 255 const g = rgb.g / 255
const b = rgb.b / 255 const b = rgb.b / 255
let max = Math.max(r, g, b) const max = Math.max(r, g, b)
let min = Math.min(r, g, b) const min = Math.min(r, g, b)
let h let h
let s let s
let l = (max + min) / 2 const l = (max + min) / 2
if (max === min) { if (max === min) {
h = s = 0 // achromatic h = s = 0 // achromatic
@@ -64,12 +64,12 @@ export default {
h /= 6 h /= 6
} }
return { return {
h, l, s h, l, s,
} }
}, },
textColor(hex) { textColor(hex) {
let rgb = this.hexToRgb(hex) const rgb = this.hexToRgb(hex)
if (rgb === null) { if (rgb === null) {
return '#000000' return '#000000'
} }
@@ -84,13 +84,13 @@ export default {
}, },
colorIsValid(hex) { colorIsValid(hex) {
var re = new RegExp('[A-Fa-f0-9]{6}') const re = new RegExp('[A-Fa-f0-9]{6}')
if (re.test(hex)) { if (re.test(hex)) {
return true return true
} }
return false return false
} },
} },
} }

View File

@@ -39,45 +39,45 @@ export default new Router({
{ {
path: '/', path: '/',
name: 'main', name: 'main',
component: Boards component: Boards,
}, },
{ {
path: '/boards', path: '/boards',
name: 'boards', name: 'boards',
component: Boards, component: Boards,
props: { props: {
navFilter: BOARD_FILTERS.ALL navFilter: BOARD_FILTERS.ALL,
} },
}, },
{ {
path: '/boards/archived', path: '/boards/archived',
name: 'boards.archived', name: 'boards.archived',
component: Boards, component: Boards,
props: { props: {
navFilter: BOARD_FILTERS.ARCHIVED navFilter: BOARD_FILTERS.ARCHIVED,
} },
}, },
{ {
path: '/boards/shared', path: '/boards/shared',
name: 'boards.shared', name: 'boards.shared',
component: Boards, component: Boards,
props: { props: {
navFilter: BOARD_FILTERS.SHARED navFilter: BOARD_FILTERS.SHARED,
} },
}, },
{ {
path: '/boards/:id', path: '/boards/:id',
name: 'board', name: 'board',
components: { components: {
default: Board, default: Board,
sidebar: Sidebar sidebar: Sidebar,
}, },
props: { props: {
default: (route) => { default: (route) => {
return { return {
id: parseInt(route.params.id, 10) id: parseInt(route.params.id, 10),
} }
} },
}, },
children: [ children: [
{ {
@@ -85,41 +85,41 @@ export default new Router({
name: 'board.details', name: 'board.details',
components: { components: {
default: Boards, default: Boards,
sidebar: BoardSidebar sidebar: BoardSidebar,
}, },
props: { props: {
default: (route) => { default: (route) => {
return { return {
id: parseInt(route.params.id, 10) id: parseInt(route.params.id, 10),
} }
}, },
sidebar: (route) => { sidebar: (route) => {
return { return {
id: parseInt(route.params.id, 10) id: parseInt(route.params.id, 10),
} }
} },
} },
}, },
{ {
path: 'cards/:cardId', path: 'cards/:cardId',
name: 'card', name: 'card',
components: { components: {
sidebar: CardSidebar sidebar: CardSidebar,
}, },
props: { props: {
default: (route) => { default: (route) => {
return { return {
cardId: parseInt(route.params.cardId, 10) cardId: parseInt(route.params.cardId, 10),
} }
}, },
sidebar: (route) => { sidebar: (route) => {
return { return {
id: parseInt(route.params.cardId, 10) id: parseInt(route.params.cardId, 10),
} }
} },
} },
} },
] ],
} },
] ],
}) })

View File

@@ -36,7 +36,7 @@ export class BoardApi {
* Updates a board. * Updates a board.
* *
* @param {Board} board * @param {Board} board
* @return Promise * @returns Promise
*/ */
updateBoard(board) { updateBoard(board) {
return axios.put(this.url(`/boards/${board.id}`), board) return axios.put(this.url(`/boards/${board.id}`), board)
@@ -57,7 +57,7 @@ export class BoardApi {
* Creates a new board. * Creates a new board.
* *
* @param {{String title, String color}} boardData The board data to send. * @param {{String title, String color}} boardData The board data to send.
* color the hexadecimal color value formated /[0-9A-F]{6}/i * color the hexadecimal color value formated /[0-9A-F]{6}/i
* @return Promise * @return Promise
*/ */
createBoard(boardData) { createBoard(boardData) {
@@ -137,7 +137,7 @@ export class BoardApi {
async cloneBoard(board) { async cloneBoard(board) {
try { try {
let response = await axios.post(this.url(`/boards/${board.id}/clone`)) const response = await axios.post(this.url(`/boards/${board.id}/clone`))
return response.data return response.data
} catch (err) { } catch (err) {
return err return err

View File

@@ -27,7 +27,7 @@ const apiClient = new CardApi()
export default { export default {
state: { state: {
cards: [] cards: [],
}, },
getters: { getters: {
cardsByStack: state => (id) => { cardsByStack: state => (id) => {
@@ -35,73 +35,73 @@ export default {
}, },
cardById: state => (id) => { cardById: state => (id) => {
return state.cards.find((card) => card.id === id) return state.cards.find((card) => card.id === id)
} },
}, },
mutations: { mutations: {
clearCards(state) { clearCards(state) {
state.cards = [] state.cards = []
}, },
addCard(state, card) { addCard(state, card) {
let existingIndex = state.cards.findIndex(_card => _card.id === card.id) const existingIndex = state.cards.findIndex(_card => _card.id === card.id)
if (existingIndex !== -1) { if (existingIndex !== -1) {
let existingCard = state.cards.find(_card => _card.id === card.id) const existingCard = state.cards.find(_card => _card.id === card.id)
Vue.set(state.cards, existingIndex, Object.assign({}, existingCard, card)) Vue.set(state.cards, existingIndex, Object.assign({}, existingCard, card))
} else { } else {
state.cards.push(card) state.cards.push(card)
} }
}, },
deleteCard(state, card) { deleteCard(state, card) {
let existingIndex = state.cards.findIndex(_card => _card.id === card.id) const existingIndex = state.cards.findIndex(_card => _card.id === card.id)
if (existingIndex !== -1) { if (existingIndex !== -1) {
state.cards.splice(existingIndex, 1) state.cards.splice(existingIndex, 1)
} }
}, },
updateCard(state, card) { updateCard(state, card) {
let existingIndex = state.cards.findIndex(_card => _card.id === card.id) const existingIndex = state.cards.findIndex(_card => _card.id === card.id)
if (existingIndex !== -1) { if (existingIndex !== -1) {
Vue.set(state.cards, existingIndex, card) Vue.set(state.cards, existingIndex, card)
} }
}, },
updateTitle(state, card) { updateTitle(state, card) {
let existingIndex = state.cards.findIndex(_card => _card.id === card.id) const existingIndex = state.cards.findIndex(_card => _card.id === card.id)
if (existingIndex !== -1) { if (existingIndex !== -1) {
state.cards[existingIndex].title = card.title state.cards[existingIndex].title = card.title
} }
}, },
assignCardToUser(state, user) { assignCardToUser(state, user) {
let existingIndex = state.cards.findIndex(_card => _card.id === user.cardId) const existingIndex = state.cards.findIndex(_card => _card.id === user.cardId)
if (existingIndex !== -1) { if (existingIndex !== -1) {
state.cards[existingIndex].assignedUsers.push(user) state.cards[existingIndex].assignedUsers.push(user)
} }
}, },
removeUserFromCard(state, user) { removeUserFromCard(state, user) {
let existingIndex = state.cards.findIndex(_card => _card.id === user.cardId) const existingIndex = state.cards.findIndex(_card => _card.id === user.cardId)
if (existingIndex !== -1) { if (existingIndex !== -1) {
let foundIndex = state.cards[existingIndex].assignedUsers.findIndex(_user => _user.id === user.id) const foundIndex = state.cards[existingIndex].assignedUsers.findIndex(_user => _user.id === user.id)
if (foundIndex !== -1) { if (foundIndex !== -1) {
state.cards[existingIndex].assignedUsers.splice(foundIndex, 1) state.cards[existingIndex].assignedUsers.splice(foundIndex, 1)
} }
} }
}, },
updateCardDesc(state, card) { updateCardDesc(state, card) {
let existingIndex = state.cards.findIndex(_card => _card.id === card.id) const existingIndex = state.cards.findIndex(_card => _card.id === card.id)
if (existingIndex !== -1) { if (existingIndex !== -1) {
state.cards[existingIndex].description = card.description state.cards[existingIndex].description = card.description
} }
}, },
updateCardDue(state, card) { updateCardDue(state, card) {
let existingIndex = state.cards.findIndex(_card => _card.id === card.id) const existingIndex = state.cards.findIndex(_card => _card.id === card.id)
if (existingIndex !== -1) { if (existingIndex !== -1) {
state.cards[existingIndex].duedate = card.duedate state.cards[existingIndex].duedate = card.duedate
} }
}, },
updateCardLabels(state, card) { updateCardLabels(state, card) {
let existingIndex = state.cards.findIndex(_card => _card.id === card.id) const existingIndex = state.cards.findIndex(_card => _card.id === card.id)
if (existingIndex !== -1) { if (existingIndex !== -1) {
let existingCard = state.cards.find(_card => _card.id === card.id) const existingCard = state.cards.find(_card => _card.id === card.id)
existingCard.labels = card.labels existingCard.labels = card.labels
} }
} },
}, },
actions: { actions: {
addCard({ commit }, card) { addCard({ commit }, card) {
@@ -192,6 +192,6 @@ export default {
.then((card) => { .then((card) => {
commit('updateCardDue', card) commit('updateCardDue', card)
}) })
} },
} },
} }

View File

@@ -37,13 +37,13 @@ const debug = process.env.NODE_ENV !== 'production'
export const BOARD_FILTERS = { export const BOARD_FILTERS = {
ALL: '', ALL: '',
ARCHIVED: 'archived', ARCHIVED: 'archived',
SHARED: 'shared' SHARED: 'shared',
} }
export default new Vuex.Store({ export default new Vuex.Store({
modules: { modules: {
stack, stack,
card card,
}, },
strict: debug, strict: debug,
state: { state: {
@@ -58,7 +58,7 @@ export default new Vuex.Store({
assignableUsers: [], assignableUsers: [],
boardFilter: BOARD_FILTERS.ALL, boardFilter: BOARD_FILTERS.ALL,
activity: [], activity: [],
activityLoadMore: true activityLoadMore: true,
}, },
getters: { getters: {
boards: state => { boards: state => {
@@ -93,7 +93,7 @@ export default new Vuex.Store({
}, },
currentBoardLabels: state => { currentBoardLabels: state => {
return state.currentBoard.labels return state.currentBoard.labels
} },
}, },
mutations: { mutations: {
toggleShowArchived(state) { toggleShowArchived(state) {
@@ -197,7 +197,7 @@ export default new Vuex.Store({
}, },
updateLabelFromCurrentBoard(state, newLabel) { updateLabelFromCurrentBoard(state, newLabel) {
let labelToUpdate = state.currentBoard.labels.find((l) => { const labelToUpdate = state.currentBoard.labels.find((l) => {
return newLabel.id === l.id return newLabel.id === l.id
}) })
@@ -214,7 +214,7 @@ export default new Vuex.Store({
state.currentBoard.acl.push(createdAcl) state.currentBoard.acl.push(createdAcl)
}, },
updateAclFromCurrentBoard(state, acl) { updateAclFromCurrentBoard(state, acl) {
for (var acl_ in state.currentBoard.acl) { for (const acl_ in state.currentBoard.acl) {
if (state.currentBoard.acl[acl_].participant.uid === acl.participant.uid) { if (state.currentBoard.acl[acl_].participant.uid === acl.participant.uid) {
state.currentBoard.acl[acl_] = acl state.currentBoard.acl[acl_] = acl
break break
@@ -223,8 +223,8 @@ export default new Vuex.Store({
}, },
deleteAclFromCurrentBoard(state, acl) { deleteAclFromCurrentBoard(state, acl) {
let removeIndex = -1 let removeIndex = -1
for (var index in state.currentBoard.acl) { for (const index in state.currentBoard.acl) {
var attr = state.currentBoard.acl[index] const attr = state.currentBoard.acl[index]
if (acl.id === attr.id) { if (acl.id === attr.id) {
removeIndex = index removeIndex = index
break break
@@ -234,7 +234,7 @@ export default new Vuex.Store({
if (removeIndex > -1) { if (removeIndex > -1) {
Vue.delete(state.currentBoard.acl, removeIndex) Vue.delete(state.currentBoard.acl, removeIndex)
} }
} },
}, },
actions: { actions: {
loadBoardById({ commit }, boardId) { loadBoardById({ commit }, boardId) {
@@ -279,7 +279,7 @@ export default new Vuex.Store({
* *
* @param commit * @param commit
* @param board The board to update. * @param board The board to update.
* @return {Promise<void>} * @returns {Promise<void>}
*/ */
async updateBoard({ commit }, board) { async updateBoard({ commit }, board) {
const storedBoard = await apiClient.updateBoard(board) const storedBoard = await apiClient.updateBoard(board)
@@ -293,7 +293,7 @@ export default new Vuex.Store({
}, },
async cloneBoard({ commit }, boardData) { async cloneBoard({ commit }, boardData) {
try { try {
let newBoard = await apiClient.cloneBoard(boardData) const newBoard = await apiClient.cloneBoard(boardData)
commit('cloneBoard', newBoard) commit('cloneBoard', newBoard)
return newBoard return newBoard
} catch (err) { } catch (err) {
@@ -408,6 +408,6 @@ export default new Vuex.Store({
commit('deleteAclFromCurrentBoard', acl) commit('deleteAclFromCurrentBoard', acl)
dispatch('loadBoardById', acl.boardId) dispatch('loadBoardById', acl.boardId)
}) })
} },
} },
}) })

View File

@@ -30,39 +30,39 @@ export default {
state: { state: {
stacks: [], stacks: [],
deletedStacks: [], deletedStacks: [],
deletedCards: [] deletedCards: [],
}, },
getters: { getters: {
stacksByBoard: state => (id) => { stacksByBoard: state => (id) => {
return state.stacks.filter((stack) => stack.boardId === id).sort((a, b) => a.order - b.order) return state.stacks.filter((stack) => stack.boardId === id).sort((a, b) => a.order - b.order)
} },
}, },
mutations: { mutations: {
addStack(state, stack) { addStack(state, stack) {
let existingIndex = state.stacks.findIndex(_stack => _stack.id === stack.id) const existingIndex = state.stacks.findIndex(_stack => _stack.id === stack.id)
if (existingIndex !== -1) { if (existingIndex !== -1) {
let existingStack = state.stacks.find(_stack => _stack.id === stack.id) const existingStack = state.stacks.find(_stack => _stack.id === stack.id)
Vue.set(state.stacks, existingIndex, Object.assign({}, existingStack, stack)) Vue.set(state.stacks, existingIndex, Object.assign({}, existingStack, stack))
} else { } else {
state.stacks.push(stack) state.stacks.push(stack)
} }
}, },
orderStack(state, { stack, removedIndex, addedIndex }) { orderStack(state, { stack, removedIndex, addedIndex }) {
let currentOrder = state.stacks.filter((_stack) => _stack.boardId === stack.boardId).sort((a, b) => a.order - b.order) const currentOrder = state.stacks.filter((_stack) => _stack.boardId === stack.boardId).sort((a, b) => a.order - b.order)
var newOrder = applyOrderToArray(currentOrder, removedIndex, addedIndex) const newOrder = applyOrderToArray(currentOrder, removedIndex, addedIndex)
for (let i = 0; i < newOrder.length; i++) { for (let i = 0; i < newOrder.length; i++) {
newOrder[i].order = parseInt(i) newOrder[i].order = parseInt(i)
} }
}, },
deleteStack(state, stack) { deleteStack(state, stack) {
let existingIndex = state.stacks.findIndex(_stack => _stack.id === stack.id) const existingIndex = state.stacks.findIndex(_stack => _stack.id === stack.id)
if (existingIndex !== -1) { if (existingIndex !== -1) {
state.stacks.splice(existingIndex, 1) state.stacks.splice(existingIndex, 1)
} }
}, },
updateStack(state, stack) { updateStack(state, stack) {
let existingIndex = state.stacks.findIndex(_stack => _stack.id === stack.id) const existingIndex = state.stacks.findIndex(_stack => _stack.id === stack.id)
if (existingIndex !== -1) { if (existingIndex !== -1) {
state.stacks[existingIndex].title = stack.title state.stacks[existingIndex].title = stack.title
} }
@@ -76,7 +76,7 @@ export default {
setDeletedCards(state, delCards) { setDeletedCards(state, delCards) {
state.deletedCards = [] state.deletedCards = []
state.deletedCards = delCards state.deletedCards = delCards
} },
}, },
actions: { actions: {
orderStack({ commit }, { stack, removedIndex, addedIndex }) { orderStack({ commit }, { stack, removedIndex, addedIndex }) {
@@ -96,9 +96,9 @@ export default {
} }
apiClient[call](boardId) apiClient[call](boardId)
.then((stacks) => { .then((stacks) => {
for (let i in stacks) { for (const i in stacks) {
let stack = stacks[i] const stack = stacks[i]
for (let j in stack.cards) { for (const j in stack.cards) {
commit('addCard', stack.cards[j]) commit('addCard', stack.cards[j])
} }
delete stack.cards delete stack.cards
@@ -140,7 +140,7 @@ export default {
.then((stack) => { .then((stack) => {
commit('addStack', stack) commit('addStack', stack)
}) })
} },
} },
} }