Skip to content
Open
Show file tree
Hide file tree
Changes from 14 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
3 changes: 3 additions & 0 deletions .changelog/current/2507-migrate-to-vite.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Maintenance

- Migration of frontend build system from webpack to Vite
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ cookbook.tar.gz

/.php-cs-fixer.cache
/.eslintcache
/css


# Built js package
js/*
Expand Down
2 changes: 2 additions & 0 deletions lib/Controller/MainController.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public function index(): TemplateResponse {
$this->userFolder->getFolder();
} catch (UserFolderNotWritableException $ex) {
Util::addScript('cookbook', 'cookbook-guest');
Util::addStyle('cookbook', 'cookbook-guest');
return new TemplateResponse($this->appName, 'invalid_guest');
}

Expand All @@ -59,6 +60,7 @@ public function index(): TemplateResponse {
$this->dbCacheService->triggerCheck();

Util::addScript('cookbook', 'cookbook-main');
Util::addStyle('cookbook', 'cookbook-main');

return new TemplateResponse($this->appName, 'index'); // templates/index.php
}
Expand Down
16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@
"bugs": {
"url": "https://github.com/nextcloud/nextcloud-cookbook/issues"
},
"type": "module",
"main": "src/main.ts",
"scripts": {
"build": "npx webpack --node-env production --progress --config webpack.config.js",
"build-bundle-analyzer": "npx webpack --node-env development --progress --config webpack.devel.js --env BUNDLE_ANALYZER=true",
"build-dev": "npx webpack --node-env development --progress --config webpack.devel.js",
"build": "vite build",
"build-dev": "vite --mode development build",
"bundle-analyzer": "vite-bundle-visualizer --open true ",
"ci-test": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" npx jest --ci",
"dev": "npx webpack --node-env development --progress --watch --config webpack.devel.js",
"dev": "vite --mode development build --watch",
"eslint": "npx eslint --cache --cache-strategy content 'src/**/*.{vue,js,ts}'",
"eslint-fix": "npx eslint --cache --cache-strategy content --fix 'src/**/*.{vue,js,ts}'",
"package-lint": "npx prettier-package-json --write ./package.json",
"prettier": "npx prettier --check src",
"prettier-fix": "npx prettier --write src",
"serve": "npx webpack serve --node-env development --progress --config webpack.config.js --env dev_server --allowed-hosts all",
"stylelint": "stylelint src",
"stylelint-fix": "stylelint --fix src",
"test": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" npx jest"
Expand Down Expand Up @@ -57,15 +57,14 @@
"@nextcloud/babel-config": "^1.0.0",
"@nextcloud/browserslist-config": "^3.0.0",
"@nextcloud/stylelint-config": "^3.0.1",
"@nextcloud/webpack-vue-config": "^6.0.0",
"@nextcloud/vite-config": "^1.7.1",
"@typescript-eslint/eslint-plugin": "^7.0.0",
"@typescript-eslint/parser": "^7.8",
"@vue/cli-plugin-typescript": "~5.0.8",
"@vue/eslint-config-typescript": "^13.0.0",
"@vue/vue2-jest": "^29.2.6",
"babel-jest": "^29.7.0",
"check-peer-dependencies": "^4.3.0",
"clean-webpack-plugin": "^4.0.0",
"eslint": "^8.53.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-airbnb-typescript": "^18.0.0",
Expand All @@ -82,7 +81,8 @@
"stylelint-scss": "^6.11.1",
"ts-loader": "^9.5.1",
"typescript": "~5.9.2",
"vue-template-compiler": "^2.7.15",
"vite": "^7.1.8",
"vite-bundle-visualizer": "^1.2.1",
"webpack": "^5.89.0",
"webpack-bundle-analyzer": "^4.9.1",
"webpack-cli": "^6.0.1",
Expand Down
6 changes: 3 additions & 3 deletions src/components/AppControls/AppControls.vue
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
:title="t('cookbook', 'Creating new recipe')"
/>
</div>
{{/* Primary buttons */}}
<!-- Primary buttons -->
<NcButton
v-if="isRecipe"
type="primary"
Expand Down Expand Up @@ -112,7 +112,7 @@
{{ t('cookbook', 'Search') }}
</NcActionInput>
</NcActions>
{{/* Overflow buttons (3-dot menu) */}}
<!-- Overflow buttons (3-dot menu) -->
<NcActions
v-if="isRecipe || isEdit"
:force-menu="true"
Expand Down Expand Up @@ -296,7 +296,7 @@ const deleteRecipe = async () => {
// Confirm delete
if (
!(await showSimpleConfirmModal(
// prettier-ignore
/* prettier-ignore */
t('cookbook', 'Are you sure you want to delete this recipe?'),
))
) {
Expand Down
2 changes: 1 addition & 1 deletion src/components/AppInvalidGuest.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</div>
<div>
{{
// prettier-ignore
/* prettier-ignore */
t("cookbook", "You are logged in with a guest account. Therefore, you are not allowed to generate arbitrary files and folders on this Nextcloud instance. To be able to use the Cookbook app as a guest, you need to specify a folder where all recipes are stored. You will need write permission to this folder." )
}}
</div>
Expand Down
10 changes: 5 additions & 5 deletions src/components/AppNavi.vue
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ const openCategory = async (idx) => {
} catch (e) {
cat.recipes = [];
await showSimpleAlertModal(
// prettier-ignore
/* prettier-ignore */
t('cookbook', 'Failed to load category {category} recipes',
{
category: cat.name,
Expand Down Expand Up @@ -218,7 +218,7 @@ const categoryUpdateName = async (idx, newName) => {
emitter.emit('categoryRenamed', [newName, oldName]);
} catch (e) {
await showSimpleAlertModal(
// prettier-ignore
/* prettier-ignore */
t('cookbook','Failed to update name of category "{category}"',
{
category: oldName,
Expand Down Expand Up @@ -266,15 +266,15 @@ const downloadRecipe = async () => {
// eslint-disable-next-line no-console
console.error(e2);
await showSimpleAlertModal(
// prettier-ignore
/* prettier-ignore */
t('cookbook','The server reported an error. Please check.'),
);
}
} else {
// eslint-disable-next-line no-console
console.error(e2);
await showSimpleAlertModal(
// prettier-ignore
/* prettier-ignore */
t('cookbook', 'Could not query the server. This might be a network problem.'),
);
}
Expand Down Expand Up @@ -305,7 +305,7 @@ const getCategories = async () => {
recipes: [
{
id: 0,
// prettier-ignore
/* prettier-ignore */
name: t('cookbook','Loading category recipes …'),
},
],
Expand Down
2 changes: 1 addition & 1 deletion src/components/FormComponents/EditImageField.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
type="text"
:value="value"
:placeholder="
// prettier-ignore
/* prettier-ignore */
t('cookbook', 'Enter URL or select from your Nextcloud instance on the right')
"
@input="$emit('input', $event.target.value)"
Expand Down
2 changes: 1 addition & 1 deletion src/components/List/EmptyList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
</div>
<div>
{{
// prettier-ignore
/* prettier-ignore */
t('cookbook', 'To get started, you may use the text box in the left navigation bar to import a new recipe. Click below to create a recipe from scratch.',)
}}
</div>
Expand Down
6 changes: 4 additions & 2 deletions src/components/List/RecipeFilterControlsInline.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
<div class="form-group">
<RecipeSortSelect
v-model="localOrderBy"
aria-label="t('cookbook', 'Show settings for filtering recipe list')"
:aria-label="
t('cookbook', 'Show settings for filtering recipe list')
"
:label="t('cookbook', 'Order')"
class="mr-4"
:title="t('cookbook', 'Show filter settings')"
Expand Down Expand Up @@ -143,7 +145,7 @@
<!-- Keep button together in a line with the last input so it does not get lonely -->
<NcButton type="tertiary" @click="clearFilters">
{{
// TRANSLATORS Button text for applying recipe-filter values
/* TRANSLATORS Button text for applying recipe-filter values */
t('cookbook', 'Clear')
}}
</NcButton>
Expand Down
4 changes: 2 additions & 2 deletions src/components/List/RecipeFilterControlsModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@
<div class="d-flex flex-row justify-end mt-4">
<NcButton type="tertiary" @click="clearFilters">
{{
// TRANSLATORS Button text for applying recipe-filter values
/* TRANSLATORS Button text for applying recipe-filter values */
t('cookbook', 'Clear')
}}
</NcButton>
Expand All @@ -185,7 +185,7 @@
@click="submitFilters"
>
{{
// TRANSLATORS Button text for applying recipe-filter values
/* TRANSLATORS Button text for applying recipe-filter values */
t('cookbook', 'Apply')
}}
</NcButton>
Expand Down
2 changes: 1 addition & 1 deletion src/components/List/RecipeListKeywordCloud.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
:name="keywordObj.name"
:count="keywordObj.count"
:title="
// prettier-ignore
/* prettier-ignore */
t('cookbook','Keyword not contained in visible recipes')
"
class="keyword disabled"
Expand Down
12 changes: 6 additions & 6 deletions src/components/Modals/SettingsDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
/>
<label for="filters">
{{
// prettier-ignore
/* prettier-ignore */
t('cookbook', 'Show filters and sorting in recipe lists')
}}
</label>
Expand All @@ -89,7 +89,7 @@
<fieldset>
<legend class="settings-info-blocks__legend">
{{
// prettier-ignore
/* prettier-ignore */
t('cookbook', 'Control which blocks of information are shown in the recipe view. If you do not use some features and find them distracting, you may hide them.')
}}
</legend>
Expand Down Expand Up @@ -164,7 +164,7 @@
>
<legend class="settings-info-blocks__legend">
{{
// prettier-ignore
/* prettier-ignore */
t('cookbook', 'This allows to temporarily enable logging in the browser console in case of problems. You will not need these settings by default.')
}}
</legend>
Expand Down Expand Up @@ -273,7 +273,7 @@ watch(
// Should this check the response of the query? To catch some errors that redirect the page
} catch {
await showSimpleAlertModal(
// prettier-ignore
/* prettier-ignore */
t('cookbook','Could not set preference for image printing'),
);
printImage.value = oldVal;
Expand Down Expand Up @@ -308,7 +308,7 @@ watch(
await store.dispatch('refreshConfig');
} catch {
await showSimpleAlertModal(
// prettier-ignore
/* prettier-ignore */
t('cookbook','Could not set recipe update interval to {interval}',
{
interval: newVal,
Expand Down Expand Up @@ -368,7 +368,7 @@ const pickRecipeFolder = () => {
})
.catch(() =>
showSimpleAlertModal(
// prettier-ignore
/* prettier-ignore */
t('cookbook','Could not set recipe folder to {path}',
{
path
Expand Down
12 changes: 6 additions & 6 deletions src/components/RecipeEdit.vue
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
<NcActionButton
class="btn-enable-recipe-yield"
:aria-label="
// prettier-ignore
/* prettier-ignore */
t('cookbook', 'Toggle if the number of servings is present')
"
@click="toggleShowRecipeYield"
Expand Down Expand Up @@ -174,7 +174,7 @@ const log = getCurrentInstance().proxy.$log;
const route = useRoute();
const store = useStore();

// prettier-ignore
/* prettier-ignore */
const CONFIRM_MSG = t('cookbook', 'You have unsaved changes! Do you still want to leave?');

// ===================
Expand Down Expand Up @@ -259,7 +259,7 @@ const availableNutritionFields = ref([
{
key: 'calories',
label: t('cookbook', 'Calories'),
// prettier-ignore
/* prettier-ignore */
placeholder: t('cookbook','E.g.: 450 kcal (amount & unit)'),
},
{
Expand Down Expand Up @@ -295,7 +295,7 @@ const availableNutritionFields = ref([
{
key: 'servingSize',
label: t('cookbook', 'Serving size'),
// prettier-ignore
/* prettier-ignore */
placeholder: t('cookbook','Enter serving size (volume or mass)'),
},
{
Expand Down Expand Up @@ -503,7 +503,7 @@ const save = async () => {

default:
await showSimpleAlertModal(
// prettier-ignore
/* prettier-ignore */
t('cookbook', 'Unknown answer {status} returned from server. See logs in your browser (press F12).',
{
status: e.response.status,
Expand All @@ -519,7 +519,7 @@ const save = async () => {
log.error(e);
} else {
await showSimpleAlertModal(
// prettier-ignore
/* prettier-ignore */
t('cookbook','Could not start request to save recipe.'),
);
log.error(e);
Expand Down
4 changes: 2 additions & 2 deletions src/components/RecipeView/RecipeView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
:key="'keyw' + idx"
:name="keyword"
:title="
// prettier-ignore
/* prettier-ignore */
t('cookbook','Search recipes with this keyword')
"
@keyword-clicked="keywordClicked(keyword)"
Expand Down Expand Up @@ -183,7 +183,7 @@
<hr />
<span class="icon-error" />
{{
// prettier-ignore
/* prettier-ignore */
t("cookbook", "The ingredient cannot be recalculated due to incorrect syntax. Please ensure the syntax follows this format: amount unit ingredient and that a specific number of portions is set for this function to work correctly. Examples: 200 g carrots or 1 pinch of salt.")
}}
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/components/SearchResults.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@

// Methods
const setup = async () => {
// TODO: This is a mess of different implementation styles, needs cleanup

Check warning on line 61 in src/components/SearchResults.vue

View workflow job for this annotation

GitHub Actions / Check for added todo messages

Found TODO: This is a mess of different implementation styles, needs cleanup
if (props.query === 'name') {
// Search by name
// TODO

Check warning on line 64 in src/components/SearchResults.vue

View workflow job for this annotation

GitHub Actions / Check for added todo messages

Found TODO
} else if (props.query === 'tags') {
// Search by tags
const tags = route.params.value;
Expand All @@ -72,7 +72,7 @@
} catch (e) {
results.value = [];
await showSimpleAlertModal(
// prettier-ignore
/* prettier-ignore */
t('cookbook', 'Failed to load recipes with keywords: {tags}',
{
tags,
Expand All @@ -96,7 +96,7 @@
} catch (e) {
results.value = [];
await showSimpleAlertModal(
// prettier-ignore
/* prettier-ignore */
t('cookbook', 'Failed to load category {category} recipes',
{
category: cat,
Expand Down
15 changes: 0 additions & 15 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,6 @@ declare module 'vue/types/vue' {
}
}

const isDevServer = process.env.WEBPACK_DEV_SERVER;

// eslint-disable-next-line camelcase,no-undef
if (isDevServer || false) {
// eslint-disable-next-line camelcase,no-undef
__webpack_public_path__ = 'http://127.0.0.1:3000/apps/cookbook/js/';
}

// eslint-disable-next-line camelcase,no-undef
__webpack_public_path__ = `${linkTo('cookbook', 'js')}/`;

// Fetch Nextcloud nonce identifier for dynamic script loading
// eslint-disable-next-line camelcase,no-undef
__webpack_nonce__ = btoa(window.OC.requestToken);

helpers.useRouter(router);

// A simple function to sanitize HTML tags
Expand Down
File renamed without changes.
Loading
Loading