Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up entry file and move helper functions to its own module #1062

Merged
merged 5 commits into from
Jul 2, 2022
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@
[#1053](https://github.com/nextcloud/cookbook/pull/1053) @christianlupus
- Remove the amount of data uploaded in CI artifacts
[#1059](https://github.com/nextcloud/cookbook/pull/1059) @christianlupus
- Outsource of functions from entry files to helper module
[#1062](https://github.com/nextcloud/cookbook/pull/1062) @christianlupus

### Documentation
- Add documentation on updates of the API endpoints
Expand Down
17 changes: 8 additions & 9 deletions src/components/AppControls.vue
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,7 @@
icon="icon-rename"
class="action-button"
:aria-label="t('cookbook', 'Edit recipe')"
@click="
$window.goTo(
'/recipe/' + $store.state.recipe.id + '/edit'
)
"
@click="goToRecipe($store.state.recipe.id)"
>{{ t("cookbook", "Edit recipe") }}</ActionButton
>
</Breadcrumb>
Expand Down Expand Up @@ -230,6 +226,8 @@
</template>

<script>
import helpers from "cookbook/js/helper"

import ActionButton from "@nextcloud/vue/dist/Components/ActionButton"
import ActionInput from "@nextcloud/vue/dist/Components/ActionInput"
import Breadcrumbs from "@nextcloud/vue/dist/Components/Breadcrumbs"
Expand Down Expand Up @@ -325,12 +323,10 @@ export default {
) {
return
}
const $this = this

this.$store
.dispatch("deleteRecipe", { id: this.$store.state.recipe.id })
.then(() => {
$this.$window.goTo("/")
helpers.goTo("/")
})
.catch((e) => {
// eslint-disable-next-line no-alert
Expand All @@ -353,12 +349,15 @@ export default {
this.$root.$emit("saveRecipe")
},
search(e) {
this.$window.goTo(`/search/${e.target[1].value}`)
helpers.goTo(`/search/${e.target[1].value}`)
},
updateFilters(e) {
this.filterValue = e
this.$root.$emit("applyRecipeFilter", e)
},
goToRecipe(id) {
helpers.goTo(`/recipe/${id}/edit`)
},
},
}
</script>
Expand Down
6 changes: 5 additions & 1 deletion src/components/AppNavi.vue
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,12 @@ import AppNavigation from "@nextcloud/vue/dist/Components/AppNavigation"
import AppNavigationCounter from "@nextcloud/vue/dist/Components/AppNavigationCounter"
import AppNavigationItem from "@nextcloud/vue/dist/Components/AppNavigationItem"
import AppNavigationNew from "@nextcloud/vue/dist/Components/AppNavigationNew"

import Vue from "vue"

import api from "cookbook/js/api-interface"
import helpers from "cookbook/js/helper"

import AppSettings from "./AppSettings.vue"
import AppNavigationCaption from "./AppNavigationCaption.vue"

Expand Down Expand Up @@ -269,7 +273,7 @@ export default {
.then((response) => {
const recipe = response.data
$this.downloading = false
$this.$window.goTo(`/recipe/${recipe.id}`)
helpers.goTo(`/recipe/${recipe.id}`)
// Refresh left navigation pane to display changes
$this.$store.dispatch("setAppNavigationRefreshRequired", {
isRequired: true,
Expand Down
11 changes: 6 additions & 5 deletions src/components/RecipeEdit.vue
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
import Vue from "vue"

import api from "cookbook/js/api-interface"
import helpers from "cookbook/js/helper"

import EditImageField from "./EditImageField.vue"
import EditInputField from "./EditInputField.vue"
Expand Down Expand Up @@ -146,7 +147,7 @@ export default {
// loading the view component and loading this edit component. If that is
// the case, the user can always manually reload by clicking the breadcrumb.
beforeRouteEnter(to, from, next) {
if (window.isSameItemInstance(from.fullPath, to.fullPath)) {
if (helpers.isSameItemInstance(from.fullPath, to.fullPath)) {
next((vm) => {
vm.setup()
})
Expand Down Expand Up @@ -182,15 +183,15 @@ export default {
next()
}
// Check if we should reload the component content
if (this.$window.shouldReloadContent(from.fullPath, to.fullPath)) {
if (helpers.shouldReloadContent(from.fullPath, to.fullPath)) {
this.setup()
}
},
beforeRouteUpdate(to, from, next) {
// beforeRouteUpdate is called when the static route stays the same
next()
// Check if we should reload the component content
if (this.$window.shouldReloadContent(from.fullPath, to.fullPath)) {
if (helpers.shouldReloadContent(from.fullPath, to.fullPath)) {
this.setup()
}
},
Expand Down Expand Up @@ -566,7 +567,7 @@ export default {
})
}
// Browse to new recipe creation
$this.$window.goTo("/recipe/create")
helpers.goTo("/recipe/create")
})
},
save() {
Expand All @@ -587,7 +588,7 @@ export default {

request
.then((response) => {
$this.$window.goTo(`/recipe/${response.data}`)
helpers.goTo(`/recipe/${response.data}`)
})
.catch((e) => {
// error
Expand Down
3 changes: 2 additions & 1 deletion src/components/RecipeView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@
import moment from "@nextcloud/moment"

import api from "cookbook/js/api-interface"
import helpers from "cookbook/js/helper"

import RecipeImages from "./RecipeImages.vue"
import RecipeIngredient from "./RecipeIngredient.vue"
Expand Down Expand Up @@ -303,7 +304,7 @@ export default {
// beforeRouteUpdate is called when the static route stays the same
next()
// Check if we should reload the component content
if (this.$window.shouldReloadContent(from.fullPath, to.fullPath)) {
if (helpers.shouldReloadContent(from.fullPath, to.fullPath)) {
this.setup()
}
},
Expand Down
3 changes: 2 additions & 1 deletion src/components/SearchResults.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

<script>
import api from "cookbook/js/api-interface"
import helpers from "cookbook/js/helper"

import RecipeList from "./RecipeList.vue"

Expand Down Expand Up @@ -47,7 +48,7 @@ export default {
this.query === "cat" &&
this.$route.params.value === val[1]
) {
this.$window.goTo(`/category/${val[0]}`)
helpers.goTo(`/category/${val[0]}`)
}
})
},
Expand Down
161 changes: 161 additions & 0 deletions src/js/helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
// Check if two routes point to the same component but have different content
function shouldReloadContent(url1, url2) {
if (url1 === url2) {
return false // Obviously should not if both routes are the same
}

const comps1 = url1.split("/")
const comps2 = url2.split("/")

if (comps1.length < 2 || comps2.length < 2) {
return false // Just a failsafe, this should never happen
}

// The route structure is as follows:
// - /{item}/:id View
// - /{item}/:id/edit Edit
// - /{item}/create Create
// If the items are different, then the router automatically handles
// component loading: do not manually reload
if (comps1[1] !== comps2[1]) {
return false
}

// If one of the routes is edit and the other is not
if (comps1.length !== comps2.length) {
// Only reload if changing from edit to create
return comps1.pop() === "create" || comps2.pop() === "create"
}
if (comps1.pop() === "create") {
// But, if we are moving from create to view, do not reload
// the create component
return false
}

// Only options left are that both of the routes are edit or view,
// but not identical, or that we're moving from view to create
// -> reload view
return true
}

// Check if the two urls point to the same item instance
function isSameItemInstance(url1, url2) {
if (url1 === url2) {
return true // Obviously true if the routes are the same
}
const comps1 = url1.split("/")
const comps2 = url2.split("/")
if (comps1.length < 2 || comps2.length < 2) {
return false // Just a failsafe, this should never happen
}
// If the items are different, then the item instance cannot be
// the same either
if (comps1[1] !== comps2[1]) {
return false
}
if (comps1.length < 3 || comps2.length < 3) {
// ID is the third url component, so can't be the same instance if
// either of the urls have less than three components
return false
}
return comps1[2] === comps2[2]
}

// A simple function to sanitize HTML tags
function escapeHTML(text) {
return text.replace(
/["&'<>]/g,
(a) =>
({
"&": "&amp;",
'"': "&quot;",
"'": "&apos;",
"<": "&lt;",
">": "&gt;",
}[a])
)
}

// Fix the decimal separator for languages that use a comma instead of dot
// deprecated
function fixDecimalSeparator(value, io) {
// value is the string value of the number to process
// io is either 'i' as in input or 'o' as in output
if (!value) {
return ""
}
if (io === "i") {
// Check if it's an American number where a comma precedes a dot
// e.g. 12,500.25
if (value.indexOf(".") > value.indexOf(",")) {
return value.replace(",", "")
}
return value.replace(",", ".")
}
if (io === "o") {
return value.toString().replace(".", ",")
}
return ""
}

// This will replace the PHP function nl2br in Vue components
// deprecated
function nl2br(text) {
return text.replace(/\n/g, "<br />")
}

// A simple function that converts a MySQL datetime into a timestamp.
// deprecated
function getTimestamp(date) {
if (date) {
return new Date(date)
}
return null
}

let router

function useRouter(_router) {
router = _router
}
// Push a new URL to the router, essentially navigating to that page.
function goTo(url) {
router.push(url)
}

// Notify the user if notifications are allowed
// deprecated
function notify(title, options) {
if (!("Notification" in window)) {
return
}
if (Notification.permission === "granted") {
// eslint-disable-next-line no-unused-vars
const notification = new Notification(title, options)
} else if (Notification.permission !== "denied") {
Notification.requestPermission((permission) => {
if (!("permission" in Notification)) {
Notification.permission = permission
}
if (permission === "granted") {
// eslint-disable-next-line no-unused-vars
const notification = new Notification(title, options)
} else {
// eslint-disable-next-line no-alert
alert(title)
}
})
}
}

export default {
shouldReloadContent,
isSameItemInstance,
escapeHTML,
fixDecimalSeparator,
nl2br,
getTimestamp,
useRouter,
goTo,
notify,
}
Loading