Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
[#346](https://github.com/nextcloud/cookbook/pull/346) @christianlupus
- CI: Create source code packages for each commit
[#346](https://github.com/nextcloud/cookbook/pull/346) @christianlupus
- Allow for inconsistient schema: Parse instructions as list of elements
- Allow for inconsistent schema: Parse instructions as list of elements
[#347](https://github.com/nextcloud/cookbook/pull/347) @victorjoos
- Show button to view all recipes without a category
[#362](https://github.com/nextcloud/cookbook/pull/362/) @seyfeb
- Add a basic changelog to the repository
[#366](https://github.com/nextcloud/cookbook/pull/366/) @christianlupus
- Enfoce update of changelog through CI
- Enforce update of changelog through CI
[#366](https://github.com/nextcloud/cookbook/pull/366/) @christianlupus
- Keyword cloud is displayed in recipe
[#373](https://github.com/nextcloud/cookbook/pull/373/) @seyfeb
Expand All @@ -41,22 +41,24 @@
[#403](https://github.com/nextcloud/cookbook/pull/403) @thembeat
- Nutrition information display and editing
[#416](https://github.com/nextcloud/cookbook/pull/416/) @seyfeb
- Asking user for confirmation when leaving recipe-editor form with changes
[#464](https://github.com/nextcloud/cookbook/pull/464/) @seyfeb

### Changed
- Switch of project ownership to neextcloud organization in GitHub
- Chanage in issue managment
- Switch of project ownership to nextcloud organization in GitHub
- Change in issue management
- Changes to `.gitignore` file
- Translation issues
- Added available Android apps to README
- Update dev dependencies to recent phpunit to avoid warnings and issues
[#376](https://github.com/nextcloud/cookbook/pull/376) @christianlupus
- Made the layout more responsive to shift the metadata right of the image in very wide screens
[#349](https://github.com/nextcloud/cookbook/pull/349/) @christianlupus
- Optimization for SVG to reduce the filesize
- Optimization for SVG to reduce the file size
[#404](https://github.com/nextcloud/cookbook/pull/404) @thembeat
- Replace Default Recipe-Thumb and Full Image with SVG
[#418](https://github.com/nextcloud/cookbook/pull/418) @thembeat
- ENhance the CI tests and build valid dist tarballs during the CI runs
- Enhance the CI tests and build valid dist tarballs during the CI runs
[#435](https://github.com/nextcloud/cookbook/pull/435) @christianlupus
- Images in recipe list are lazily loaded
[#413](https://github.com/nextcloud/cookbook/pull/413/) @seyfeb
Expand Down
64 changes: 55 additions & 9 deletions src/components/RecipeEdit.vue
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,13 @@ export default {
// keep it up to date in multiple places if it changes later
recipeInit: null,

// ==========================
// These are helper variables

// Changes have been made to the initial values of the form
formDirty: false,
// the save button has been clicked
savingRecipe: false,
prepTime: { time: [0, 0], paddedTime: '' },
cookTime: { time: [0, 0], paddedTime: '' },
totalTime: { time: [0, 0], paddedTime: '' },
Expand Down Expand Up @@ -109,6 +115,12 @@ export default {
// convert keyword array to comma-separated string
this.recipe['keywords'] = this.selectedKeywords.join()
}
},
recipe: {
deep: true,
handler() {
this.formDirty = true
}
}
},
methods: {
Expand All @@ -129,6 +141,19 @@ export default {
addEntry: function(field, index, content='') {
this.recipe[field].splice(index, 0, content)
},
beforeWindowUnload(e) {
if (this.confirmStayInEditedForm()) {
// Cancel the window unload event
e.preventDefault()
e.returnValue = ''
}
},
confirmLeavingPage() {
return window.confirm('You have unsaved changes! Do you still want to leave?')
},
confirmStayInEditedForm() {
return !this.savingRecipe && this.formDirty && !this.confirmLeavingPage()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will continue to new URL when a saving action is just running, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea was: If the user clicked the save button (saving is running), the browser continues to the new URL without checking if the form is dirty (this.formDirty) and (if it is dirty) asking for confirmation (!this.confirmLeavingPage())

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I see that. This is more related to the overall comment below about the abort of a saving action.

},
deleteEntry: function(field, index) {
this.recipe[field].splice(index, 1)
},
Expand Down Expand Up @@ -216,6 +241,7 @@ export default {
})
},
save: function() {
this.savingRecipe = true
this.$store.dispatch('setSavingRecipe', { saving: true })
let $this = this
if (this.recipe.id) {
Expand All @@ -232,6 +258,8 @@ export default {
}).fail(function(e) {
$this.$store.dispatch('setSavingRecipe', { saving: false })
alert(t('cookbook', 'Recipe could not be saved'))
}).always(() => {
$this.savingRecipe = false
})
} else {
// Create a new recipe
Expand All @@ -247,6 +275,8 @@ export default {
}).fail(function(e) {
$this.$store.dispatch('setSavingRecipe', { saving: false })
alert(t('cookbook', 'Recipe could not be saved'))
}).always(() => {
$this.savingRecipe = false
})
}
},
Expand Down Expand Up @@ -287,14 +317,17 @@ export default {
this.allCategories.push(this.recipe['recipeCategory'])
}


// Always set the active page last!
this.$store.dispatch('setPage', { page: 'edit' })
} else {
this.initEmptyRecipe()
this.$store.dispatch('setPage', { page: 'create' })
}
this.recipeInit = this.recipe
this.recipeInit = JSON.parse(JSON.stringify(this.recipe))
this.$nextTick(function() {
this.formDirty = false
})

},
initEmptyRecipe: function() {
this.prepTime = { time: [0, 0], paddedTime: '' }
Expand All @@ -318,6 +351,7 @@ export default {
recipeInstructions: [],
nutrition: {}
}
this.formDirty = false
}
},
mounted () {
Expand All @@ -337,6 +371,10 @@ export default {
this.$root.$on('reloadRecipeEdit', () => {
this.loadRecipeData()
})
this.savingRecipe = false
},
beforeDestroy() {
window.removeEventListener('beforeunload', this.beforeWindowUnload)
},
// We can check if the user has browsed from the same recipe's view to this
// edit and save some time by not reloading the recipe data, leading to a
Expand All @@ -363,13 +401,19 @@ export default {
* This can also be used to confirm that the user wants to leave the page
* if there are unsaved changes.
*/
beforeRouteLeave (to, from, next) {
beforeRouteLeave (to, from, next) {
// beforeRouteLeave is called when the static route changes.
// We have to check if the target component stays the same and reload.
// However, we should not reload if the component changes; otherwise
// reloaded data may overwrite the data loaded at the target component
// which will at the very least result in incorrect breadcrumb path!
next()
// Cancel the navigation, if the form has unsaved edits and the user did not
// confirm leave. This prevents accidentally losing changes
if (this.confirmStayInEditedForm()){
next(false)
} else {
// We have to check if the target component stays the same and reload.
// However, we should not reload if the component changes; otherwise
// reloaded data may overwrite the data loaded at the target component
// which will at the very least result in incorrect breadcrumb path!
next()
}
// Check if we should reload the component content
if (this.$window.shouldReloadContent(from.fullPath, to.fullPath)) {
this.setup()
Expand All @@ -383,7 +427,9 @@ export default {
this.setup()
}
},

created() {
window.addEventListener('beforeunload', this.beforeWindowUnload)
},
}
</script>

Expand Down