@@ -77,24 +76,10 @@ const recipeOrderingOptions = ref([
},
]);
-defineProps({
- value: {
- type: Object,
- default: () => ({
- label: t('cookbook', 'Name'),
- iconUp: true,
- recipeProperty: 'name',
- order: 'ascending',
- }),
- required: true,
- },
+const value = defineModel({
+ type: Object,
+ required: true,
});
-
-const orderBy = ref(recipeOrderingOptions.value[0]);
-
-function handleInput() {
- emit('input', orderBy.value);
-}
diff --git a/src/components/Modals/SimpleConfirmModal.vue b/src/components/Modals/SimpleConfirmModal.vue
deleted file mode 100644
index da94c2d03..000000000
--- a/src/components/Modals/SimpleConfirmModal.vue
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-
-
{{ content }}
-
- {{
- t('cookbook', 'Cancel')
- }}
- {{
- t('cookbook', 'OK')
- }}
-
-
-
-
-
-
-
-
-
-
diff --git a/src/components/RecipeEdit.vue b/src/components/RecipeEdit.vue
index 11df3ba25..b388aa2f1 100644
--- a/src/components/RecipeEdit.vue
+++ b/src/components/RecipeEdit.vue
@@ -29,19 +29,19 @@
:field-label="t('cookbook', 'Image')"
/>
}
*/
const savingRecipe = ref(false);
-const prepTime = ref({ time: [0, 0, 0], paddedTime: '' });
-const cookTime = ref({ time: [0, 0, 0], paddedTime: '' });
-const totalTime = ref({ time: [0, 0, 0], paddedTime: '' });
const allCategories = ref([]);
/**
* @type {import('vue').Ref}
@@ -365,31 +361,15 @@ const isNavigationDangerous = computed(
() => !savingRecipe.value && formDirty.value,
);
+const recipeYield = computed({
+ get: () => String(recipe.value.recipeYield),
+ set: (v) => { recipe.value.recipeYield = Number(v); },
+});
+
// ===================
// Watchers
// ===================
-watch(
- () => prepTime.value,
- () => {
- recipe.value.prepTime = prepTime.value.paddedTime;
- },
- { deep: true },
-);
-watch(
- () => cookTime.value,
- () => {
- recipe.value.cookTime = cookTime.value.paddedTime;
- },
- { deep: true },
-);
-watch(
- () => totalTime.value,
- () => {
- recipe.value.totalTime = totalTime.value.paddedTime;
- },
- { deep: true },
-);
watch(
() => selectedKeywords.value,
() => {
@@ -449,7 +429,7 @@ const fetchCategories = async () => {
}
isFetchingCategories.value = false;
} catch (e) {
- await showSimpleAlertModal(t('cookbook', 'Failed to fetch categories'));
+ await showSimpleAlertModal(t('cookbook', 'Error'), t('cookbook', 'Failed to fetch categories'));
if (e && e instanceof Error) {
throw e;
}
@@ -472,7 +452,7 @@ const fetchKeywords = async () => {
}
isFetchingKeywords.value = false;
} catch (e) {
- await showSimpleAlertModal(t('cookbook', 'Failed to fetch keywords'));
+ await showSimpleAlertModal(t('cookbook', 'Error'), t('cookbook', 'Failed to fetch keywords'));
if (e && e instanceof Error) {
throw e;
}
@@ -502,11 +482,12 @@ const save = async () => {
switch (e.response.status) {
case 409:
case 422:
- await showSimpleAlertModal(e.response.data.msg);
+ await showSimpleAlertModal(t('cookbook', 'Error'), e.response.data.msg);
break;
default:
await showSimpleAlertModal(
+ t('cookbook', 'Error'),
/* prettier-ignore */
t('cookbook', 'Unknown answer {status} returned from server. See logs in your browser (press F12).',
{
@@ -518,11 +499,14 @@ const save = async () => {
}
} else if (e.request) {
await showSimpleAlertModal(
+ t('cookbook', 'Error'),
+ /* prettier-ignore */
t('cookbook', 'No answer for request was received.'),
);
log.error(e);
} else {
await showSimpleAlertModal(
+ t('cookbook', 'Error'),
/* prettier-ignore */
t('cookbook','Could not start request to save recipe.'),
);
@@ -537,9 +521,6 @@ const save = async () => {
};
const initEmptyRecipe = () => {
- prepTime.value = { time: [0, 0, 0], paddedTime: '' };
- cookTime.value = { time: [0, 0, 0], paddedTime: '' };
- totalTime.value = { time: [0, 0, 0], paddedTime: '' };
// this.nutrition = {}
recipe.value = {
id: 0,
@@ -571,7 +552,7 @@ const initClone = () => {
recipe.value.id = 0;
// Update
- // eslint-disable-next-line no-template-curly-in-string
+
recipe.value.name = t('cookbook', 'Clone of {name}', {
name: recipe.value.name,
});
@@ -581,38 +562,6 @@ const setup = async () => {
fetchCategories();
fetchKeywords();
if (route.params.id) {
- // Parse time values
- let timeComps = recipe.value.prepTime
- ? recipe.value.prepTime.match(/PT(\d+?)H(\d+?)M(\d+?)S/)
- : null;
- prepTime.value = {
- time: timeComps
- ? [timeComps[1], timeComps[2], timeComps[3]]
- : [0, 0, 0],
- paddedTime: recipe.value.prepTime,
- };
-
- timeComps = recipe.value.cookTime
- ? recipe.value.cookTime.match(/PT(\d+?)H(\d+?)M(\d+?)S/)
- : null;
- cookTime.value = {
- time: timeComps
- ? [timeComps[1], timeComps[2], timeComps[3]]
- : [0, 0, 0],
- paddedTime: recipe.value.cookTime,
- };
-
- timeComps = recipe.value.totalTime
- ? recipe.value.totalTime.match(/PT(\d+?)H(\d+?)M(\d+?)S/)
- : null;
-
- totalTime.value = {
- time: timeComps
- ? [timeComps[1], timeComps[2], timeComps[3]]
- : [0, 0, 0],
- paddedTime: recipe.value.totalTime,
- };
-
selectedKeywords.value = recipe.value.keywords
.split(',')
.map((kw) => kw.trim())
@@ -684,7 +633,7 @@ const loadRecipeData = async () => {
recipe.value = response.data;
await setup();
} catch {
- await showSimpleAlertModal(t('cookbook', 'Loading recipe failed'));
+ await showSimpleAlertModal(t('cookbook', 'Error'), t('cookbook', 'Loading recipe failed'));
// Disable loading indicator
if (legacyStore.loadingRecipe) {
legacyStore.setLoadingRecipe({ recipe: 0 });
@@ -733,7 +682,10 @@ onBeforeRouteLeave(async (to, from, next) => {
// confirm leave. This prevents accidentally losing changes
if (
isNavigationDangerous.value &&
- !(await showSimpleConfirmModal(CONFIRM_MSG))
+ !(await showSimpleConfirmModal(
+ t('cookbook', 'Discard changes?'),
+ CONFIRM_MSG
+ ))
) {
next(false);
} else {
@@ -774,12 +726,12 @@ onMounted(() => {
// Update selectable categories
const idx = allCategories.value.findIndex((c) => c === val[1]);
if (idx >= 0) {
- // eslint-disable-next-line prefer-destructuring
+
allCategories.value[idx] = val[0];
}
// Update selected category if the currently selected was renamed
if (recipe.value.recipeCategory === val[1]) {
- // eslint-disable-next-line prefer-destructuring
+
recipe.value.recipeCategory = val[0];
}
});
diff --git a/src/components/RecipeView/RecipeTimer.vue b/src/components/RecipeView/RecipeTimer.vue
index dcc2e7f15..23187d48e 100644
--- a/src/components/RecipeView/RecipeTimer.vue
+++ b/src/components/RecipeView/RecipeTimer.vue
@@ -90,7 +90,10 @@ const onTimerEnd = () => {
// Start playing audio to alert the user that the timer is up
audio.value.play();
- await showSimpleAlertModal(t('cookbook', 'Cooking time is up!'));
+ await showSimpleAlertModal(
+ t('cookbook', 'Reminder'),
+ t('cookbook', 'Cooking time is up!')
+ );
// Stop audio after the alert is confirmed
audio.value.pause();
diff --git a/src/components/RecipeView/RecipeView.vue b/src/components/RecipeView/RecipeView.vue
index a677f033c..1149c8919 100644
--- a/src/components/RecipeView/RecipeView.vue
+++ b/src/components/RecipeView/RecipeView.vue
@@ -364,7 +364,7 @@ import {
onBeforeRouteUpdate,
useRoute,
useRouter,
-} from 'vue-router/composables';
+} from 'vue-router';
import api from 'cookbook/js/api-interface';
import helpers from 'cookbook/js/helper';
@@ -644,7 +644,7 @@ const setup = async () => {
legacyStore.setPage({ page: 'recipe' });
- await showSimpleAlertModal(t('cookbook', 'Loading recipe failed'));
+ await showSimpleAlertModal(t('cookbook', 'Error'), t('cookbook', 'Loading recipe failed'));
} finally {
isLoading.value = false;
}
diff --git a/src/components/SearchResults.vue b/src/components/SearchResults.vue
index d297f6e87..a67f0fb2a 100644
--- a/src/components/SearchResults.vue
+++ b/src/components/SearchResults.vue
@@ -10,7 +10,7 @@
diff --git a/src/composables/useCookbookDialogs/index.ts b/src/composables/useCookbookDialogs/index.ts
new file mode 100644
index 000000000..1bafa7491
--- /dev/null
+++ b/src/composables/useCookbookDialogs/index.ts
@@ -0,0 +1,40 @@
+import { ref } from 'vue';
+
+const isDialogOpen = ref(false);
+const resolvePromise = ref void)>(null);
+const buttons = ref({});
+const title = ref('');
+const message = ref('');
+const allowClose = ref(true);
+let nextClosingValue = null;
+
+export function useCookbookDialogs() {
+ function show(_title: string, _message: string, _allowClose: boolean = true, _buttons = {}) {
+ title.value = _title;
+ message.value = _message;
+ allowClose.value = _allowClose;
+ buttons.value = _buttons;
+ nextClosingValue = null;
+ isDialogOpen.value = true;
+ return new Promise((resolve) => {
+ resolvePromise.value = resolve;
+ });
+ }
+ function close() {
+ isDialogOpen.value = false;
+ resolvePromise.value?.(nextClosingValue);
+ }
+ function setClosingValue(value: any) {
+ nextClosingValue = value;
+ }
+ return {
+ isDialogOpen,
+ buttons,
+ show,
+ close,
+ setClosingValue,
+ dialogTitle: title,
+ dialogMessage: message,
+ dialogAllowClose: allowClose,
+ };
+}
diff --git a/src/guest.ts b/src/guest.ts
index 26e8d0c85..2ab21a669 100644
--- a/src/guest.ts
+++ b/src/guest.ts
@@ -7,8 +7,8 @@
///
-import Vue from 'vue';
-import { createPinia, PiniaVuePlugin } from 'pinia';
+import { createApp } from 'vue';
+import { createPinia } from 'pinia';
import { useLegacyStore } from './store';
@@ -27,26 +27,28 @@ declare global {
}
}
-Vue.config.devtools = import.meta.env.MODE === 'development';
+const app = createApp({
+ extends: AppInvalidGuest,
+ beforeCreate() {
+ const legacyStore = useLegacyStore();
+ legacyStore.refreshConfig();
+ legacyStore.initializeStore();
+ },
+});
+
+// TODO Check devmode for debugging
+app.config.performance = import.meta.env.MODE === 'development';
// Also make the injections available in Vue components
-Vue.prototype.OC = window.OC;
+app.config.globalProperties.OC = window.OC;
// Pass translation engine to Vue
-Vue.prototype.t = window.t;
-Vue.prototype.n = window.n;
+app.config.globalProperties.t = window.t;
+app.config.globalProperties.n = window.n;
-Vue.use(PiniaVuePlugin);
const pinia = createPinia();
+app.use(pinia);
// Start the app once document is done loading
-const App = Vue.extend(AppInvalidGuest);
-new App({
- // router,
- pinia,
- beforeCreate() {
- const legacyStore = useLegacyStore();
- legacyStore.refreshConfig();
- legacyStore.initializeStore();
- },
-}).$mount('#content');
+app.mount('#content');
+
diff --git a/src/js/LogicOperators/AndOperator.js b/src/js/LogicOperators/AndOperator.js
index a7f0fddbe..c51a964d6 100644
--- a/src/js/LogicOperators/AndOperator.js
+++ b/src/js/LogicOperators/AndOperator.js
@@ -5,7 +5,7 @@ import BinaryOperator from './BinaryOperator';
* @extends BinaryOperator
*/
class AndOperator extends BinaryOperator {
- // eslint-disable-next-line class-methods-use-this
+
get toString() {
return 'AND';
}
@@ -16,7 +16,7 @@ class AndOperator extends BinaryOperator {
* @param {boolean} current - The current value to apply.
* @returns {boolean} The result after applying the AND operation.
*/
- // eslint-disable-next-line class-methods-use-this
+
apply(result, current) {
return result && current;
}
diff --git a/src/js/LogicOperators/BinaryOperator.js b/src/js/LogicOperators/BinaryOperator.js
index ec0e82e74..72a828043 100644
--- a/src/js/LogicOperators/BinaryOperator.js
+++ b/src/js/LogicOperators/BinaryOperator.js
@@ -3,7 +3,7 @@
* @abstract
*/
class BinaryOperator {
- // eslint-disable-next-line class-methods-use-this
+
get toString() {
return 'Abstract operation base class';
}
@@ -24,7 +24,7 @@ class BinaryOperator {
* @param {boolean} current - The current value to apply.
* @throws {Error} Method 'apply' must be implemented by subclasses.
*/
- // eslint-disable-next-line no-unused-vars,class-methods-use-this
+
apply(result, current) {
throw new Error("Method 'apply' must be implemented by subclasses");
}
diff --git a/src/js/LogicOperators/OrOperator.js b/src/js/LogicOperators/OrOperator.js
index cd6448fa5..90642dea5 100644
--- a/src/js/LogicOperators/OrOperator.js
+++ b/src/js/LogicOperators/OrOperator.js
@@ -5,7 +5,7 @@ import BinaryOperator from './BinaryOperator';
* @extends BinaryOperator
*/
class OrOperator extends BinaryOperator {
- // eslint-disable-next-line class-methods-use-this
+
get toString() {
return 'OR';
}
@@ -16,7 +16,7 @@ class OrOperator extends BinaryOperator {
* @param {boolean} current - The current value to apply.
* @returns {boolean} The result after applying the OR operation.
*/
- // eslint-disable-next-line class-methods-use-this
+
apply(result, current) {
return result || current;
}
diff --git a/src/js/RecipeFilters/RecipeFilter.js b/src/js/RecipeFilters/RecipeFilter.js
index 4d25b52e2..af7f532f9 100644
--- a/src/js/RecipeFilters/RecipeFilter.js
+++ b/src/js/RecipeFilters/RecipeFilter.js
@@ -22,7 +22,7 @@ class RecipeFilter {
* @param {Object} recipe - The recipe object to be filtered.
* @throws {Error} Method 'filter' must be implemented by subclasses.
*/
- // eslint-disable-next-line class-methods-use-this,no-unused-vars
+
filter(recipe) {
throw new Error("Method 'filter' must be implemented by subclasses");
}
diff --git a/src/js/RecipeFilters/RecipeNamesFilter.js b/src/js/RecipeFilters/RecipeNamesFilter.js
index 4987bdb13..4fc00ca38 100644
--- a/src/js/RecipeFilters/RecipeNamesFilter.js
+++ b/src/js/RecipeFilters/RecipeNamesFilter.js
@@ -24,7 +24,7 @@ class RecipeNamesFilter extends RecipeFilter {
this.filterMode = filterMode;
}
- // eslint-disable-next-line class-methods-use-this
+
get fuseOptions() {
return {
isCaseSensitive: false,
diff --git a/src/js/api-interface.js b/src/js/api-interface.js
index 9150bd61f..31b324de0 100644
--- a/src/js/api-interface.js
+++ b/src/js/api-interface.js
@@ -1,4 +1,3 @@
-import Vue from 'vue';
import axios from '@nextcloud/axios';
import { generateUrl } from '@nextcloud/router';
@@ -7,9 +6,17 @@ const instance = axios.create();
const baseUrl = `${generateUrl('apps/cookbook')}/webapp`;
+const apiInterfaceConfig = {
+ app: null,
+};
+
+export function setApp(app) {
+ apiInterfaceConfig.app = app;
+}
+
// Add a debug log for every request
instance.interceptors.request.use((config) => {
- Vue.$log.debug(
+ apiInterfaceConfig.app.$log.debug(
`[axios] Making "${config.method}" request to "${config.url}"`,
config,
);
@@ -18,7 +25,7 @@ instance.interceptors.request.use((config) => {
contentType &&
!['application/json', 'text/json'].includes(contentType)
) {
- Vue.$log.warn(
+ apiInterfaceConfig.app.$log.warn(
`[axios] Request to "${config.url}" is using Content-Type "${contentType}", not JSON`,
);
}
@@ -27,11 +34,11 @@ instance.interceptors.request.use((config) => {
instance.interceptors.response.use(
(response) => {
- Vue.$log.debug('[axios] Received response', response);
+ apiInterfaceConfig.app.$log.debug('[axios] Received response', response);
return response;
},
(error) => {
- Vue.$log.warn('[axios] Received error', error);
+ apiInterfaceConfig.app.$log.warn('[axios] Received error', error);
return Promise.reject(error);
},
);
diff --git a/src/js/helper.js b/src/js/helper.js
index 34341f017..5dcb5bcf3 100644
--- a/src/js/helper.js
+++ b/src/js/helper.js
@@ -148,7 +148,6 @@ function notify(title, options) {
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) => {
@@ -156,10 +155,9 @@ function notify(title, options) {
Notification.permission = permission;
}
if (permission === 'granted') {
- // eslint-disable-next-line no-unused-vars
const notification = new Notification(title, options);
} else {
- showSimpleAlertModal(title);
+ showSimpleAlertModal(title, '');
}
});
}
diff --git a/src/js/logging.js b/src/js/logging.js
index 0491ad004..1e4a4b439 100644
--- a/src/js/logging.js
+++ b/src/js/logging.js
@@ -1,5 +1,4 @@
-// TODO: Switch to vuejs3-logger when we switch to Vue 3
-import VueLogger from 'vuejs-logger';
+import VueLogger from 'vuejs3-logger';
import moment from '@nextcloud/moment';
const DEFAULT_LOG_LEVEL = 'info';
@@ -51,10 +50,10 @@ const isEnabled = () => {
return JSON.parse(userValue) ?? DEFAULT;
};
-export default function setupLogging(Vue) {
+export default function setupLogging(app) {
const logLevel = localStorage.getItem(KEY_LOG_LEVEL) ?? DEFAULT_LOG_LEVEL;
- Vue.use(VueLogger, {
+ app.use(VueLogger, {
isEnabled: isEnabled(),
logLevel,
stringifyArguments: false,
@@ -64,7 +63,7 @@ export default function setupLogging(Vue) {
showConsoleColors: true,
});
- Vue.$log.info(`Setting up logging with log level ${logLevel}`);
+ app.$log.info(`Setting up logging with log level ${logLevel}`);
}
export function enableLogging() {
diff --git a/src/js/modals.js b/src/js/modals.js
index 6bb1e16cc..34eb3fd6b 100644
--- a/src/js/modals.js
+++ b/src/js/modals.js
@@ -1,15 +1,35 @@
-import { create } from 'vue-modal-dialogs';
-
-import SimpleAlertModal from '../components/Modals/SimpleAlertModal.vue';
-import SimpleConfirmModal from '../components/Modals/SimpleConfirmModal.vue';
-
-export const showSimpleAlertModal = create(
- SimpleAlertModal,
- 'content',
- 'title',
-);
-export const showSimpleConfirmModal = create(
- SimpleConfirmModal,
- 'content',
- 'title',
-);
+// import { create } from 'vue-modal-dialogs';
+// TODO Add real alternative
+
+import { useCookbookDialogs } from 'cookbook/composables/useCookbookDialogs';
+
+const { show, setClosingValue } = useCookbookDialogs();
+
+export function showSimpleAlertModal(title, msg) {
+ return show(title, msg, true, [
+ {
+ label: t('cookbook', 'Dismiss'),
+ variant: 'primary',
+ },
+ ]);
+}
+
+export function showSimpleConfirmModal(title, msg) {
+ return show(title, msg, false, [
+ {
+ label: t('cookbook', 'Cancel'),
+ variant: 'secondary',
+ callback: () => {
+ setClosingValue(false);
+ },
+ },
+ {
+ label: t('cookbook', 'OK'),
+ variant: 'primary',
+ callback: () => {
+ setClosingValue(true);
+ },
+ },
+ ]);
+ // return confirm('showSimpleConfirmModal', msg);
+}
diff --git a/src/js/utils/string-utils.js b/src/js/utils/string-utils.js
index 67b25305f..31f68dcd9 100644
--- a/src/js/utils/string-utils.js
+++ b/src/js/utils/string-utils.js
@@ -8,7 +8,6 @@
* @param substituteLetters Substitute some letters by similar looking letters.
* @returns {string} Normalized string value.
*/
-// eslint-disable-next-line import/prefer-default-export
export function normalize(
str,
toLowercase = true,
diff --git a/src/main.ts b/src/main.ts
index 375e67f00..ee99262ca 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -10,21 +10,24 @@
// Markdown
import VueShowdown from 'vue-showdown';
-import Vue from 'vue';
+import { createApp, h } from 'vue';
-import * as ModalDialogs from 'vue-modal-dialogs';
+// TODO
+// import * as ModalDialogs from 'vue-modal-dialogs';
-import { createPinia, PiniaVuePlugin } from 'pinia';
+import { createPinia } from 'pinia';
import helpers from './js/helper';
import setupLogging from './js/logging';
-import router from './router';
+import { createMainRouter, getRouter } from './router';
import { useLegacyStore } from './store';
+import { setApp as setAppInApiInterface } from 'cookbook/js/api-interface';
import AppMain from './components/AppMain.vue';
-Vue.config.devtools = import.meta.env.MODE === 'development';
+console.log('Mode: ', import.meta.env.MODE);
+
declare global {
interface Window {
@@ -52,44 +55,64 @@ declare module 'vue/types/vue' {
}
}
+const app = createApp(AppMain);
+
+const app2 = createApp({
+ // template: 'hello
',
+ render() {
+ return h('div', 'hello');
+ }
+});
+
+// TODO Check dev mode for debugging
+app.config.performance = import.meta.env.MODE === 'development';
+
+createMainRouter();
+const router = getRouter();
+app.use(router);
+
+// Register helper functions
helpers.useRouter(router);
// A simple function to sanitize HTML tags
-// eslint-disable-next-line no-param-reassign
+
window.escapeHTML = helpers.escapeHTML;
// Also make the injections available in Vue components
-Vue.prototype.$window = window;
-Vue.prototype.OC = window.OC;
+app.config.globalProperties.$window = window;
+app.config.globalProperties.OC = window.OC;
// Markdown for Vue
-Vue.use(VueShowdown, {
+app.use(VueShowdown, {
// set default flavor for Markdown
flavor: 'vanilla',
});
// TODO: Equivalent library for Vue3 when we make that transition:
// https://github.com/rlemaigre/vue3-promise-dialog
-Vue.use(ModalDialogs);
+// TODO Vue.use(ModalDialogs);
-setupLogging(Vue);
+setupLogging(app);
+setAppInApiInterface(app);
// Pass translation engine to Vue
-Vue.prototype.t = window.t;
-Vue.prototype.n = window.n;
+app.config.globalProperties.t = window.t;
+app.config.globalProperties.n = window.n;
-Vue.use(PiniaVuePlugin);
const pinia = createPinia();
+app.use(pinia);
+
+// Only create the store after `use`ing the pinia store
+const legacyStore = useLegacyStore();
+legacyStore.refreshConfig();
+legacyStore.initializeStore();
// Start the app once document is done loading
-Vue.$log.info('Main is done. Creating App.');
-const App = Vue.extend(AppMain);
-new App({
- router,
- pinia,
- beforeCreate() {
- const legacyStore = useLegacyStore();
- legacyStore.refreshConfig();
- legacyStore.initializeStore();
- },
-}).$mount('#content');
+// app.$log.info('Main is done. Creating App.');
+
+
+// app2.use(pinia);
+// app2.use(router);
+
+app.mount('#content');
+
diff --git a/src/router/index.ts b/src/router/index.ts
index 73d2cbef8..6d994c1e1 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -4,8 +4,7 @@
* ----------------------
* @license AGPL3 or later
*/
-import Vue from 'vue';
-import VueRouter from 'vue-router';
+import { createRouter, createWebHashHistory, Router } from 'vue-router';
import Index from '../components/AppIndex.vue';
import NotFound from '../components/NotFound.vue';
@@ -13,8 +12,6 @@ import RecipeView from '../components/RecipeView/RecipeView.vue';
import RecipeEdit from '../components/RecipeEdit.vue';
import Search from '../components/SearchResults.vue';
-Vue.use(VueRouter);
-
// The router will try to match routers in a descending order.
// Routes that share the same root, must be listed from the
// most descriptive to the least descriptive, e.g.
@@ -68,9 +65,20 @@ const routes = [
{ path: '/', name: 'index', component: Index },
// Anything not matched goes to NotFound
- { path: '*', name: 'not-found', component: NotFound },
+ { path: '/:pathMatch(.+)*', name: 'not-found', component: NotFound },
];
-export default new VueRouter({
- routes,
-});
+let _router: Router;
+
+export function createMainRouter() {
+ _router = createRouter({
+ history: createWebHashHistory(),
+ routes,
+ });
+}
+
+export function getRouter() {
+ return _router;
+}
+
+
diff --git a/src/store/index.ts b/src/store/index.ts
index 2507b8830..45c15433d 100644
--- a/src/store/index.ts
+++ b/src/store/index.ts
@@ -262,5 +262,4 @@ const useLegacyStore = defineStore('legacyStore', {
},
});
-// eslint-disable-next-line import/prefer-default-export
export { useLegacyStore };
diff --git a/src/tests/unit/utils/applyRecipeFilters.test.js b/src/tests/unit/utils/applyRecipeFilters.test.js
index 0ac9ccbbd..6e553b70b 100644
--- a/src/tests/unit/utils/applyRecipeFilters.test.js
+++ b/src/tests/unit/utils/applyRecipeFilters.test.js
@@ -1,6 +1,5 @@
-// eslint-disable-next-line import/no-extraneous-dependencies
import { jest } from '@jest/globals';
-// eslint-disable-next-line max-classes-per-file
+
import applyFilters from '../../../js/utils/applyRecipeFilters';
import RecipeFilter from '../../../js/RecipeFilters/RecipeFilter';
import { AndOperator } from '../../../js/LogicOperators';