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

Introduce VueJS, make not-grocy a SPA. #25

Draft
wants to merge 17 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 2 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
36 changes: 32 additions & 4 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
/* eslint-disable indent */
// eslint-disable-next-line no-undef
module.exports = {
env: {
browser: true,
es2021: true
},
extends: [
'plugin:vue/essential',
"eslint:recommended"
"eslint:recommended",
],
parserOptions: {
ecmaVersion: 12,
sourceType: 'module'
},
plugins: [
'vue'
'vue',
'@typescript-eslint',
],
globals: {
// from vendor.js:
Expand All @@ -28,5 +31,30 @@ module.exports = {
"indent": ["error", "tab"],
"brace-style": ["error", "allman", { "allowSingleLine": true }],
"semi": ["error", "always", { "omitLastInOneLineBlock": true }],
}
}
},
overrides: [
{
files: ["*.ts", "*.tsx"],
parser: '@typescript-eslint/parser',
extends: [
'plugin:vue/essential',
"eslint:recommended",
'plugin:@typescript-eslint/recommended',
],
parserOptions: {
project: "./tsconfig.json",
}
},
{
files: ["*.vue"],
parser: "vue-eslint-parser",
parserOptions: {
parser: '@typescript-eslint/parser',
vueFeatures: {
filter: false,
interpolationAsNonHTML: true
}
}
}
]
};
5 changes: 4 additions & 1 deletion .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
{
"recommendations": []
"recommendations": [
"octref.vetur",
"dbaeumer.vscode-eslint"
]
}
8 changes: 8 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,12 @@
"php-cs-fixer.formatHtml": true,
"php-cs-fixer.autoFixBySemicolon": true,
"php-cs-fixer.onsave": true,
"eslint.validate": [
"javascript",
"typescript",
"vue"
],
"eslint.options": {
"useEslintrc": true,
}
}
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ watch:
${SASS} ${SASSFLAGS} --watch ${SASS_INPUT} ${TMPSASS} & \
${POSTCSS} ${TMPSASS} --config . -o ${SASS_OUTPUT} --watch & \
${ROLLUP} --watch --no-watch.clearScreen --config ${RFLAGS} & \
${ROLLUP} --watch --no-watch-clearScreen --config rollup.vue.js ${RFLAGS} & \
${PHP} ${RUNFLAGS} & \
trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT & \
wait
Expand All @@ -141,6 +142,10 @@ css: yarn.lock | $(OBJDIRS)
${SASS} ${SASSFLAGS} ${SASS_INPUT} ${SASS_OUTPUT}
${POSTCSS} --config . ${SASS_OUTPUT} -r

.PHONY=frontend
frontend:
${ROLLUP} --config rollup.vue.js ${RFLAGS}


# To bundle all resources, there are a few prerequisites:
# First, the public output folders need to be created.
Expand Down
14 changes: 14 additions & 0 deletions js/App.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<template>
<p> lol</p>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
data()
{
return {};
}
});
</script>
33 changes: 17 additions & 16 deletions js/grocy.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
/* eslint-disable @typescript-eslint/no-this-alias */
// todo: axe some stuff from here for better tree-shaking. also brr, side effects.
import './vendor';
import { GrocyApi } from './lib/api';
import { RefreshContextualTimeago } from './configs/timeago';
import { setDatatableDefaults } from './configs/datatable';
import { GrocyFrontendHelpers } from './helpers/frontend';
import { setInitialGlobalState } from './configs/globalstate';
import { WakeLock } from './lib/WakeLock';
import { UISound } from './lib/UISound';
import { Nightmode } from './lib/nightmode';
import { HeaderClock } from './helpers/clock';
import { BoolVal } from './helpers/extensions';
import './legacy/vendor';
import { GrocyApi } from './legacy/lib/api';
import { RefreshContextualTimeago } from './legacy/configs/timeago';
import { setDatatableDefaults } from './legacy/configs/datatable';
import { GrocyFrontendHelpers } from './legacy/helpers/frontend';
import { setInitialGlobalState } from './legacy/configs/globalstate';
import { WakeLock } from './legacy/lib/WakeLock';
import { UISound } from './legacy/lib/UISound';
import { Nightmode } from './legacy/lib/nightmode';
import { HeaderClock } from './legacy/helpers/clock';
import { BoolVal } from './legacy/helpers/extensions';
import Translator from 'gettext-translator';
import { register as timeagoRegisterLang } from 'timeago.js';
import * as timeagoLangs from 'timeago.js/lib/lang';
import { WindowMessageBag } from './helpers/messagebag';
import * as components from './components';
import { WindowMessageBag } from './legacy/helpers/messagebag';
import * as components from './legacy/components';
import * as uuid from 'uuid';
import * as views from './viewjs';
import { GrocyProxy } from './lib/proxy'; //import { $ } from 'jquery';
import * as views from './legacy/viewjs';
import { GrocyProxy } from './legacy/lib/proxy'; //import { $ } from 'jquery';

import moment from 'moment';
import './helpers/string';
import './legacy/helpers/string';

class GrocyClass
{
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
14 changes: 14 additions & 0 deletions js/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { createApp } from 'vue';
import router from './router';
import App from './App.vue';

// PrimeVue components
import PrimeVue from 'primevue/config';

const app = createApp(App);

app.use(PrimeVue);
app.use(router);


app.mount("#app");
11 changes: 11 additions & 0 deletions js/pages/Stock/Overview.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<template>
<p> Hi! </p>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
// type inference enabled
});
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { openBlock as _openBlock, createBlock as _createBlock } from "vue";

export function render(_ctx, _cache, $props, $setup, $data, $options)
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems like a build artifact.

Copy link
Owner Author

Choose a reason for hiding this comment

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

Yes. At some point I completely messed up the rollup config, and that's that. Also, eslint breaks in the vue-rollup config. I have no idea why. Linting in VS Code or with the command line works, so I am not concerned.

{
return (_openBlock(), _createBlock("p", null, " Hi! "));
}
19 changes: 19 additions & 0 deletions js/router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { createRouter, createWebHashHistory } from 'vue-router';
import StockOverview from './pages/Stock/Overview.vue';
const routes = [
{
path: '/',
name: 'Home',
component: StockOverview
},
];
const router = createRouter({
history: createWebHashHistory(),
routes
});
export default router;
//# sourceMappingURL=router.js.map
//# sourceMappingURL=router.js.map
//# sourceMappingURL=router.js.map
//# sourceMappingURL=router.js.map
//# sourceMappingURL=router.js.map
7 changes: 7 additions & 0 deletions js/shims-vue.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/ban-types */
declare module '*.vue' {
import type { DefineComponent } from 'vue';
const component: DefineComponent<{}, {}, any>;
export default component;
}
16 changes: 14 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
"jquery-serializejson": "^2.9.0",
"moment": "^2.27.0",
"nosleep.js": "^0.11.0",
"primeicons": "^4.1.0",
"primevue": "^3.5.1",
"sass": "^1.35.1",
"sprintf-js": "^1.1.2",
"startbootstrap-sb-admin": "4.0.0",
Expand All @@ -43,7 +45,9 @@
"timeago": "^1.6.7",
"timeago.js": "^4.0.2",
"toastr": "^2.1.4",
"uuid": "^8.3.2"
"uuid": "^8.3.2",
"vue": "next",
"vue-router": "4"
},
"devDependencies": {
"@babel/core": "^7.14.6",
Expand All @@ -52,6 +56,9 @@
"@rollup/plugin-commonjs": "^19.0.0",
"@rollup/plugin-node-resolve": "^13.0.0",
"@rollup/plugin-replace": "^2.4.2",
"@typescript-eslint/eslint-plugin": "^4.28.1",
"@typescript-eslint/parser": "^4.28.1",
"@vue/compiler-sfc": "^3.1.4",
"autoprefixer": "^10.2.6",
"babel-core": "^6.26.3",
"babel-preset-es2015": "^6.24.1",
Expand All @@ -72,7 +79,12 @@
"postcss-import": "^14.0.2",
"rollup": "^2.52.1",
"rollup-plugin-postcss": "^4.0.0",
"rollup-plugin-typescript2": "^0.30.0",
"rollup-plugin-vue": "latest",
"standard": "^16.0.3",
"uglify-js": "^3.13.10"
"tslib": "^2.3.0",
"typescript": "^4.3.5",
"uglify-js": "^3.13.10",
"vue-eslint-parser": "^7.7.2"
}
}
4 changes: 3 additions & 1 deletion php/Controllers/SystemController.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ public function Root(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Htt
$demoDataGeneratorService->PopulateDemoData();
}

return $response->withRedirect($this->AppContainer->get('UrlManager')->ConstructUrl($this->GetEntryPageRelative()));
// yolo, this is a SPA now.
return $this->render($request, $response, 'vue');
//return $response->withRedirect($this->AppContainer->get('UrlManager')->ConstructUrl($this->GetEntryPageRelative()));
}

public function __construct(\DI\Container $container)
Expand Down
9 changes: 9 additions & 0 deletions php/Middleware/AuthMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ public function __invoke(Request $request, RequestHandler $handler): Response

if ($routeName === 'root')
{
if (GROCY_MODE === 'dev' || GROCY_MODE === 'demo' || GROCY_MODE === 'prerelease' || GROCY_IS_EMBEDDED_INSTALL || GROCY_DISABLE_AUTH)
{
$sessionService = SessionService::getInstance();
$user = $sessionService->GetDefaultUser();
hackathi marked this conversation as resolved.
Show resolved Hide resolved

define('GROCY_AUTHENTICATED', true);
define('GROCY_USER_USERNAME', $user->username);
define('GROCY_USER_PICTURE_FILE_NAME', $user->picture_file_name);
}
return $handler->handle($request);
}
elseif ($routeName === 'login')
Expand Down
38 changes: 38 additions & 0 deletions php/Views/vue.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html lang="{{ GROCY_LOCALE }}"
dir="{{ $dir }}">

<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

<meta name="robots" content="noindex,nofollow">
<meta name="format-detection" content="telephone=no">

<link rel="apple-touch-icon" sizes="180x180" href="{{ $U('/img/appicons/apple-touch-icon.png?v=', true) }}{{ $version }}">
<link rel="icon" type="image/png" sizes="32x32" href="{{ $U('/img/appicons/favicon-32x32.png?v=', true) }}{{ $version }}">
<link rel="icon" type="image/png" sizes="16x16" href="{{ $U('/img/appicons/favicon-16x16.png?v=', true) }}{{ $version }}">

<link rel="manifest" href="{{ $U('/img/appicons/site.webmanifest?v=', true) }}{{ $version }}">
<link rel="mask-icon" href="{{ $U('/img/appicons/safari-pinned-tab.svg?v=', true) }}{{ $version }}" color="#0b024c">
<link rel="shortcut icon" href="{{ $U('/img/appicons/favicon.ico?v=', true) }}{{ $version }}">
<meta name="apple-mobile-web-app-title" content="grocy">
<meta name="application-name" content="grocy">
<meta name="msapplication-TileColor" content="#e5e5e5">
<meta name="msapplication-config" content="{{ $U('/img/appicons/browserconfig.xml?v=', true) }}{{ $version }}">
<meta name="theme-color" content="#ffffff">

<title>grocy</title>

<link href="{{ $U('/components_unmanaged/noto-sans-v11-latin/noto-sans-v11-latin.min.css?v=', true) }}{{ $version }}" rel="stylesheet">
<link href="{{ $U('/dist/grocy.css?v=', true) }}{{ $version }}" rel="stylesheet">
</head>

<body>
<div id="app"></div>

<script src="{{ $U('/dist/main.js?v=', true) }}{{ $version }}"></script>
</body>

</html>
45 changes: 45 additions & 0 deletions rollup.vue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/* eslint-disable no-undef */
import vue from 'rollup-plugin-vue';
import commonjs from '@rollup/plugin-commonjs';
import resolve from '@rollup/plugin-node-resolve';
import babel from '@rollup/plugin-babel';
import postcss from 'rollup-plugin-postcss';
import replace from '@rollup/plugin-replace';
import typescript from 'rollup-plugin-typescript2';

import path from 'path';


const env = process.env.NODE_ENV || 'development';

export default {
input: [
'js/main.ts'
],
output: {
dir: 'public/dist',
format: 'umd',
name: 'VueGrocy',
sourcemap: true,
},
plugins: [
resolve({ browser: true, preferBuiltins: true }),
vue({
target: "browser"
}),
typescript(),
commonjs(),
babel({
babelHelpers: 'bundled',
exclude: 'node_modules/**'
}),
postcss({ // will load postcss.config.js
extract: path.resolve('public/dist/app.css'),
minimize: env !== 'development',
}),
replace({
'process.env.NODE_ENV': JSON.stringify(env),
preventAssignment: true,
})
]
};
14 changes: 13 additions & 1 deletion scss/grocy.scss
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,16 @@
// end third-party

// TODO: does it need to be at the end?
@import "night-mode";
@import "night-mode";

// now comes the fun part, because whatever is set above, primeVue will now override.
.theme-day {
@import 'primevue/resources/themes/saga-green/theme.css'; // this will be the day theme.
}
.theme-night {
@import 'primevue/resources/themes/arya-green/theme.css'; // this will be the night theme.
}

@import 'primevue/resources/primevue.css'; // core css
@import 'primeicons/primeicons.css'; // icons

Loading