Compare commits

..

37 Commits

Author SHA1 Message Date
Alf Sebastian Houge
302bdd2222 Implement switching language (but doesn't persist) 2023-07-18 22:48:36 +02:00
Alf Sebastian Houge
14968013dd Write and read language setting from backend 2023-02-26 13:54:55 +01:00
Alf Sebastian Houge
efa6aed8eb Add language masters 2023-02-26 13:45:17 +01:00
Alf Sebastian Houge
533c68ee09 Add db migration for supporting per user language setting 2023-02-26 13:44:58 +01:00
Alf Sebastian Houge
9da21b2192 Change go module name 2023-02-16 22:35:03 +01:00
Alf Sebastian Houge
a8c85bcd7d Merge pull request #34 from AlfHou/chore/update-dependencies
Chore/update dependencies
2023-02-12 21:06:27 +01:00
Alf Sebastian Houge
d597a4ed30 Fix sizing issues in font awesome icons 2023-02-12 17:38:26 +01:00
Alf Sebastian Houge
45456280b4 Fix scss warnings 2023-02-07 21:00:20 +01:00
Alf Sebastian Houge
1d5794e344 Update lint staged 2023-02-07 20:36:08 +01:00
Alf Sebastian Houge
cd558ba744 Update buefy 2023-02-07 20:34:51 +01:00
Alf Sebastian Houge
3a2c82c789 Fix warnings and translation errors in user creator 2023-02-05 00:39:21 +01:00
Alf Sebastian Houge
d196536d74 Update vue packages 2023-02-04 23:35:07 +01:00
Alf Sebastian Houge
630a7f2ec6 Update vuex and vue router 2023-02-04 23:28:09 +01:00
Alf Sebastian Houge
f2bc01289a update icon fonts 2023-02-04 22:04:19 +01:00
Alf Sebastian Houge
a8d2b37087 Fix eslint errors 2023-02-04 22:01:27 +01:00
Alf Sebastian Houge
7436399d90 Update eslint 2023-02-04 21:48:16 +01:00
Alf Sebastian Houge
bc3e1f0982 Update stylelint-scss 2023-02-04 21:43:56 +01:00
Alf Sebastian Houge
d429fa34bd Update hygen 2023-02-04 21:43:09 +01:00
Alf Sebastian Houge
5095cb4c61 Update lintstaged 2023-02-04 21:41:48 +01:00
Alf Sebastian Houge
e0df7ee80e Update markdown-cli 2023-02-04 21:38:53 +01:00
Alf Sebastian Houge
431de8c3eb Update sass-loader 2023-02-04 21:36:47 +01:00
Alf Sebastian Houge
41793784ea Update stylelint 2023-02-04 21:34:34 +01:00
Alf Sebastian Houge
85b5ad28bf Update core.js 2023-02-04 21:22:17 +01:00
Alf Sebastian Houge
b386012e13 Use node version 16 and higher 2023-02-04 21:14:26 +01:00
Alf Sebastian Houge
df2d7288df Update caniuse browser list 2023-02-04 15:41:42 +01:00
Alf Sebastian Houge
7a6f796561 Update date-fns 2023-02-04 15:25:32 +01:00
Alf Sebastian Houge
aee52d0594 Update icon fonts 2023-02-04 15:16:54 +01:00
Alf Sebastian Houge
f8b1de8d15 Update eslint dependencies 2023-02-04 14:56:07 +01:00
Alf Sebastian Houge
a7896340e1 Update express 2023-02-04 14:03:37 +01:00
Alf Sebastian Houge
f2a3bb2e9f Update lint-staged 2023-02-04 14:01:44 +01:00
Alf Sebastian Houge
d343619f13 Update sass 2023-02-04 13:58:56 +01:00
Alf Sebastian Houge
adce0efa8b Update stylelint dependency 2023-02-04 13:57:28 +01:00
Alf Sebastian Houge
fc6f4bc00d Update stylelint-config-recess-order dependency 2023-02-04 13:55:27 +01:00
Alf Sebastian Houge
a16bcf850f Update stylelint-scss 2023-02-04 13:53:51 +01:00
Alf Sebastian Houge
4ace38f8f3 Update currency-formatter 2023-01-31 22:28:05 +01:00
Alf Sebastian Houge
63e330ffb0 Update outdated packages accoording to version locks 2023-01-31 22:07:26 +01:00
Alf Sebastian Houge
fc9796081e Remove yarn from project 2023-01-31 21:53:53 +01:00
54 changed files with 20788 additions and 25462 deletions

View File

@@ -7,7 +7,8 @@ import (
"os"
"time"
"github.com/akhilrex/hammond/db"
"hammond/db"
"github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"

View File

@@ -7,10 +7,11 @@ import (
"os"
"strings"
"github.com/akhilrex/hammond/common"
"github.com/akhilrex/hammond/db"
"github.com/akhilrex/hammond/models"
"github.com/akhilrex/hammond/service"
"hammond/common"
"hammond/db"
"hammond/models"
"hammond/service"
"github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin"
)

View File

@@ -5,10 +5,11 @@ import (
"net/http"
"os"
"github.com/akhilrex/hammond/common"
"github.com/akhilrex/hammond/db"
"github.com/akhilrex/hammond/models"
"github.com/akhilrex/hammond/service"
"hammond/common"
"hammond/db"
"hammond/models"
"hammond/service"
"github.com/gin-gonic/gin"
)

View File

@@ -4,7 +4,8 @@ import (
"net/http"
"strconv"
"github.com/akhilrex/hammond/service"
"hammond/service"
"github.com/gin-gonic/gin"
)

View File

@@ -3,10 +3,11 @@ package controllers
import (
"net/http"
"github.com/akhilrex/hammond/common"
"github.com/akhilrex/hammond/db"
"github.com/akhilrex/hammond/models"
"github.com/akhilrex/hammond/service"
"hammond/common"
"hammond/db"
"hammond/models"
"hammond/service"
"github.com/gin-gonic/gin"
)
@@ -18,6 +19,7 @@ func RegisterAnonMasterConroller(router *gin.RouterGroup) {
"distanceUnits": db.DistanceUnitDetails,
"roles": db.RoleDetails,
"currencies": models.GetCurrencyMasterList(),
"languages": models.GetLanguageMastersList(),
})
})
}
@@ -51,7 +53,7 @@ func udpateSettings(c *gin.Context) {
func udpateMySettings(c *gin.Context) {
var model models.UpdateSettingModel
if err := c.ShouldBind(&model); err == nil {
err := service.UpdateUserSettings(c.MustGet("userId").(string), model.Currency, *model.DistanceUnit, model.DateFormat)
err := service.UpdateUserSettings(c.MustGet("userId").(string), model.Currency, *model.DistanceUnit, model.DateFormat, model.Language)
if err != nil {
c.JSON(http.StatusUnprocessableEntity, common.NewError("udpateMySettings", err))
return

View File

@@ -5,7 +5,8 @@ import (
"os"
"strings"
"github.com/akhilrex/hammond/db"
"hammond/db"
"github.com/dgrijalva/jwt-go"
"github.com/dgrijalva/jwt-go/request"
"github.com/gin-gonic/gin"

View File

@@ -3,9 +3,10 @@ package controllers
import (
"net/http"
"github.com/akhilrex/hammond/common"
"github.com/akhilrex/hammond/models"
"github.com/akhilrex/hammond/service"
"hammond/common"
"hammond/models"
"hammond/service"
"github.com/gin-gonic/gin"
)

View File

@@ -4,10 +4,11 @@ import (
"fmt"
"net/http"
"github.com/akhilrex/hammond/common"
"github.com/akhilrex/hammond/db"
"github.com/akhilrex/hammond/models"
"github.com/akhilrex/hammond/service"
"hammond/common"
"hammond/db"
"hammond/models"
"hammond/service"
"github.com/gin-gonic/gin"
)

View File

@@ -3,10 +3,11 @@ package controllers
import (
"net/http"
"github.com/akhilrex/hammond/common"
"github.com/akhilrex/hammond/db"
"github.com/akhilrex/hammond/models"
"github.com/akhilrex/hammond/service"
"hammond/common"
"hammond/db"
"hammond/models"
"hammond/service"
"github.com/gin-gonic/gin"
)

View File

@@ -4,9 +4,10 @@ import (
"errors"
"net/http"
"github.com/akhilrex/hammond/common"
"github.com/akhilrex/hammond/models"
"github.com/akhilrex/hammond/service"
"hammond/common"
"hammond/models"
"hammond/service"
"github.com/gin-gonic/gin"
)

View File

@@ -19,6 +19,7 @@ type User struct {
Name string `json:"name"`
Vehicles []Vehicle `gorm:"many2many:user_vehicles;" json:"vehicles"`
IsDisabled bool `json:"isDisabled"`
Language string `json:"language"`
}
func (b *User) MarshalJSON() ([]byte, error) {

View File

@@ -27,6 +27,10 @@ var migrations = []localMigration{
Name: "2022_03_08_13_16_AddVIN",
Query: "ALTER TABLE vehicles ADD COLUMN vin text",
},
{
Name: "2023_02_26_13_42_AddLanguage",
Query: "ALTER TABLE users ADD COLUMN language text default 'en'",
},
}
func RunMigrations() {

View File

@@ -1,4 +1,4 @@
module github.com/akhilrex/hammond
module hammond
go 1.16

View File

@@ -5,9 +5,10 @@ import (
"log"
"os"
"github.com/akhilrex/hammond/controllers"
"github.com/akhilrex/hammond/db"
"github.com/akhilrex/hammond/service"
"hammond/controllers"
"hammond/db"
"hammond/service"
"github.com/gin-contrib/location"
"github.com/gin-gonic/contrib/static"
"github.com/gin-gonic/gin"

View File

@@ -3,7 +3,7 @@ package models
import (
"time"
"github.com/akhilrex/hammond/db"
"hammond/db"
)
type CreateAlertModel struct {

View File

@@ -1,6 +1,6 @@
package models
import "github.com/akhilrex/hammond/db"
import "hammond/db"
type LoginResponse struct {
Name string `json:"name"`

24
server/models/language.go Normal file
View File

@@ -0,0 +1,24 @@
package models
type LanguageModel struct {
Emoji string `json:"emoji"`
Name string `json:"name"`
NameNative string `json:"nameNative"`
Shorthand string `json:"shorthand"`
}
func GetLanguageMastersList() []LanguageModel {
return []LanguageModel{
{
Emoji: "🇬🇧",
Name: "English",
NameNative: "English",
Shorthand: "en",
}, {
Emoji: "🇩🇪",
Name: "German",
NameNative: "Deutsch",
Shorthand: "de",
},
}
}

View File

@@ -1,11 +1,12 @@
package models
import "github.com/akhilrex/hammond/db"
import "hammond/db"
type UpdateSettingModel struct {
Currency string `json:"currency" form:"currency" query:"currency"`
DateFormat string `json:"dateFormat" form:"dateFormat" query:"dateFormat"`
DistanceUnit *db.DistanceUnit `json:"distanceUnit" form:"distanceUnit" query:"distanceUnit" `
Language string `json:"language" form:"language" query:"language"`
}
type ClarksonMigrationModel struct {

View File

@@ -4,7 +4,7 @@ import (
"encoding/json"
"time"
"github.com/akhilrex/hammond/db"
"hammond/db"
)
type MileageModel struct {

View File

@@ -3,7 +3,8 @@ package models
import (
"time"
"github.com/akhilrex/hammond/db"
"hammond/db"
_ "github.com/go-playground/validator/v10"
)

View File

@@ -4,8 +4,8 @@ import (
"errors"
"time"
"github.com/akhilrex/hammond/db"
"github.com/akhilrex/hammond/models"
"hammond/db"
"hammond/models"
)
func CreateAlert(model models.CreateAlertModel, vehicleId, userId string) (*db.VehicleAlert, error) {

View File

@@ -8,7 +8,7 @@ import (
"strings"
"time"
"github.com/akhilrex/hammond/db"
"hammond/db"
)
func DrivvoParseExpenses(content []byte, user *db.User, vehicle *db.Vehicle) ([]db.Expense, []string) {

View File

@@ -13,9 +13,10 @@ import (
"strconv"
"time"
"github.com/akhilrex/hammond/db"
"github.com/akhilrex/hammond/internal/sanitize"
"github.com/akhilrex/hammond/models"
"hammond/db"
"hammond/internal/sanitize"
"hammond/models"
uuid "github.com/satori/go.uuid"
)

View File

@@ -7,7 +7,8 @@ import (
"strconv"
"time"
"github.com/akhilrex/hammond/db"
"hammond/db"
"github.com/leekchan/accounting"
)

View File

@@ -3,7 +3,7 @@ package service
import (
"bytes"
"github.com/akhilrex/hammond/db"
"hammond/db"
)
func WriteToDB(fillups []db.Fillup, expenses []db.Expense) []string {

View File

@@ -1,7 +1,9 @@
package service
import (
"github.com/akhilrex/hammond/db"
"errors"
"hammond/db"
"hammond/models"
)
func CanInitializeSystem() (bool, error) {
@@ -14,15 +16,30 @@ func UpdateSettings(currency string, distanceUnit db.DistanceUnit) error {
setting.DistanceUnit = distanceUnit
return db.UpdateSettings(setting)
}
func UpdateUserSettings(userId, currency string, distanceUnit db.DistanceUnit, dateFormat string) error {
func UpdateUserSettings(userId, currency string, distanceUnit db.DistanceUnit, dateFormat string, language string) error {
user, err := db.GetUserById(userId)
if err != nil {
return err
}
// TODO: Pull into function
languageExists := false
languages := models.GetLanguageMastersList();
for _, lang := range languages {
if (language == lang.Shorthand){
languageExists = true
}
}
if (!languageExists) {
return errors.New("Language not in masters list")
}
user.Currency = currency
user.DistanceUnit = distanceUnit
user.DateFormat = dateFormat
user.Language = language
return db.UpdateUser(user)
}

View File

@@ -4,9 +4,9 @@ import (
"sort"
"time"
"github.com/akhilrex/hammond/common"
"github.com/akhilrex/hammond/db"
"github.com/akhilrex/hammond/models"
"hammond/common"
"hammond/db"
"hammond/models"
)
func GetMileageByVehicleId(vehicleId string, since time.Time, mileageOption string) (mileage []models.MileageModel, err error) {

View File

@@ -3,8 +3,8 @@ package service
import (
"strings"
"github.com/akhilrex/hammond/db"
"github.com/akhilrex/hammond/models"
"hammond/db"
"hammond/models"
)
func CreateUser(userModel *models.RegisterRequest, role db.Role) error {

View File

@@ -3,8 +3,9 @@ package service
import (
"fmt"
"github.com/akhilrex/hammond/db"
"github.com/akhilrex/hammond/models"
"hammond/db"
"hammond/models"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)

View File

@@ -20,6 +20,7 @@ module.exports = {
'no-console': process.env.PRE_COMMIT
? ['error', { allow: ['warn', 'error'] }]
: 'off',
'vue/multi-word-component-names': 0,
'import/no-relative-parent-imports': 'error',
'import/order': 'error',
'vue/array-bracket-spacing': 'error',

View File

@@ -6,10 +6,9 @@ WORKDIR /app
# Copy dependency-related files
COPY package.json ./
COPY yarn.lock ./
# Install project dependencies
RUN yarn install
RUN npm install
# Expose ports 8080, which the dev server will be bound to
EXPOSE 8080

30847
ui/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -6,91 +6,81 @@
"dev": "vue-cli-service serve",
"dev:e2e": "cross-env VUE_APP_TEST=e2e vue-cli-service test:e2e --mode=development",
"build": "vue-cli-service build --modern",
"build:ci": "yarn build --report",
"build:ci": "npm build --report",
"lint:eslint": "eslint --fix",
"lint:stylelint": "stylelint --fix",
"lint:markdownlint": "markdownlint",
"lint:prettier": "prettier --write --loglevel warn",
"lint:all:eslint": "yarn lint:eslint --ext .js,.vue .",
"lint:all:stylelint": "yarn lint:stylelint \"src/**/*.{vue,scss}\"",
"lint:all:markdownlint": "yarn lint:markdownlint \"docs/*.md\" \"*.md\"",
"lint:all:prettier": "yarn lint:prettier \"**/*.{js,json,css,scss,vue,html,md}\"",
"lint": "run-s lint:all:*",
"test:unit": "cross-env VUE_APP_TEST=unit vue-cli-service test:unit",
"test:unit:file": "yarn test:unit --bail --findRelatedTests",
"test:unit:watch": "yarn test:unit --watch --notify --notifyMode change",
"test:unit:ci": "yarn test:unit --coverage --ci",
"test:e2e": "cross-env VUE_APP_TEST=e2e vue-cli-service test:e2e --headless",
"test": "run-s test:unit test:e2e",
"test:ci": "run-s test:unit:ci test:e2e",
"new": "cross-env HYGEN_TMPLS=generators hygen new",
"docs": "vuepress dev",
"docker": "docker-compose exec dev yarn"
"docs": "vuepress dev"
},
"gitHooks": {
"pre-commit": "cross-env PRE_COMMIT=true lint-staged"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.27",
"@fortawesome/free-solid-svg-icons": "^5.12.1",
"@fortawesome/vue-fontawesome": "0.1.9",
"axios": "^0.27.2",
"buefy": "^0.9.7",
"@fortawesome/fontawesome-svg-core": "^6.3.0",
"@fortawesome/free-solid-svg-icons": "^6.3.0",
"@fortawesome/vue-fontawesome": "^2.0.10",
"axios": "^1.3.2",
"buefy": "^0.9.22",
"chart.js": "^2.9.4",
"core-js": "3.6.4",
"currency-formatter": "^1.5.7",
"date-fns": "2.10.0",
"core-js": "^3.27.2",
"currency-formatter": "^1.5.9",
"date-fns": "^2.29.3",
"lodash": "^4.17.21",
"node-gyp": "^9.3.1",
"normalize.css": "8.0.1",
"nprogress": "0.2.0",
"vue": "2.6.11",
"normalize.css": "^8.0.1",
"nprogress": "^0.2.0",
"vue": "^2.6.11",
"vue-chartjs": "^3.5.1",
"vue-i18n": "^8.28.2",
"vue-meta": "2.3.3",
"vue-router": "3.1.6",
"vuex": "3.1.2"
"vue-meta": "^2.4.0",
"vue-router": "^3.6.5",
"vuex": "^3.6.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "4.2.x",
"@vue/cli-plugin-eslint": "4.2.x",
"@vue/cli-plugin-unit-jest": "4.2.x",
"@vue/cli-service": "4.2.x",
"@vue/cli-plugin-babel": "^4.5.19",
"@vue/cli-plugin-eslint": "^4.5.19",
"@vue/cli-plugin-unit-jest": "^4.5.19",
"@vue/cli-service": "^4.5.19",
"@vue/eslint-config-prettier": "6.0.x",
"@vue/eslint-config-standard": "5.1.x",
"@vue/test-utils": "1.0.0-beta.31",
"babel-core": "7.0.0-bridge.0",
"@vue/eslint-config-standard": "^5.1.1",
"@vue/test-utils": "^1.3.4",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "10.1.x",
"cross-env": "7.0.x",
"eslint": "6.8.x",
"eslint-plugin-import": "2.20.x",
"eslint-plugin-node": "11.0.x",
"eslint-plugin-promise": "4.2.x",
"eslint-plugin-standard": "4.0.x",
"eslint-plugin-vue": "6.2.x",
"express": "4.17.x",
"hygen": "4.0.x",
"imagemin-lint-staged": "0.4.x",
"lint-staged": "10.0.x",
"markdownlint-cli": "^0.31.1",
"npm-run-all": "4.1.x",
"sass": "1.26.x",
"sass-loader": "8.0.x",
"stylelint": "13.2.x",
"stylelint-config-css-modules": "2.2.x",
"stylelint-config-prettier": "8.0.x",
"stylelint-config-recess-order": "2.0.x",
"stylelint-config-standard": "20.0.x",
"stylelint-scss": "3.14.x",
"vue-template-compiler": "2.6.11",
"vuepress": "1.3.x"
"cross-env": "^7.0.1",
"eslint": "^6.8.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.3.1",
"eslint-plugin-standard": "^5.0.0",
"eslint-plugin-vue": "^9.9.0",
"express": "^4.18.2",
"hygen": "^6.2.11",
"imagemin-lint-staged": "^0.5.1",
"lint-staged": "^13.1.1",
"markdownlint-cli": "^0.33.0",
"npm-run-all": "^4.1.1",
"sass": "^1.58.0",
"sass-loader": "^8.0.2",
"stylelint": "^14.16.1",
"stylelint-config-css-modules": "^4.1.0",
"stylelint-config-prettier": "^9.0.4",
"stylelint-config-standard": "^29.0.0",
"stylelint-scss": "^4.3.0",
"vue-template-compiler": "^2.6.11",
"vuepress": "^1.9.8"
},
"resolutions": {
"@vue/cli-plugin-unit-jest/jest": "25.1.x",
"@vue/cli-plugin-unit-jest/babel-jest": "25.1.x"
},
"engines": {
"node": ">=10.13.3",
"yarn": ">=1.0.0"
"node": ">=16.0.0"
}
}

View File

@@ -7,6 +7,10 @@
<link rel="shortcut icon" href="<%= webpackConfig.output.publicPath %>hammond.png" />
<link rel="apple-touch-icon" href="<%= webpackConfig.output.publicPath %>touch-icon.png" />
<title><%= webpackConfig.name %></title>
<!-- Temporary until fontawesome 6 is supported in buefy (see issue: https://github.com/FortAwesome/Font-Awesome/issues/18663) -->
<style>
.icon svg { width: 1em; height: 1em; max-width: 80%; max-height: 80%; }
</style>
</head>
<body>
<!-- This is where our app will be mounted. -->

View File

@@ -95,11 +95,10 @@ export default {
</div>
<div class="column">
<b-button
tag="input"
tag="button"
native-type="submit"
:disabled="tryingToCreate"
type="is-primary"
:value="this.$t('uploadfile')"
class="control"
>
{{ $t('uploadfile') }}

View File

@@ -50,7 +50,7 @@ export default {
<b-select
v-if="unprocessedQuickEntries.length"
v-model="quickEntry"
:placeholder="this.$t('referquickentry')"
:placeholder="$t('referquickentry')"
expanded
@input="showQuickEntry($event)"
>

View File

@@ -92,7 +92,7 @@ export default {
<div class="box" style="max-width:600px">
<h1 class="subtitle">{{ $t('share') }} {{ vehicle.nickname }}</h1>
<section>
<div class="columns is-mobile" v-for="model in models" :key="model.id">
<div v-for="model in models" :key="model.id" class="columns is-mobile">
<div class="column is-one-third">
<b-field>
<b-switch v-model="model.isShared" :disabled="model.isOwner" @input="changeShareStatus(model)">

View File

@@ -10,10 +10,10 @@ $size-input-padding-vertical: 0.75em;
$size-input-padding-horizontal: 1em;
$size-input-padding: $size-input-padding-vertical $size-input-padding-horizontal;
$size-input-border: 1px;
$size-input-border-radius: (1em + $size-input-padding-vertical * 2) / 10;
$size-input-border-radius: calc((1em + $size-input-padding-vertical * 2) / 10);
// BUTTONS
$size-button-padding-vertical: $size-grid-padding / 2;
$size-button-padding-horizontal: $size-grid-padding / 1.5;
$size-button-padding-vertical: calc($size-grid-padding / 2);
$size-button-padding-horizontal: calc($size-grid-padding / 1.5);
$size-button-padding: $size-button-padding-vertical
$size-button-padding-horizontal;

View File

@@ -147,7 +147,7 @@
$max-screen,
$max-value
) {
$a: ($max-value - $min-value) / ($max-screen - $min-screen);
$a: calc(($max-value - $min-value) / ($max-screen - $min-screen));
$b: $min-value - $a * $min-screen;
$sign: '+';

View File

@@ -34,7 +34,6 @@ import '@components/_globals'
import 'buefy/dist/buefy.css'
import 'nprogress/nprogress.css'
Vue.component('vue-fontawesome', FontAwesomeIcon)
library.add(
faCheck,
faTimes,
@@ -54,7 +53,8 @@ library.add(
faShare,
faUserFriends,
faTimesCircle
)
);
Vue.component('VueFontawesome', FontAwesomeIcon)
Vue.use(Buefy, {
defaultIconComponent: 'vue-fontawesome',

View File

@@ -162,41 +162,41 @@ export default {
</div>
</div>
<form @submit.prevent="createExpense">
<b-field :label="this.$t('selectvehicle')">
<b-select v-model="selectedVehicle" :placeholder="this.$t('vehicle')" required expanded :disabled="expense.id">
<b-field :label="$t('selectvehicle')">
<b-select v-model="selectedVehicle" :placeholder="$t('vehicle')" required expanded :disabled="expense.id">
<option v-for="option in myVehicles" :key="option.id" :value="option">
{{ option.nickname }}
</option>
</b-select>
</b-field>
<b-field :label="this.$t('expenseby')">
<b-select v-model="expenseModel.userId" :placeholder="this.$t('user')" required expanded :disabled="expense.id">
<b-field :label="$t('expenseby')">
<b-select v-model="expenseModel.userId" :placeholder="$t('user')" required expanded :disabled="expense.id">
<option v-for="option in users" :key="option.userId" :value="option.userId">
{{ option.name }}
</option>
</b-select>
</b-field>
<b-field :label="this.$t('expensedate')">
<b-field :label="$t('expensedate')">
<b-datepicker
v-model="expenseModel.date"
:date-formatter="formatDate"
:placeholder="this.$t('clicktoselect')"
:placeholder="$t('clicktoselect')"
icon="calendar"
:max-date="new Date()"
>
</b-datepicker>
</b-field>
<b-field :label="this.$t('expensetype') + `*`">
<b-field :label="$t('expensetype') + `*`">
<b-input v-model="expenseModel.expenseType" expanded required></b-input>
</b-field>
<b-field :label="this.$t('totalamountpaid')">
<b-field :label="$t('totalamountpaid')">
<p class="control">
<span class="button is-static">{{ me.currency }}</span>
</p>
<b-input v-model.number="expenseModel.amount" type="number" min="0" expanded step=".001" required></b-input>
</b-field>
<b-field :label="this.$t('odometer')">
<b-field :label="$t('odometer')">
<p class="control">
<span class="button is-static">{{ $t('unit.short.' + me.distanceUnitDetail.key) }}</span>
</p>
@@ -207,7 +207,7 @@ export default {
<b-switch v-model="showMore">{{ $t('fillmoredetails') }}</b-switch>
</b-field>
<fieldset v-if="showMore">
<b-field :label="this.$t('details')">
<b-field :label="$t('details')">
<b-input v-model="expenseModel.comments" type="textarea" expanded></b-input>
</b-field>
</fieldset>
@@ -216,7 +216,7 @@ export default {
</b-field>
<br />
<b-field>
<b-button tag="input" native-type="submit" :value="this.$t('save')" :disabled="tryingToCreate" type="is-primary" label="Create Expense" expanded> </b-button>
<b-button tag="button" native-type="submit" :value="$t('save')" :disabled="tryingToCreate" type="is-primary" label="Create Expense" expanded/>
</b-field>
</form>
</Layout>

View File

@@ -193,21 +193,21 @@ export default {
</div>
</div>
<form class="" @submit.prevent="createFillup">
<b-field :label="this.$t('selectvehicle')">
<b-select v-model="selectedVehicle" :placeholder="this.$t('vehicle')" required expanded :disabled="fillup.id">
<b-field :label="$t('selectvehicle')">
<b-select v-model="selectedVehicle" :placeholder="$t('vehicle')" required expanded :disabled="fillup.id">
<option v-for="option in myVehicles" :key="option.id" :value="option">
{{ option.nickname }}
</option>
</b-select>
</b-field>
<b-field :label="this.$t('expenseby')">
<b-select v-model="fillupModel.userId" :placeholder="this.$t('user')" required expanded :disabled="fillup.id">
<b-field :label="$t('expenseby')">
<b-select v-model="fillupModel.userId" :placeholder="$t('user')" required expanded :disabled="fillup.id">
<option v-for="option in users" :key="option.userId" :value="option.userId">
{{ option.name }}
</option>
</b-select>
</b-field>
<b-field :label="this.$t('fillupdate')">
<b-field :label="$t('fillupdate')">
<b-datepicker
v-model="fillupModel.date"
:date-formatter="formatDate"
@@ -218,7 +218,7 @@ export default {
>
</b-datepicker>
</b-field>
<b-field :label="this.$t('fuelsubtype')">
<b-field :label="$t('fuelsubtype')">
<b-autocomplete
v-model="fillupModel.fuelSubType"
:data="filteredFuelSubtypes"
@@ -229,27 +229,27 @@ export default {
>
</b-autocomplete>
</b-field>
<b-field :label="this.$t('quantity') + `*`" addons>
<b-field :label="$t('quantity') + `*`" addons>
<b-input v-model.number="fillupModel.fuelQuantity" type="number" step=".001" min="0" expanded required></b-input>
<b-select v-model="fillupModel.fuelUnit" :placeholder="this.$t('fuelunit')" required>
<b-select v-model="fillupModel.fuelUnit" :placeholder="$t('fuelunit')" required>
<option v-for="(option, key) in fuelUnitMasters" :key="key" :value="key">
{{ $t('unit.long.' + option.key) }}
</option>
</b-select>
</b-field>
<b-field :label="this.$t('per', { '0': this.$t('price'), '1': $t('unit.short.' + vehicle.fuelUnitDetail.key) })"
<b-field :label="$t('per', { '0': $t('price'), '1': $t('unit.short.' + vehicle.fuelUnitDetail.key) })"
><p class="control">
<span class="button is-static">{{ me.currency }}</span>
</p>
<b-input v-model.number="fillupModel.perUnitPrice" type="number" min="0" step=".001" expanded required></b-input>
</b-field>
<b-field :label="this.$t('totalamountpaid')">
<b-field :label="$t('totalamountpaid')">
<p class="control">
<span class="button is-static">{{ me.currency }}</span>
</p>
<b-input v-model.number="fillupModel.totalAmount" type="number" min="0" step=".001" expanded required></b-input>
</b-field>
<b-field :label="this.$t('odometer')">
<b-field :label="$t('odometer')">
<p class="control">
<span class="button is-static">{{ $t('unit.short.' + me.distanceUnitDetail.key) }}</span>
</p>
@@ -265,10 +265,10 @@ export default {
<b-switch v-model="showMore">{{ $t('fillmoredetails') }}</b-switch>
</b-field>
<fieldset v-if="showMore">
<b-field :label="this.$t('fillingstation')">
<b-field :label="$t('fillingstation')">
<b-input v-model="fillupModel.fillingStation" type="text" expanded></b-input>
</b-field>
<b-field :label="this.$t('comments')">
<b-field :label="$t('comments')">
<b-input v-model="fillupModel.comments" type="textarea" expanded></b-input>
</b-field>
</fieldset>
@@ -277,7 +277,7 @@ export default {
</b-field>
<br />
<b-field>
<b-button tag="input" native-type="submit" :disabled="tryingToCreate" type="is-primary" :value="this.$t('save')" :label="this.$t('createfillup')" expanded> </b-button>
<b-button tag="button" native-type="submit" :disabled="tryingToCreate" type="is-primary" :value="$t('save')" :label="$t('createfillup')" expanded/>
<p v-if="authError">
There was an error logging in to your account.
</p>

View File

@@ -134,53 +134,53 @@ export default {
</div>
</div>
<form @submit.prevent="createVehicle">
<b-field :label="this.$t('nickname') + `*`">
<b-field :label="$t('nickname') + `*`">
<b-input v-model="vehicleModel.nickname" type="text" expanded required></b-input>
</b-field>
<b-field :label="this.$t('registration') + `*`">
<b-field :label="$t('registration') + `*`">
<b-input v-model="vehicleModel.registration" type="text" expanded required></b-input>
</b-field>
<b-field label="VIN">
<b-input v-model="vehicleModel.vin" type="text" expanded></b-input>
</b-field>
<b-field :label="this.$t('fueltype') + `*`">
<b-select v-model.number="vehicleModel.fuelType" :placeholder="this.$t('fueltype')" required expanded>
<b-field :label="$t('fueltype') + `*`">
<b-select v-model.number="vehicleModel.fuelType" :placeholder="$t('fueltype')" required expanded>
<option v-for="(option, key) in fuelTypeMasters" :key="key" :value="key">
{{ $t('fuel.' + option.key) }}
</option>
</b-select>
</b-field>
<b-field :label="this.$t('fuelunit') + `*`">
<b-select v-model.number="vehicleModel.fuelUnit" :placeholder="this.$t('fuelunit')" required expanded>
<b-field :label="$t('fuelunit') + `*`">
<b-select v-model.number="vehicleModel.fuelUnit" :placeholder="$t('fuelunit')" required expanded>
<option v-for="(option, key) in fuelUnitMasters" :key="key" :value="key">
{{ $t('unit.long.' + option.key) }}
</option>
</b-select>
</b-field>
<b-field :label="this.$t('make') + `*`">
<b-field :label="$t('make') + `*`">
<b-input v-model="vehicleModel.make" type="text" required expanded></b-input>
</b-field>
<b-field :label="this.$t('model') + `*`">
<b-field :label="$t('model') + `*`">
<b-input v-model="vehicleModel.model" type="text" required expanded></b-input>
</b-field>
<b-field :label="this.$t('yearmanufacture') + `*`">
<b-field :label="$t('yearmanufacture') + `*`">
<b-input v-model.number="vehicleModel.yearOfManufacture" type="number" expanded number></b-input>
</b-field>
<b-field :label="this.$t('enginesize')">
<b-field :label="$t('enginesize')">
<b-input v-model.number="vehicleModel.engineSize" type="number" expanded number></b-input>
</b-field>
<br />
<b-field>
<b-button
tag="input"
tag="button"
native-type="submit"
:disabled="tryingToCreate"
type="is-primary"
:value="this.$t('save')"
:label="this.$t('createvehicle')"
:value="$t('save')"
:label="$t('createvehicle')"
expanded
>
<BaseIcon v-if="tryingToCreate" name="sync" spin />

View File

@@ -154,7 +154,7 @@ export default {
</b-field>
</div>
<div class="column">
<b-button tag="input" native-type="submit" :disabled="tryingToCreate" type="is-primary" value="Upload File" class="control">
<b-button tag="button" native-type="submit" :disabled="tryingToCreate" type="is-primary" class="control">
Import
</b-button>
</div></div

View File

@@ -9,6 +9,19 @@ export default {
meta: [{ name: 'description', content: 'The Import Fuelly page.' }],
},
components: { Layout },
props: {
user: {
type: Object,
required: true,
},
},
data: function() {
return {
file: null,
tryingToCreate: false,
errors: [],
}
},
computed: {
...mapState('utils', ['isMobile']),
uploadButtonLabel() {
@@ -27,19 +40,6 @@ export default {
}
},
},
props: {
user: {
type: Object,
required: true,
},
},
data: function() {
return {
file: null,
tryingToCreate: false,
errors: [],
}
},
methods: {
importFuelly() {
if (this.file == null) {
@@ -121,7 +121,7 @@ export default {
</b-field>
</div>
<div class="column">
<b-button tag="input" native-type="submit" :disabled="tryingToCreate" type="is-primary" :value="this.$t('uploadfile')" class="control">
<b-button tag="button" native-type="submit" :disabled="tryingToCreate" type="is-primary" class="control">
{{ $t('import') }}
</b-button>
</div></div

View File

@@ -187,7 +187,7 @@ export default {
{{ connectionError }}
</b-notification>
<b-field addons :label="this.$t('mysqlconnstr')">
<b-field addons :label="$t('mysqlconnstr')">
<b-input v-model="url" required></b-input>
</b-field>
@@ -200,20 +200,20 @@ export default {
<div v-if="migrationMode === 'fresh'" class="box content">
<h1 class="title">{{ $t('init.fresh.setupadminuser') }}</h1>
<form @submit.prevent="register">
<b-field :label="this.$t('init.fresh.yourname')">
<b-field :label="$t('init.fresh.yourname')">
<b-input v-model="registerModel.name" required></b-input>
</b-field>
<b-field :label="this.$t('init.fresh.youremail')">
<b-field :label="$t('init.fresh.youremail')">
<b-input v-model="registerModel.email" type="email" required></b-input>
</b-field>
<b-field :label="this.$t('init.fresh.yourpassword')">
<b-field :label="$t('init.fresh.yourpassword')">
<b-input v-model="registerModel.password" type="password" required minlength="8" password-reveal></b-input>
</b-field>
<b-field :label="this.$t('currency')">
<b-field :label="$t('currency')">
<b-autocomplete
v-model="registerModel.currency"
:custom-formatter="formatCurrency"
:placeholder="this.$t('currency')"
:placeholder="$t('currency')"
:data="filteredCurrencyMasters"
:keep-first="true"
:open-on-focus="true"
@@ -221,8 +221,8 @@ export default {
@select="(option) => (selected = option)"
></b-autocomplete>
</b-field>
<b-field :label="this.$t('distanceunit')">
<b-select v-model.number="registerModel.distanceUnit" :placeholder="this.$t('distanceunit')" required expanded>
<b-field :label="$t('distanceunit')">
<b-select v-model.number="registerModel.distanceUnit" :placeholder="$t('distanceunit')" required expanded>
<option v-for="(option, key) in distanceUnitMasters" :key="key" :value="key">
{{ `${$t('unit.long.' + option.key)} (${$t('unit.short.' + option.key)})` }}
</option>
@@ -230,7 +230,7 @@ export default {
</b-field>
<br />
<div class="buttons">
<b-button type="is-primary" native-type="submit" tag="input" :value="this.$t('save')"></b-button>
<b-button type="is-primary" native-type="submit" tag="button" :value="$t('save')"></b-button>
<b-button type="is-danger is-light" @click="resetMigrationMode">{{ $t('cancel') }}</b-button>
</div>

View File

@@ -71,7 +71,7 @@ export default {
<b-field :label="$t('password')">
<b-input v-model="password" tag="b-input" name="password" type="password" :placeholder="placeholders.password" />
</b-field>
<b-button tag="input" native-type="submit" :value="$t('login')" :disabled="tryingToLogIn" type="is-primary">
<b-button tag="button" native-type="submit" :disabled="tryingToLogIn" type="is-primary">
<BaseIcon v-if="tryingToLogIn" name="sync" spin />
<span v-else>
{{ $t('login') }}

View File

@@ -22,11 +22,13 @@ export default {
data: function() {
return {
settingsModel: {
language: this.me.language,
currency: this.me.currency,
distanceUnit: this.me.distanceUnit,
dateFormat: this.me.dateFormat,
},
tryingToSave: false,
selectedLanguage: "",
changePassModel: {
old: '',
new: '',
@@ -36,7 +38,7 @@ export default {
}
},
computed: {
...mapState('vehicles', ['currencyMasters', 'distanceUnitMasters']),
...mapState('masters', ['currencyMasters', 'languageMasters', 'distanceUnitMasters']),
passwordValid() {
if (this.changePassModel.new === '' || this.changePassModel.renew === '') {
return true
@@ -59,6 +61,9 @@ export default {
})
},
},
mounted() {
this.selectedLanguage = this.formatLanguage(this.languageMasters.filter(x => x.shorthand === this.me.language)[0])
},
methods: {
changePassword() {
if (!this.passwordValid) {
@@ -110,6 +115,7 @@ export default {
type: 'is-success',
duration: 3000,
})
this.$i18n.locale = this.settingsModel.language
})
.catch((ex) => {
this.$buefy.toast.open({
@@ -126,6 +132,9 @@ export default {
formatCurrency(option) {
return `${option.namePlural} (${option.code})`
},
formatLanguage(option) {
return `${option.nameNative} ${option.emoji}`
},
},
}
</script>
@@ -136,9 +145,18 @@ export default {
<div class="columns"
><div class="column">
<form class="box " @submit.prevent="saveSettings">
<h1 class="subtitle">
{{ $t('settingdesc') }}
</h1>
<b-field :label="$t('language')">
<b-autocomplete
v-model="selectedLanguage"
:placeholder="$t('language')"
:keep-first="true"
:custom-formatter="formatLanguage"
:data="languageMasters"
:open-on-focus="true"
required
@select="(option) => (settingsModel.language = option.shorthand)"
/>
</b-field>
<b-field :label="$t('currency')">
<b-autocomplete
v-model="settingsModel.currency"
@@ -167,7 +185,7 @@ export default {
</b-field>
<br />
<b-field>
<b-button tag="input" native-type="submit" :disabled="tryingToSave" type="is-primary" :value="$t('save')" expanded> </b-button>
<b-button tag="button" native-type="submit" :disabled="tryingToSave" type="is-primary" expanded> {{ $t('save') }} </b-button>
</b-field>
</form>
</div>
@@ -185,7 +203,8 @@ export default {
</b-field>
<p v-if="!passwordValid" class="help is-danger">{{ $t('passworddontmatch') }}</p>
<b-field>
<b-button tag="input" native-type="submit" :disabled="!passwordValid" type="is-primary" :value="$t('changepassword')" expanded>
<b-button tag="button" native-type="submit" :disabled="!passwordValid" type="is-primary" expanded>
{{ $t('changepassword') }}
</b-button>
</b-field>
</form>

View File

@@ -72,15 +72,15 @@ export default {
</div>
<br />
<form class="" @submit.prevent="saveSettings">
<b-field :label="this.$t('currency')">
<b-select v-model="settingsModel.currency" :placeholder="this.$t('currency')" required expanded>
<b-field :label="$t('currency')">
<b-select v-model="settingsModel.currency" :placeholder="$t('currency')" required expanded>
<option v-for="option in currencyMasters" :key="option.code" :value="option.code">
{{ `${option.namePlural} (${option.code})` }}
</option>
</b-select>
</b-field>
<b-field :label="this.$t('distanceunit')">
<b-select v-model.number="settingsModel.distanceUnit" :placeholder="this.$t('distanceunit')" required expanded>
<b-field :label="$t('distanceunit')">
<b-select v-model.number="settingsModel.distanceUnit" :placeholder="$t('distanceunit')" required expanded>
<option v-for="(option, key) in distanceUnitMasters" :key="key" :value="key">
{{ `${$t('unit.long.' + option.key)} (${$t('unit.short.' + option.key)})` }}
</option>
@@ -88,7 +88,7 @@ export default {
</b-field>
<br />
<b-field>
<b-button tag="input" native-type="submit" :disabled="tryingToSave" type="is-primary" :value="this.$t('save')" expanded> </b-button>
<b-button tag="button" native-type="submit" :disabled="tryingToSave" type="is-primary" expanded> {{ $t('save') }}</b-button>
</b-field>
</form>
</Layout>

View File

@@ -138,13 +138,13 @@ export default {
<div v-if="showUserForm" class="box content">
<h1 class="title">{{ $t('createnewuser') }}</h1>
<form @submit.prevent="register">
<b-field :label="this.$t('name')">
<b-field :label="$t('name')">
<b-input v-model="registerModel.name" required></b-input>
</b-field>
<b-field :label="this.$t('email')">
<b-field :label="$t('email')">
<b-input v-model="registerModel.email" type="email" required></b-input>
</b-field>
<b-field :label="this.$t('password')">
<b-field :label="$t('password')">
<b-input
v-model="registerModel.password"
type="password"
@@ -153,24 +153,24 @@ export default {
password-reveal
></b-input>
</b-field>
<b-field :label="this.$t('role')">
<b-select v-model.number="registerModel.role" :placeholder="this.$t('placeholder')" required expanded>
<b-field :label="$t('role')">
<b-select v-model.number="registerModel.role" :placeholder="$t('role')" required expanded>
<option v-for="(option, key) in roleMasters" :key="key" :value="key">
{{ `test` }}
{{ `${option.key}` }}
</option>
</b-select>
</b-field>
<b-field :label="this.$t('currency')">
<b-select v-model="registerModel.currency" :placeholder="this.$t('currency')" required expanded>
<b-field :label="$t('currency')">
<b-select v-model="registerModel.currency" :placeholder="$t('currency')" required expanded>
<option v-for="option in currencyMasters" :key="option.code" :value="option.code">
{{ `${option.namePlural} (${option.code})` }}
</option>
</b-select>
</b-field>
<b-field :label="this.$t('distanceunit')">
<b-field :label="$t('distanceunit')">
<b-select
v-model.number="registerModel.distanceUnit"
:placeholder="this.$t('distanceunit')"
:placeholder="$t('distanceunit')"
required
expanded
>
@@ -181,28 +181,28 @@ export default {
</b-field>
<br />
<div class="buttons">
<b-button type="is-primary" native-type="submit" tag="input" :value="this.$t('save')"></b-button>
<b-button type="is-primary" native-type="submit" tag="button">{{ $t('save') }}</b-button>
<b-button type="is-danger is-light" @click="resetUserForm">{{ $t('cancel') }}</b-button>
</div>
</form>
</div>
<b-table :data="users" hoverable mobile-cards detail-key="id" paginated per-page="10" :row-class="(row, index) => row.isDisabled && 'is-disabled'">
<b-table-column v-slot="props" field="name" :label="this.$t('name')">
<b-table-column v-slot="props" field="name" :label="$t('name')">
{{ `${props.row.name}` }} <template v-if="props.row.id === user.id">({{ $t('you') }})</template>
</b-table-column>
<b-table-column v-slot="props" field="email" :label="this.$t('email')">
<b-table-column v-slot="props" field="email" :label="$t('email')">
{{ `${props.row.email}` }}
</b-table-column>
<b-table-column v-slot="props" field="role" :label="this.$t('role')">
<b-table-column v-slot="props" field="role" :label="$t('role')">
{{ `${$t('roles.' + props.row.roleDetail.key)}` }}
</b-table-column>
<b-table-column v-slot="props" field="createdAt" :label="this.$t('created')" sortable date>
<b-table-column v-slot="props" field="createdAt" :label="$t('created')" sortable date>
{{ formatDate(props.row.createdAt) }}
</b-table-column>
<b-table-column v-slot="props">
<b-button type="is-success" v-if="props.row.isDisabled && props.row.roleDetail.key === 'USER'" @click="changeDisabledStatus(props.row.id, false)">{{ $t('enable') }}</b-button>
<b-button type="is-danger" v-if="!props.row.isDisabled && props.row.roleDetail.key === 'USER'" @click="changeDisabledStatus(props.row.id, true)">{{ $t('disable') }}</b-button>
<b-button v-if="props.row.isDisabled && props.row.roleDetail.key === 'USER'" type="is-success" @click="changeDisabledStatus(props.row.id, false)">{{ $t('enable') }}</b-button>
<b-button v-if="!props.row.isDisabled && props.row.roleDetail.key === 'USER'" type="is-danger" @click="changeDisabledStatus(props.row.id, true)">{{ $t('disable') }}</b-button>
</b-table-column>
</b-table>
</div>

View File

@@ -92,7 +92,10 @@ export default {
},
{
label: this.$t('avgfuelcost'),
value: this.$t('per', {'0': this.formatCurrency(x.avgFuelPrice, x.currency), '1': this.$t('unit.short.' + this.vehicle.fuelUnitDetail.key)}),
value: this.$t('per', {
0: this.formatCurrency(x.avgFuelPrice, x.currency),
1: this.$t('unit.short.' + this.vehicle.fuelUnitDetail.key),
}),
},
]
})
@@ -309,15 +312,15 @@ export default {
<div class="column is-one-half" :class="isMobile ? 'has-text-centered' : ''">
<p class="title">{{ vehicle.nickname }} - {{ vehicle.registration }}</p>
<p class="subtitle">
{{ [vehicle.make, vehicle.model, this.$t('fuel.' + vehicle.fuelTypeDetail.key)].join(' | ') }}
{{ [vehicle.make, vehicle.model, $t('fuel.' + vehicle.fuelTypeDetail.key)].join(' | ') }}
<template v-if="users.length > 1">
| {{ $t("sharedwith") }} :
| {{ $t('sharedwith') }} :
{{
users
.map((x) => {
if (x.userId === me.id) {
return this.$t('you')
return $t('you')
} else {
return x.name
}
@@ -328,8 +331,8 @@ export default {
</p>
</div>
<div :class="(!isMobile ? 'has-text-right ' : '') + 'column is-one-half buttons'">
<b-button type="is-primary" tag="router-link" :to="`/vehicles/${vehicle.id}/fillup`">{{ this.$t('addfillup') }}</b-button>
<b-button type="is-primary" tag="router-link" :to="`/vehicles/${vehicle.id}/expense`">{{ this.$t('addexpense') }}</b-button>
<b-button type="is-primary" tag="router-link" :to="`/vehicles/${vehicle.id}/fillup`">{{ $t('addfillup') }}</b-button>
<b-button type="is-primary" tag="router-link" :to="`/vehicles/${vehicle.id}/expense`">{{ $t('addexpense') }}</b-button>
<b-button
v-if="vehicle.isOwner"
tag="router-link"
@@ -339,9 +342,8 @@ export default {
props: { vehicle: vehicle },
params: { id: vehicle.id },
}"
>
<b-icon pack="fas" icon="edit" type="is-info"> </b-icon
></b-button>
><b-icon pack="fas" icon="edit" type="is-info"> </b-icon>
</b-button>
<b-button v-if="vehicle.isOwner" :title="$t('sharevehicle')" @click="showShareVehicleModal">
<b-icon pack="fas" icon="user-friends" type="is-info"> </b-icon
></b-button>
@@ -362,42 +364,42 @@ export default {
<h1 class="title is-4">{{ $t('pastfillups') }}</h1>
<b-table :data="fillups" hoverable mobile-cards :detailed="isMobile" detail-key="id" paginated per-page="10">
<b-table-column v-slot="props" field="date" :label="this.$t('date')" :td-attrs="columnTdAttrs" sortable date>
<b-table-column v-slot="props" field="date" :label="$t('date')" :td-attrs="columnTdAttrs" sortable date>
{{ formatDate(props.row.date) }}
</b-table-column>
<b-table-column v-slot="props" field="fuelSubType" :label="this.$t('fuelsubtype')" :td-attrs="columnTdAttrs">
<b-table-column v-slot="props" field="fuelSubType" :label="$t('fuelsubtype')" :td-attrs="columnTdAttrs">
{{ props.row.fuelSubType }}
</b-table-column>
<b-table-column v-slot="props" field="fuelQuantity" :label="this.$t('quantity')" :td-attrs="hiddenMobile" numeric>
<b-table-column v-slot="props" field="fuelQuantity" :label="$t('quantity')" :td-attrs="hiddenMobile" numeric>
{{ `${props.row.fuelQuantity} ${$t('unit.short.' + props.row.fuelUnitDetail.key)}` }}
</b-table-column>
<b-table-column
v-slot="props"
field="perUnitPrice"
:label="this.$t('per', { '0': this.$t('price'), '1': this.$t('unit.short.' + vehicle.fuelUnitDetail.key) })"
:label="$t('per', { '0': $t('price'), '1': $t('unit.short.' + vehicle.fuelUnitDetail.key) })"
:td-attrs="hiddenMobile"
numeric
sortable
>
{{ `${formatCurrency(props.row.perUnitPrice, props.row.currency)}` }}
</b-table-column>
<b-table-column v-if="isMobile" v-slot="props" field="totalAmount" :label="this.$t('total')" :td-attrs="hiddenDesktop" sortable numeric>
<b-table-column v-if="isMobile" v-slot="props" field="totalAmount" :label="$t('total')" :td-attrs="hiddenDesktop" sortable numeric>
{{ `${me.currency} ${props.row.totalAmount}` }} ({{ `${props.row.fuelQuantity} ${$t('unit.short.' + props.row.fuelUnitDetail.key)}` }} @
{{ `${me.currency} ${props.row.perUnitPrice}` }})
</b-table-column>
<b-table-column v-if="!isMobile" v-slot="props" field="totalAmount" :label="this.$t('total')" :td-attrs="hiddenMobile" sortable numeric>
<b-table-column v-if="!isMobile" v-slot="props" field="totalAmount" :label="$t('total')" :td-attrs="hiddenMobile" sortable numeric>
{{ `${formatCurrency(props.row.totalAmount, props.row.currency)}` }}
</b-table-column>
<b-table-column v-slot="props" width="20" field="isTankFull" :label="this.$t('fulltank')" :td-attrs="hiddenMobile">
<b-table-column v-slot="props" width="20" field="isTankFull" :label="$t('fulltank')" :td-attrs="hiddenMobile">
<b-icon pack="fas" :icon="props.row.isTankFull ? 'check' : 'times'" type="is-info"> </b-icon>
</b-table-column>
<b-table-column v-slot="props" field="odoReading" :label="this.$t('odometer')" :td-attrs="hiddenMobile" numeric>
<b-table-column v-slot="props" field="odoReading" :label="$t('odometer')" :td-attrs="hiddenMobile" numeric>
{{ `${props.row.odoReading} ${$t('unit.short.' + me.distanceUnitDetail.key)}` }}
</b-table-column>
<b-table-column v-slot="props" field="fillingStation" :label="this.$t('gasstation')" :td-attrs="hiddenMobile">
<b-table-column v-slot="props" field="fillingStation" :label="$t('gasstation')" :td-attrs="hiddenMobile">
{{ `${props.row.fillingStation}` }}
</b-table-column>
<b-table-column v-slot="props" field="userId" :label="this.$t('by')" :td-attrs="hiddenMobile">
<b-table-column v-slot="props" field="userId" :label="$t('by')" :td-attrs="hiddenMobile">
{{ `${props.row.user.name}` }}
</b-table-column>
<b-table-column v-slot="props">
@@ -412,7 +414,10 @@ export default {
>
<b-icon pack="fas" icon="edit" type="is-info"> </b-icon
></b-button>
<b-button type="is-ghost" :title="$t('deletefillup')" @click="deleteFillup(props.row.id)">
<b-button
type="is-ghost"
:title="$t('deletefillup')"
@click="deleteFillup(props.row.id)">
<b-icon pack="fas" icon="trash" type="is-danger"> </b-icon
></b-button>
</b-table-column>
@@ -427,22 +432,22 @@ export default {
<h1 class="title is-4">{{ $t('expenses') }}</h1>
<b-table :data="expenses" hoverable mobile-cards paginated per-page="10">
<b-table-column v-slot="props" field="date" :label="this.$t('date')" :td-attrs="columnTdAttrs" date>
<b-table-column v-slot="props" field="date" :label="$t('date')" :td-attrs="columnTdAttrs" date>
{{ formatDate(props.row.date) }}
</b-table-column>
<b-table-column v-slot="props" field="expenseType" :label="this.$t('expensetype')">
<b-table-column v-slot="props" field="expenseType" :label="$t('expensetype')">
{{ `${props.row.expenseType}` }}
</b-table-column>
<b-table-column v-slot="props" field="amount" :label="this.$t('total')" :td-attrs="hiddenMobile" sortable numeric>
<b-table-column v-slot="props" field="amount" :label="$t('total')" :td-attrs="hiddenMobile" sortable numeric>
{{ `${formatCurrency(props.row.amount, props.row.currency)}` }}
</b-table-column>
<b-table-column v-slot="props" field="odoReading" :label="this.$t('odometer')" :td-attrs="columnTdAttrs" numeric>
<b-table-column v-slot="props" field="odoReading" :label="$t('odometer')" :td-attrs="columnTdAttrs" numeric>
{{ `${props.row.odoReading} ${$t('unit.short.' + me.distanceUnitDetail.key)}` }}
</b-table-column>
<b-table-column v-slot="props" field="userId" :label="this.$t('by')" :td-attrs="columnTdAttrs">
<b-table-column v-slot="props" field="userId" :label="$t('by')" :td-attrs="columnTdAttrs">
{{ `${props.row.user.name}` }}
</b-table-column>
<b-table-column v-slot="props">
@@ -467,7 +472,9 @@ export default {
<br />
<div class="box">
<div class="columns">
<div class="column is-three-quarters"> <h1 class="title is-4">{{ $t('attachments') }}</h1></div>
<div class="column is-three-quarters">
<h1 class="title is-4">{{ $t('attachments') }}</h1></div
>
<div class="column buttons">
<b-button type="is-primary" @click="showAttachmentForm = true">
{{ $t('addattachment') }}
@@ -492,18 +499,18 @@ export default {
</b-upload>
</b-field>
<b-field>
<b-input v-model="title" required :placeholder="this.$t('labelforfile')"></b-input>
<b-input v-model="title" required :placeholder="$t('labelforfile')"></b-input>
</b-field>
<b-field class="buttons">
<b-button tag="input" native-type="submit" :disabled="tryingToUpload" type="is-primary" label="Upload File" value="Upload File">
<b-button tag="button" native-type="submit" :disabled="tryingToUpload" type="is-primary" label="Upload File" value="Upload File">
</b-button>
<b-button
tag="input"
tag="button"
native-type="submit"
:disabled="tryingToUpload"
type="is-danger"
label="Upload File"
label="Cancel"
value="Cancel"
@click="showAttachmentForm = false"
>
@@ -516,14 +523,14 @@ export default {
</div>
<b-table :data="attachments" hoverable mobile-cards>
<b-table-column v-slot="props" field="title" :label="this.$t('title')" :td-attrs="columnTdAttrs">
<b-table-column v-slot="props" field="title" :label="$t('title')" :td-attrs="columnTdAttrs">
{{ `${props.row.title}` }}
</b-table-column>
<b-table-column v-slot="props" field="originalName" :label="this.$t('name')" :td-attrs="columnTdAttrs">
<b-table-column v-slot="props" field="originalName" :label="$t('name')" :td-attrs="columnTdAttrs">
{{ `${props.row.originalName}` }}
</b-table-column>
<b-table-column v-slot="props" field="id" :label="this.$t('download')" :td-attrs="columnTdAttrs">
<b-table-column v-slot="props" field="id" :label="$t('download')" :td-attrs="columnTdAttrs">
<b-button tag="a" :href="`/api/attachments/${props.row.id}/file?access_token=${currentUser.token}`" :download="props.row.originalName">
<b-icon type="is-primary" icon="download"></b-icon>
</b-button>
@@ -533,7 +540,9 @@ export default {
</div>
<div class="box">
<div class="columns">
<div class="column" :class="isMobile ? 'has-text-centered' : ''"> <h1 class="title">{{ $t('statistics') }}</h1></div>
<div class="column" :class="isMobile ? 'has-text-centered' : ''">
<h1 class="title">{{ $t('statistics') }}</h1></div
>
<div class="column">
<div class="columns is-pulled-right is-medium">
<div class="column">

View File

@@ -0,0 +1,52 @@
import axios from 'axios'
export const state = {
languageMasters: [],
fuelUnitMasters: [],
distanceUnitMasters: [],
currencyMasters: [],
fuelTypeMasters: [],
roleMasters: [],
}
export const mutations = {
CACHE_LANGUAGE_MASTERS(state, masters) {
state.languageMasters = masters
},
CACHE_FUEL_UNIT_MASTERS(state, masters) {
state.fuelUnitMasters = masters
},
CACHE_DISTANCE_UNIT_MASTERS(state, masters) {
state.distanceUnitMasters = masters
},
CACHE_FUEL_TYPE_MASTERS(state, masters) {
state.fuelTypeMasters = masters
},
CACHE_CURRENCY_MASTERS(state, masters) {
state.currencyMasters = masters
},
CACHE_ROLE_MASTERS(state, roles) {
state.roleMasters = roles
},
}
export const getters = {}
export const actions = {
init({ dispatch, rootState }) {
const { currentUser } = rootState.auth
if (currentUser) {
dispatch('fetchMasters')
}
},
fetchMasters({ commit, state, rootState }) {
return axios.get('/api/masters').then((response) => {
commit('CACHE_LANGUAGE_MASTERS', response.data.languages)
commit('CACHE_FUEL_UNIT_MASTERS', response.data.fuelUnits)
commit('CACHE_FUEL_TYPE_MASTERS', response.data.fuelTypes)
commit('CACHE_CURRENCY_MASTERS', response.data.currencies)
commit('CACHE_DISTANCE_UNIT_MASTERS', response.data.distanceUnits)
commit('CACHE_ROLE_MASTERS', response.data.roles)
return response.data
})
},
}

View File

@@ -4,11 +4,6 @@ import { filter } from 'lodash'
import parseISO from 'date-fns/parseISO'
export const state = {
vehicles: [],
roleMasters: [],
fuelUnitMasters: [],
distanceUnitMasters: [],
currencyMasters: [],
fuelTypeMasters: [],
quickEntries: [],
vehicleStats: new Map(),
}
@@ -29,24 +24,9 @@ export const mutations = {
CACHE_VEHICLE_STATS(state, stats) {
state.vehicleStats.set(stats.vehicleId, stats)
},
CACHE_FUEL_UNIT_MASTERS(state, masters) {
state.fuelUnitMasters = masters
},
CACHE_DISTANCE_UNIT_MASTERS(state, masters) {
state.distanceUnitMasters = masters
},
CACHE_FUEL_TYPE_MASTERS(state, masters) {
state.fuelTypeMasters = masters
},
CACHE_CURRENCY_MASTERS(state, masters) {
state.currencyMasters = masters
},
CACHE_QUICK_ENTRIES(state, entries) {
state.quickEntries = entries
},
CACHE_ROLE_MASTERS(state, roles) {
state.roleMasters = roles
},
}
export const actions = {
@@ -54,22 +34,9 @@ export const actions = {
const { currentUser } = rootState.auth
if (currentUser) {
dispatch('fetchVehicles')
dispatch('fetchMasters')
dispatch('fetchQuickEntries', { force: true })
}
},
fetchMasters({ commit, state, rootState }) {
return axios.get('/api/masters').then((response) => {
const fuelUnitMasters = response.data.fuelUnits
const fuelTypeMasters = response.data.fuelTypes
commit('CACHE_FUEL_UNIT_MASTERS', fuelUnitMasters)
commit('CACHE_FUEL_TYPE_MASTERS', fuelTypeMasters)
commit('CACHE_CURRENCY_MASTERS', response.data.currencies)
commit('CACHE_DISTANCE_UNIT_MASTERS', response.data.distanceUnits)
commit('CACHE_ROLE_MASTERS', response.data.roles)
return response.data
})
},
fetchVehicles({ commit, state, rootState }) {
return axios.get('/api/me/vehicles').then((response) => {
const data = response.data

14736
ui/yarn.lock

File diff suppressed because it is too large Load Diff