fix: add retry and show warning on description saving error (#7070)

Signed-off-by: Luka Trovic <luka@nextcloud.com>
This commit is contained in:
Luka Trovic
2025-07-03 11:47:28 +02:00
committed by GitHub
parent 7799854df4
commit 62a9ce3131
3 changed files with 36 additions and 6 deletions

View File

@@ -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')
}, },

View File

@@ -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
if (this.card.id !== undefined) { try {
await this.$store.dispatch('updateCardDesc', { ...this.card, description: this.description }) if (this.card.id !== undefined) {
await this.$store.dispatch('updateCardDesc', { ...this.card, description: this.description })
}
this.$emit('change', this.description)
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.$emit('change', this.description)
this.descriptionLastEdit = 0
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()

View File

@@ -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