fix: add retry and show warning on description saving error (#7070)
Signed-off-by: Luka Trovic <luka@nextcloud.com>
This commit is contained in:
@@ -87,7 +87,7 @@ import HomeIcon from 'vue-material-design-icons/Home.vue'
|
|||||||
import CommentIcon from 'vue-material-design-icons/Comment.vue'
|
import CommentIcon from 'vue-material-design-icons/Comment.vue'
|
||||||
import ActivityIcon from 'vue-material-design-icons/LightningBolt.vue'
|
import ActivityIcon from 'vue-material-design-icons/LightningBolt.vue'
|
||||||
|
|
||||||
import { showError } from '@nextcloud/dialogs'
|
import { showError, showWarning } from '@nextcloud/dialogs'
|
||||||
import { getLocale } from '@nextcloud/l10n'
|
import { getLocale } from '@nextcloud/l10n'
|
||||||
import CardMenuEntries from '../cards/CardMenuEntries.vue'
|
import CardMenuEntries from '../cards/CardMenuEntries.vue'
|
||||||
|
|
||||||
@@ -139,6 +139,7 @@ export default {
|
|||||||
...mapState({
|
...mapState({
|
||||||
isFullApp: (state) => state.isFullApp,
|
isFullApp: (state) => state.isFullApp,
|
||||||
currentBoard: (state) => state.currentBoard,
|
currentBoard: (state) => state.currentBoard,
|
||||||
|
hasCardSaveError: (state) => state.hasCardSaveError,
|
||||||
}),
|
}),
|
||||||
...mapGetters(['canEdit', 'assignables', 'cardActions', 'stackById']),
|
...mapGetters(['canEdit', 'assignables', 'cardActions', 'stackById']),
|
||||||
currentCard() {
|
currentCard() {
|
||||||
@@ -198,6 +199,10 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
closeSidebar() {
|
closeSidebar() {
|
||||||
|
if (this.hasCardSaveError) {
|
||||||
|
showWarning(t('deck', 'Cannot close unsaved card!'))
|
||||||
|
return
|
||||||
|
}
|
||||||
this.$router?.push({ name: 'board' })
|
this.$router?.push({ name: 'board' })
|
||||||
this.$emit('close')
|
this.$emit('close')
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -73,7 +73,9 @@ import AttachmentList from './AttachmentList.vue'
|
|||||||
import { NcActions, NcActionButton, NcModal } from '@nextcloud/vue'
|
import { NcActions, NcActionButton, NcModal } from '@nextcloud/vue'
|
||||||
import { formatFileSize } from '@nextcloud/files'
|
import { formatFileSize } from '@nextcloud/files'
|
||||||
import { generateUrl } from '@nextcloud/router'
|
import { generateUrl } from '@nextcloud/router'
|
||||||
|
import { showWarning } from '@nextcloud/dialogs'
|
||||||
import PaperclipIcon from 'vue-material-design-icons/Paperclip.vue'
|
import PaperclipIcon from 'vue-material-design-icons/Paperclip.vue'
|
||||||
|
import { mapState } from 'vuex'
|
||||||
|
|
||||||
const markdownIt = new MarkdownIt({
|
const markdownIt = new MarkdownIt({
|
||||||
linkify: true,
|
linkify: true,
|
||||||
@@ -135,6 +137,9 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
...mapState({
|
||||||
|
hasCardSaveError: (state) => state.hasCardSaveError,
|
||||||
|
}),
|
||||||
mimetypeForAttachment() {
|
mimetypeForAttachment() {
|
||||||
return (mimetype) => {
|
return (mimetype) => {
|
||||||
const url = OC.MimeType.getIconUrl(mimetype)
|
const url = OC.MimeType.getIconUrl(mimetype)
|
||||||
@@ -285,15 +290,31 @@ export default {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.descriptionSaving = true
|
this.descriptionSaving = true
|
||||||
|
try {
|
||||||
if (this.card.id !== undefined) {
|
if (this.card.id !== undefined) {
|
||||||
await this.$store.dispatch('updateCardDesc', { ...this.card, description: this.description })
|
await this.$store.dispatch('updateCardDesc', { ...this.card, description: this.description })
|
||||||
}
|
}
|
||||||
this.$emit('change', this.description)
|
this.$emit('change', this.description)
|
||||||
this.descriptionLastEdit = 0
|
this.descriptionLastEdit = 0
|
||||||
|
this.$store.commit('setHasCardSaveError', false)
|
||||||
|
} catch (e) {
|
||||||
|
this.$store.commit('setHasCardSaveError', true)
|
||||||
|
showWarning(t('deck', 'Could not save description'), { timeout: 2500 })
|
||||||
|
console.error(e)
|
||||||
|
|
||||||
|
// Retry of network error
|
||||||
|
if (['ERR_NETWORK', 'ETIMEDOUT'].includes(e.code)) {
|
||||||
|
this.setSaveTimeout()
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
this.descriptionSaving = false
|
this.descriptionSaving = false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
updateDescription() {
|
updateDescription() {
|
||||||
this.descriptionLastEdit = Date.now()
|
this.descriptionLastEdit = Date.now()
|
||||||
|
this.setSaveTimeout()
|
||||||
|
},
|
||||||
|
setSaveTimeout() {
|
||||||
clearTimeout(this.descriptionSaveTimeout)
|
clearTimeout(this.descriptionSaveTimeout)
|
||||||
this.descriptionSaveTimeout = setTimeout(async () => {
|
this.descriptionSaveTimeout = setTimeout(async () => {
|
||||||
await this.saveDescription()
|
await this.saveDescription()
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ export default new Vuex.Store({
|
|||||||
sidebarShown: false,
|
sidebarShown: false,
|
||||||
currentBoard: null,
|
currentBoard: null,
|
||||||
currentCard: null,
|
currentCard: null,
|
||||||
|
hasCardSaveError: false,
|
||||||
boards: loadState('deck', 'initialBoards', []),
|
boards: loadState('deck', 'initialBoards', []),
|
||||||
sharees: [],
|
sharees: [],
|
||||||
assignableUsers: [],
|
assignableUsers: [],
|
||||||
@@ -131,6 +132,9 @@ export default new Vuex.Store({
|
|||||||
setFullApp(state, isFullApp) {
|
setFullApp(state, isFullApp) {
|
||||||
Vue.set(state, 'isFullApp', isFullApp)
|
Vue.set(state, 'isFullApp', isFullApp)
|
||||||
},
|
},
|
||||||
|
setHasCardSaveError(state, hasCardSaveError) {
|
||||||
|
Vue.set(state, 'hasCardSaveError', hasCardSaveError)
|
||||||
|
},
|
||||||
SET_CONFIG(state, { key, value }) {
|
SET_CONFIG(state, { key, value }) {
|
||||||
const [scope, id, configKey] = key.split(':', 3)
|
const [scope, id, configKey] = key.split(':', 3)
|
||||||
let indexExisting = -1
|
let indexExisting = -1
|
||||||
|
|||||||
Reference in New Issue
Block a user