@@ -59,24 +59,24 @@ type EnumDetail struct {
|
||||
var FuelUnitDetails map[FuelUnit]EnumDetail = map[FuelUnit]EnumDetail{
|
||||
LITRE: {
|
||||
Short: "Lt",
|
||||
Long: "Litre",
|
||||
Long: "litre",
|
||||
},
|
||||
GALLON: {
|
||||
Short: "Gal",
|
||||
Long: "Gallon",
|
||||
Long: "gallon",
|
||||
}, KILOGRAM: {
|
||||
Short: "Kg",
|
||||
Long: "Kilogram",
|
||||
Long: "kilogram",
|
||||
}, KILOWATT_HOUR: {
|
||||
Short: "KwH",
|
||||
Long: "Kilowatt Hour",
|
||||
Long: "kilowatthour",
|
||||
}, US_GALLON: {
|
||||
Short: "US Gal",
|
||||
Long: "US Gallon",
|
||||
Long: "usgallon",
|
||||
},
|
||||
MINUTE: {
|
||||
Short: "Mins",
|
||||
Long: "Minutes",
|
||||
Long: "minutes",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -41,10 +41,12 @@
|
||||
"currency-formatter": "^1.5.7",
|
||||
"date-fns": "2.10.0",
|
||||
"lodash": "^4.17.21",
|
||||
"node-gyp": "^9.3.1",
|
||||
"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"
|
||||
|
||||
@@ -20,7 +20,7 @@ export default {
|
||||
}
|
||||
} else {
|
||||
if (this.file == null) {
|
||||
return 'Upload Photo'
|
||||
return this.$t('uploadphoto')
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
@@ -39,7 +39,7 @@ export default {
|
||||
.post(`/api/quickEntries`, formData)
|
||||
.then((data) => {
|
||||
this.$buefy.toast.open({
|
||||
message: 'Quick Entry Created Successfully',
|
||||
message: this.$t('quickentrycreatedsuccessfully'),
|
||||
type: 'is-success',
|
||||
duration: 3000,
|
||||
})
|
||||
@@ -68,9 +68,9 @@ export default {
|
||||
<div class="section box">
|
||||
<div class="columns">
|
||||
<div class="column is-two-thirds">
|
||||
<p class="title">Quick Entry</p>
|
||||
<p class="title">{{ $tc('quickentry',1) }}</p>
|
||||
<p class="subtitle"
|
||||
>Take a pic of the invoice or the fuel pump display to make an entry later.</p
|
||||
>{{ $t('quickentrydesc') }}</p
|
||||
></div
|
||||
>
|
||||
<div class="column is-one-third is-flex is-align-content-center">
|
||||
@@ -99,10 +99,10 @@ export default {
|
||||
native-type="submit"
|
||||
:disabled="tryingToCreate"
|
||||
type="is-primary"
|
||||
value="Upload File"
|
||||
:value="this.$t('uploadfile')"
|
||||
class="control"
|
||||
>
|
||||
Upload File
|
||||
{{ $t('uploadfile') }}
|
||||
</b-button>
|
||||
</div></div
|
||||
>
|
||||
|
||||
@@ -30,7 +30,7 @@ export default {
|
||||
var labels = this.chartData.map((x) => x.date.substr(0, 10))
|
||||
var dataset = {
|
||||
steppedLine: true,
|
||||
label: `Mileage (${this.user.distanceUnitDetail.short}/${this.vehicle.fuelUnitDetail.short})`,
|
||||
label: `${this.$t('odometer')} (${this.user.distanceUnitDetail.short}/${this.vehicle.fuelUnitDetail.short})`,
|
||||
fill: true,
|
||||
data: this.chartData.map((x) => x.mileage),
|
||||
}
|
||||
|
||||
@@ -10,42 +10,42 @@ export default {
|
||||
persistentNavRoutes: [
|
||||
{
|
||||
name: 'home',
|
||||
title: 'Home',
|
||||
title: this.$t('menu.home'),
|
||||
},
|
||||
],
|
||||
loggedInNavRoutes: [
|
||||
{
|
||||
name: 'quickEntries',
|
||||
title: () => 'Quick Entries',
|
||||
title: () => this.$t('menu.quickentries'),
|
||||
badge: () => this.unprocessedQuickEntries.length,
|
||||
},
|
||||
{
|
||||
name: 'import',
|
||||
title: () => 'Import',
|
||||
title: () => this.$t('menu.import'),
|
||||
},
|
||||
{
|
||||
name: 'settings',
|
||||
title: 'Settings',
|
||||
title: this.$t('menu.settings'),
|
||||
},
|
||||
{
|
||||
name: 'logout',
|
||||
title: 'Log out',
|
||||
title: this.$t('menu.logout'),
|
||||
},
|
||||
],
|
||||
loggedOutNavRoutes: [
|
||||
{
|
||||
name: 'login',
|
||||
title: 'Log in',
|
||||
title: this.$t('menu.login'),
|
||||
},
|
||||
],
|
||||
adminNavRoutes: [
|
||||
{
|
||||
name: 'site-settings',
|
||||
title: 'Site Settings',
|
||||
title: this.$t('menu.sitesettings'),
|
||||
},
|
||||
{
|
||||
name: 'users',
|
||||
title: 'Users',
|
||||
title: this.$t('menu.users'),
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -72,7 +72,7 @@ export default {
|
||||
<NavBarRoutes :routes="persistentNavRoutes" />
|
||||
<NavBarRoutes v-if="loggedIn" :routes="loggedInNavRoutes" />
|
||||
<NavBarRoutes v-else :routes="loggedOutNavRoutes" />
|
||||
<b-navbar-dropdown v-if="loggedIn && isAdmin" label="Admin">
|
||||
<b-navbar-dropdown v-if="loggedIn && isAdmin" :label="$t('menu.admin')">
|
||||
<NavBarRoutes :routes="adminNavRoutes" />
|
||||
</b-navbar-dropdown>
|
||||
</template>
|
||||
|
||||
@@ -50,12 +50,12 @@ export default {
|
||||
<b-select
|
||||
v-if="unprocessedQuickEntries.length"
|
||||
v-model="quickEntry"
|
||||
placeholder="Refer quick entry"
|
||||
:placeholder="this.$t('referquickentry')"
|
||||
expanded
|
||||
@input="showQuickEntry($event)"
|
||||
>
|
||||
<option v-for="option in unprocessedQuickEntries" :key="option.id" :value="option">
|
||||
Taken: {{ parseAndFormatDateTime(option.createdAt) }}
|
||||
{{ $t('created') }}: {{ parseAndFormatDateTime(option.createdAt) }}
|
||||
</option>
|
||||
</b-select>
|
||||
<p class="control">
|
||||
|
||||
@@ -55,7 +55,7 @@ export default {
|
||||
return
|
||||
}
|
||||
this.$buefy.dialog.confirm({
|
||||
title: 'Transfer Vehicle',
|
||||
title: this.$t('transfervehicle'),
|
||||
message: 'Are you sure you want to do this? You will lose ownership and all editing rights if you confirm.',
|
||||
cancelText: 'Cancel',
|
||||
confirmText: 'Go Ahead',
|
||||
@@ -90,7 +90,7 @@ export default {
|
||||
|
||||
<template>
|
||||
<div class="box" style="max-width:600px">
|
||||
<h1 class="subtitle">Share {{ vehicle.nickname }}</h1>
|
||||
<h1 class="subtitle">{{ $t('share') }} {{ vehicle.nickname }}</h1>
|
||||
<section>
|
||||
<div class="columns is-mobile" v-for="model in models" :key="model.id">
|
||||
<div class="column is-one-third">
|
||||
@@ -101,7 +101,7 @@ export default {
|
||||
</b-field> </div
|
||||
><div class="column is-three-quarters">
|
||||
<b-field>
|
||||
<b-button v-if="model.isShared && !model.isOwner" type="is-primary is-small" @click="transferVehicle(model)">Make Owner</b-button>
|
||||
<b-button v-if="model.isShared && !model.isOwner" type="is-primary is-small" @click="transferVehicle(model)">{{ $t('makeowner') }}</b-button>
|
||||
</b-field></div
|
||||
></div
|
||||
>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script>
|
||||
import { addDays, addMonths } from 'date-fns'
|
||||
import currencyFormtter from 'currency-formatter'
|
||||
import currencyFormatter from 'currency-formatter'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
import axios from 'axios'
|
||||
@@ -14,12 +14,12 @@ export default {
|
||||
data: function() {
|
||||
return {
|
||||
dateRangeOptions: [
|
||||
{ label: 'This week', value: 'this_week' },
|
||||
{ label: 'This month', value: 'this_month' },
|
||||
{ label: 'Past 30 days', value: 'past_30_days' },
|
||||
{ label: 'Past 3 months', value: 'past_3_months' },
|
||||
{ label: 'This year', value: 'this_year' },
|
||||
{ label: 'All Time', value: 'all_time' },
|
||||
{ label: this.$t('thisweek'), value: 'this_week' },
|
||||
{ label: this.$t('thismonth'), value: 'this_month' },
|
||||
{ label: this.$tc('pastxdays', 30), value: 'past_30_days' },
|
||||
{ label: this.$tc('pastxmonths', 3), value: 'past_3_months' },
|
||||
{ label: this.$t('thisyear'), value: 'this_year' },
|
||||
{ label: this.$t('alltime'), value: 'all_time' },
|
||||
],
|
||||
dateRangeOption: 'past_30_days',
|
||||
stats: [],
|
||||
@@ -49,15 +49,15 @@ export default {
|
||||
return this.stats.map((x) => {
|
||||
return [
|
||||
{
|
||||
label: 'Total Expenditure',
|
||||
label: this.$t('totalexpenses'),
|
||||
value: this.formatCurrency(x.expenditureTotal, x.currency),
|
||||
},
|
||||
{
|
||||
label: 'Fillup Costs',
|
||||
label: this.$t('fillupcost'),
|
||||
value: `${this.formatCurrency(x.expenditureFillups, x.currency)} (${x.countFillups})`,
|
||||
},
|
||||
{
|
||||
label: 'Other Expenses',
|
||||
label: this.$t('otherexpenses'),
|
||||
value: `${this.formatCurrency(x.expenditureExpenses, x.currency)} (${x.countExpenses})`,
|
||||
},
|
||||
]
|
||||
@@ -80,7 +80,7 @@ export default {
|
||||
if (!currencyCode) {
|
||||
currencyCode = this.me.currency
|
||||
}
|
||||
return currencyFormtter.format(number, { code: currencyCode })
|
||||
return currencyFormatter.format(number, { code: currencyCode })
|
||||
},
|
||||
getStats() {
|
||||
axios
|
||||
@@ -129,7 +129,7 @@ export default {
|
||||
<template>
|
||||
<div>
|
||||
<div class="columns">
|
||||
<div class="column" :class="isMobile ? 'has-text-centered' : ''"> <h1 class="title">Stats</h1></div>
|
||||
<div class="column" :class="isMobile ? 'has-text-centered' : ''"> <h1 class="title">{{ $t('statistics') }}</h1></div>
|
||||
<div class="column">
|
||||
<b-select v-model="dateRangeOption" class="is-pulled-right is-medium">
|
||||
<option v-for="option in dateRangeOptions" :key="option.value" :value="option.value">
|
||||
|
||||
77
ui/src/i18n.js
Normal file
77
ui/src/i18n.js
Normal file
@@ -0,0 +1,77 @@
|
||||
import Vue from 'vue';
|
||||
import VueI18n from 'vue-i18n';
|
||||
|
||||
Vue.use(VueI18n);
|
||||
|
||||
function loadLocaleMessages () {
|
||||
const locales = require.context('./locales', true, /[A-Za-z0-9-_,\s]+\.json$/i)
|
||||
const messages = {}
|
||||
locales.keys().forEach(key => {
|
||||
const matched = key.match(/([A-Za-z0-9-_]+)\./i)
|
||||
if (matched && matched.length > 1) {
|
||||
const locale = matched[1]
|
||||
messages[locale] = locales(key)
|
||||
}
|
||||
})
|
||||
return messages
|
||||
}
|
||||
|
||||
const dateTimeFormats = {
|
||||
'en-US': {
|
||||
short: {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric'
|
||||
},
|
||||
long: {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
weekday: 'long',
|
||||
hour: 'numeric',
|
||||
minute: 'numeric'
|
||||
}
|
||||
},
|
||||
'de-DE': {
|
||||
short: {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric'
|
||||
},
|
||||
long: {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
weekday: 'long',
|
||||
hour: 'numeric',
|
||||
minute: 'numeric',
|
||||
hour12: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const numberFormats = {
|
||||
'en-US': {
|
||||
currency: {
|
||||
style: 'currency',
|
||||
currency: 'USD'
|
||||
}
|
||||
},
|
||||
'de-DE': {
|
||||
currency: {
|
||||
style: 'currency',
|
||||
currency: 'EUR',
|
||||
currencyDisplay: 'symbol'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const i18n = new VueI18n({
|
||||
locale: 'de-DE', // set locale
|
||||
fallbackLocale: 'en-US',
|
||||
messages: loadLocaleMessages(), // set locale messages
|
||||
numberFormats,
|
||||
dateTimeFormats
|
||||
});
|
||||
|
||||
export default i18n;
|
||||
193
ui/src/locales/de.json
Normal file
193
ui/src/locales/de.json
Normal file
@@ -0,0 +1,193 @@
|
||||
{
|
||||
"quickentry": "Keine Schnelleinträge | Schnelleintrag | Schnelleinträge",
|
||||
"statistics": "Statistiken",
|
||||
"thisweek": "Diese Woche",
|
||||
"thismonth": "Dieser Monat",
|
||||
"pastxdays": "Letzter Tag | Letzte {count} Tage",
|
||||
"pastxmonths": "Letzter Monat | Letzte {count} Monate",
|
||||
"thisyear": "Dieses Jahr",
|
||||
"alltime": "Gesamt",
|
||||
"noattachments": "Keine Anhänge",
|
||||
"attachments": "Anhänge",
|
||||
"choosefile": "Datei auswählen",
|
||||
"addattachment": "Anhang hinzufügen",
|
||||
"sharedwith": "Geteilt mit",
|
||||
"share": "Teile",
|
||||
"you": "Sie",
|
||||
"addfillup": "Tankfüllung erfassen",
|
||||
"createfillup": "Erfasse Tankfüllung",
|
||||
"deletefillup": "Lösche diese Tankfüllung",
|
||||
"addexpense": "Ausgabe erfassen",
|
||||
"createexpense": "Erfasse Ausgabe",
|
||||
"deleteexpense": "Lösche diese Ausgabe",
|
||||
"nofillups": "Keine Tankfüllungen",
|
||||
"transfervehicle": "Fahrzeug übertragen",
|
||||
"settingssaved": "Einstellungen erfolgreich gespeichert",
|
||||
"yoursettings": "Deine Einstellungen",
|
||||
"settings": "Einstellungen",
|
||||
"changepassword": "Passwort ändern",
|
||||
"oldpassword": "Bisheriges Passwort",
|
||||
"newpassword": "Neues Passwort",
|
||||
"repeatnewpassword": "Neues Passwort wiederhiolen",
|
||||
"passworddontmatch": "Passwörter stimmen nicht überein",
|
||||
"save": "Speichern",
|
||||
"supportthedeveloper": "Unterstütze den Entwickler",
|
||||
"buyhimabeer": "Kauf ihm ein Bier!",
|
||||
"moreinfo": "Mehr Info",
|
||||
"currency": "Währung",
|
||||
"distanceunit": "Entfernungseinheit",
|
||||
"dateformat": "Datumsformat",
|
||||
"createnow": "Jetzt erstellen",
|
||||
"yourvehicles": "Deine Fahrzeuge",
|
||||
"menu": {
|
||||
"quickentries": "Schnellinträge",
|
||||
"logout": "Abmelden",
|
||||
"import": "Import",
|
||||
"home": "Start",
|
||||
"settings": "Einstellungen",
|
||||
"admin": "Verwalten",
|
||||
"sitesettings": "Globale Einstellungen",
|
||||
"users": "Benutzer",
|
||||
"login": "Anmelden"
|
||||
},
|
||||
"enterusername": "E-Mail eingeben",
|
||||
"enterpassword": "Passwort eingeben",
|
||||
"email": "E-Mail",
|
||||
"password": "Passwort",
|
||||
"login": "Anmelden",
|
||||
"totalexpenses": "Gesamtausgaben",
|
||||
"fillupcost": "Tank Ausgaben",
|
||||
"otherexpenses": "Andere Ausgaben",
|
||||
"addvehicle": "Fahrzeug hinzufügen",
|
||||
"editvehicle": "Fahrzeug bearbeiten",
|
||||
"deletevehicle": "Fahrzeug löschen",
|
||||
"sharevehicle": "Fahrzeug teilen",
|
||||
"makeowner": "zum Besitzer machen",
|
||||
"lastfillup": "Letztes Tanken",
|
||||
"quickentrydesc": "Mach ein Foto deiner Rechnung oder der Zapfsäule um den Eintrag später zu ergänzen.",
|
||||
"quickentrycreatedsuccessfully": "Schnelleintrag erfolgreich erstellt",
|
||||
"uploadfile": "Datei hochladen",
|
||||
"uploadphoto": "Foto hochladen",
|
||||
"details": "Details",
|
||||
"odometer": "Kilometerzähler",
|
||||
"language": "Sprache",
|
||||
"date": "Datum",
|
||||
"pastfillups": "Tankfüllungen",
|
||||
"fuelsubtype": "Kraftstofftyp",
|
||||
"fueltype": "Kraftstoff",
|
||||
"quantity": "Menge",
|
||||
"gasstation": "Tankstelle",
|
||||
"fuel": {
|
||||
"Petrol": "Benzin",
|
||||
"Diesel": "Diesel",
|
||||
"CNG": "CNG",
|
||||
"LPG": "LPG",
|
||||
"Electric": "Strom",
|
||||
"Ethanol": "Ethanol"
|
||||
},
|
||||
"unit": {
|
||||
"long": {
|
||||
"litre": "Liter",
|
||||
"gallon": "Gallone",
|
||||
"kilowatthour": "Kilowattstunde",
|
||||
"kilogram": "Kilogramm",
|
||||
"usgallon": "US-Gallone",
|
||||
"minutes": "Minuten"
|
||||
},
|
||||
"short": {
|
||||
"litre": "L",
|
||||
"gallon": "Gal",
|
||||
"kilowatthour": "KwH",
|
||||
"kilogram": "Kg",
|
||||
"usgallon": "US-Gal",
|
||||
"minutes": "Min"
|
||||
}
|
||||
},
|
||||
"avgfillupqty": "Ø Tankmenge",
|
||||
"avgfillupexpense": "Ø Tankwert",
|
||||
"avgfuelcost": "Ø Spritpreis",
|
||||
"per": "{0} pro {1}",
|
||||
"price": "Preis",
|
||||
"total": "Gesamt",
|
||||
"fulltank": "Voller Tank",
|
||||
"getafulltank": "Hast du vollgetankt?",
|
||||
"by": "Von",
|
||||
"expenses": "Ausgaben",
|
||||
"expensetype": "Ausgaben Typ",
|
||||
"noexpenses": "Keine Ausgaben",
|
||||
"download": "Herunterladen",
|
||||
"title": "Titel",
|
||||
"name": "Name",
|
||||
"delete": "Löschen",
|
||||
"importdata": "Importiere Daten in Hammond",
|
||||
"importdatadesc": "Wähle eine der folgenden Optionen um Daten in Hammond zu importieren",
|
||||
"import": "Importiere",
|
||||
"importcsv": "Wenn du {name} nutzt um deine Fahrzeugdaten zu verwalten, exportiere die CSV Datei aus {name} und klicke hier zum importieren.",
|
||||
"unprocessedquickentries": "Du hast einen Schnelleintrag zum bearbeiten. | Du hast {0} Schnelleinträge zum bearbeiten.",
|
||||
"show": "Anzeigen",
|
||||
"loginerror": "Bei der Anmeldung ist ein Fehler aufgetreten. {msg}",
|
||||
"showunprocessed": "Zeige unbearbeitete",
|
||||
"unprocessed": "unbearbeitet",
|
||||
"sitesettingdesc": "Ändere die globalen Einstellungen. Diese werden als Standard für neue Benutzer verwendet.",
|
||||
"areyousure": "Bist du dir sicher?",
|
||||
"adduser": "Benutzer hinzufügen",
|
||||
"usercreatedsuccessfully": "Benutzer erfolgreich gespeichert",
|
||||
"role": "Rolle",
|
||||
"created": "Erstellt",
|
||||
"createnewuser": "Erstelle neuen Benutzer",
|
||||
"cancel": "Abbrechen",
|
||||
"novehicles": "Du hast noch kein Fahrzeug erstellt. Lege jetzt einen Eintrag für das zu Verwaltende Auto an.",
|
||||
"processed": "Bearbeitet",
|
||||
"notfound": "Nicht gefunden",
|
||||
"timeout": "The page timed out while loading. Are you sure you're still connected to\nthe Internet?",
|
||||
"clicktoselect": "Klicke zum auswählen...",
|
||||
"expenseby": "Ausgabe von",
|
||||
"selectvehicle": "Wähle ein Fahrzeug aus",
|
||||
"expensedate": "Datum der Ausgabe",
|
||||
"totalamountpaid": "Gezahlter Gesamtbetrag",
|
||||
"fillmoredetails": "Weitere Details ausfüllen",
|
||||
"markquickentryprocessed": "Markiere gewählten Schnelleintrag als bearbeitet",
|
||||
"referquickentry": "Wähle Schnelleintrag",
|
||||
"deletequickentry": "Willst du diesen Schnelleintrag wirklcih Löschen? Diese Aktion kann nicht rückgängig gemacht werden.",
|
||||
"fuelunit": "Kraftstoffeinheit",
|
||||
"fillingstation": "Tankstelle",
|
||||
"comments": "Kommentare",
|
||||
"missfillupbefore": "Hast du vergessen die vorherige Tankfüllung zu erfassen?",
|
||||
"fillupdate": "Tankdatum",
|
||||
"fillupsavedsuccessfully": "Tankfüllung erfolgreich gespeichert",
|
||||
"expensesavedsuccessfully": "Ausgabe erfolgreich gespeichert",
|
||||
"vehiclesavedsuccessfully": "Fahrzeug erfolgreich gespeichert",
|
||||
"back": "Zurück",
|
||||
"nickname": "Bezeichnung",
|
||||
"registration": "Nummernschild",
|
||||
"createvehicle": "Fahrzeug erstellen",
|
||||
"make": "Marke",
|
||||
"model": "Modell",
|
||||
"yearmanufacture": "Jahr der Erstzulassung",
|
||||
"enginesize": "Hubraum (in cc)",
|
||||
"testconn": "Teste Verbindung",
|
||||
"migrate": "Migrieren",
|
||||
"init": {
|
||||
"migrateclarkson": "Migriere von Clarkson",
|
||||
"migrateclarksondesc": "Wenn du bereits eine Instanz von Clarkson verwendest und die Daten migrieren möchtest, klicke hier.",
|
||||
"freshinstall": "Frische Installation",
|
||||
"freshinstalldesc": "Wenn du eine neue Installation von Hammond starten möchtest, klicke hier.",
|
||||
"clarkson": {
|
||||
"desc": "<p>Zuerst musst du sicherstellen, dass das Deployment von Hammond die von Clarkson verwendete MySQL Datenbank erreichen kann.</p><p>Wenn dies nicht möglich ist kannst du eine Kopie erstellen die für Hammond erreichbar ist.</p><p>Wenn das erledigt ist, füge hier den Connection String im folgenden Format ein.</p><p>Alle aus Clarkson importierten Nutzer bekommen ihren Benutzernamen als E-Mail und das Passwort wird geändert zu <span class='' style='font-weight:bold'>hammond</span></p><code>user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local</code><br/><br/>",
|
||||
"success": "Deine Daten wurden erfolgreich von Clarkson migriert. Du wirst in kürze zur Anmeldung weitergeleitet wo du dich mit deiner E-Mail und dem passwort `hammond` anmelden kannst."
|
||||
},
|
||||
"fresh": {
|
||||
"setupadminuser": "Erstelle einen Administrator",
|
||||
"yourpassword": "Dein Passwort",
|
||||
"youremail": "Deine E-Mail Adresse",
|
||||
"yourname": "Dein Name",
|
||||
"success": "Du hast dich erfolgreich registriert. Du wirst in kürze zur Anmeldung weitergeleitet und kannst Anfangen Hammond zu verwenden."
|
||||
}
|
||||
},
|
||||
"profile": "Profil",
|
||||
"processedon": "Bearbeitet am",
|
||||
"enable": "Entsperren",
|
||||
"disable": "Sperren",
|
||||
"confirm": "Bestätigen",
|
||||
"labelforfile": "Bezeichnung für diese Datei"
|
||||
}
|
||||
200
ui/src/locales/en.json
Normal file
200
ui/src/locales/en.json
Normal file
@@ -0,0 +1,200 @@
|
||||
{
|
||||
"quickentry": "No Quick Entries | Quick Entry | Quick Entries",
|
||||
"statistics": "Statistics",
|
||||
"thisweek": "This week",
|
||||
"thismonth": "This month",
|
||||
"pastxdays": "Past one day | Past {count} days",
|
||||
"pastxmonths": "Past one month | Past {count} months",
|
||||
"thisyear": "This year",
|
||||
"alltime": "All Time",
|
||||
"noattachments": "No Attachments so far",
|
||||
"attachments": "Anhänge",
|
||||
"choosefile": "Choose File",
|
||||
"addattachment": "Add Attachment",
|
||||
"sharedwith": "Shared with",
|
||||
"share": "Share",
|
||||
"you": "You",
|
||||
"addfillup": "Add Fillup",
|
||||
"createfillup": "Create Fillup",
|
||||
"deletefillup": "Lösche diese Tankfüllung",
|
||||
"addexpense": "Add Expense",
|
||||
"createexpense": "Create Expense",
|
||||
"deleteexpense": "Delete this expense",
|
||||
"nofillups": "No Fillups so far",
|
||||
"transfervehicle": "Transfer Vehicle",
|
||||
"settingssaved": "Settings saved successfully",
|
||||
"yoursettings": "Your Settings",
|
||||
"settings": "Settings",
|
||||
"changepassword": "Change password",
|
||||
"oldpassword": "Old password",
|
||||
"newpassword": "New password",
|
||||
"repeatnewpassword": "Repeat New Password",
|
||||
"passworddontmatch": "Password values don't match",
|
||||
"save": "Save",
|
||||
"supportthedeveloper": "Support the developer",
|
||||
"buyhimabeer": "Buy him a beer!",
|
||||
"featurerequest": "Feature Request",
|
||||
"foundabug": "Found a bug",
|
||||
"currentversion": "Current Version",
|
||||
"moreinfo": "More Info",
|
||||
"currency": "Currency",
|
||||
"distanceunit": "Distance Unit",
|
||||
"dateformat": "Date Format",
|
||||
"createnow": "Create Now",
|
||||
"yourvehicles": "Your Vehicles",
|
||||
"menu": {
|
||||
"quickentries": "Quick Entries",
|
||||
"logout": "Log out",
|
||||
"import": "Import",
|
||||
"home": "Home",
|
||||
"settings": "Settings",
|
||||
"admin": "Admin",
|
||||
"sitesettings": "Site Settings",
|
||||
"users": "Users",
|
||||
"login": "Log in"
|
||||
},
|
||||
"enterusername": "Enter your username",
|
||||
"enterpassword": "Enter your password",
|
||||
"email": "Email",
|
||||
"password": "Password",
|
||||
"login": "log in",
|
||||
"totalexpenses": "Total Expenses",
|
||||
"fillupcost": "Fillup Costs",
|
||||
"otherexpenses": "Other Expenses",
|
||||
"addvehicle": "Add Vehicle",
|
||||
"editvehicle": "Edit Vehicle",
|
||||
"deletevehicle": "Delete Vehicle",
|
||||
"sharevehicle": "Share vehicle",
|
||||
"makeowner": "Make Owner",
|
||||
"lastfillup": "Last Fillup",
|
||||
"quickentrydesc": "Take a pic of the invoice or the fuel pump display to make an entry later.",
|
||||
"quickentrycreatedsuccessfully": "Quick Entry Created Successfully",
|
||||
"uploadfile": "Upload File",
|
||||
"uploadphoto": "Upload Photo",
|
||||
"details": "Details",
|
||||
"odometer": "Odometer",
|
||||
"language": "Language",
|
||||
"date": "Date",
|
||||
"pastfillups": "Past Fillups",
|
||||
"fuelsubtype": "Fuel Subtype",
|
||||
"fueltype": "Fuel Type",
|
||||
"quantity": "Quantity",
|
||||
"gasstation": "Gas Station",
|
||||
"fuel": {
|
||||
"Petrol": "Petrol",
|
||||
"Diesel": "Diesel",
|
||||
"CNG": "CNG",
|
||||
"LPG": "LPG",
|
||||
"Electric": "Electric",
|
||||
"Ethanol": "Ethanol"
|
||||
},
|
||||
"unit": {
|
||||
"long": {
|
||||
"litre": "Litre",
|
||||
"gallon": "Gallon",
|
||||
"kilowatthour": "Kilowatt Hour",
|
||||
"kilogram": "Kilogram",
|
||||
"usgallon": "US Gallon",
|
||||
"minutes": "Minutes"
|
||||
},
|
||||
"short": {
|
||||
"litre": "Lt",
|
||||
"gallon": "Gal",
|
||||
"kilowatthour": "KwH",
|
||||
"kilogram": "Kg",
|
||||
"usgallon": "US Gal",
|
||||
"minutes": "Mins"
|
||||
}
|
||||
},
|
||||
"avgfillupqty": "Avg Fillup Qty",
|
||||
"avgfillupexpense": "Avg Fillup Expense",
|
||||
"avgfuelcost": "Avg Fuel Cost",
|
||||
"per": "{0} per {1}",
|
||||
"price": "Price",
|
||||
"total": "Total",
|
||||
"fulltank": "Tank Full",
|
||||
"getafulltank": "Did you get a full tank?",
|
||||
"by": "By",
|
||||
"expenses": "Expenses",
|
||||
"expensetype": "Expense Type",
|
||||
"noexpenses": "No Expenses so far",
|
||||
"download": "Download",
|
||||
"title": "Title",
|
||||
"name": "Name",
|
||||
"delete": "Delete",
|
||||
"importdata": "Import data into Hammond",
|
||||
"importdatadesc": "Choose from the following options to import data into Hammond",
|
||||
"import": "Import",
|
||||
"importcsv": "If you have been using {name} to store your vehicle data, export the CSV file from {name} and click here to import.",
|
||||
"unprocessedquickentries": "You have one quick entry to be processed. | You have {0} quick entries pending to be processed.",
|
||||
"show": "Show",
|
||||
"loginerror": "There was an error logging in to your account. {msg}",
|
||||
"showunprocessed": "Show unprocessed only",
|
||||
"unprocessed": "unprocessed",
|
||||
"sitesettingdesc": "Update site level settings. These will be used as default values for new users.",
|
||||
"areyousure": "Are you sure you want to do this?",
|
||||
"adduser": "Add User",
|
||||
"usercreatedsuccessfully": "User Created Successfully",
|
||||
"userdisabledsuccessfully": "User disabled successfully",
|
||||
"userenabledsuccessfully": "User enabled successfully",
|
||||
"role": "Role",
|
||||
"created": "Created",
|
||||
"createnewuser": "Create New User",
|
||||
"cancel": "Cancel",
|
||||
"novehicles": "It seems you have not yet created a vehicle in the system. Start by creating an entry for one of the vehicles you want to track.",
|
||||
"processed": "Mark Processed",
|
||||
"notfound": "Not Found",
|
||||
"timeout": "The page timed out while loading. Are you sure you're still connected to\nthe Internet?",
|
||||
"clicktoselect": "Click to select...",
|
||||
"expenseby": "Expense by",
|
||||
"selectvehicle": "Select a vehicle",
|
||||
"expensedate": "Expense Date",
|
||||
"totalamountpaid": "Total Amount Paid",
|
||||
"fillmoredetails": "Fill more details",
|
||||
"markquickentryprocessed": "Mark selected Quick Entry as processed",
|
||||
"referquickentry": "Refer quick entry",
|
||||
"deletequickentry": "This will delete this Quick Entry. This step cannot be reversed. Are you sure?",
|
||||
"fuelunit": "Fuel Unit",
|
||||
"fillingstation": "Filling Station Name",
|
||||
"comments": "Comments",
|
||||
"missfillupbefore": "Did you miss the fillup entry before this one?",
|
||||
"fillupdate": "Fillup Date",
|
||||
"fillupsavedsuccessfully": "Fillup Saved Successfully",
|
||||
"expensesavedsuccessfully": "Expense Saved Successfully",
|
||||
"vehiclesavedsuccessfully": "Vehicle Saved Successfully",
|
||||
"settingssavedsuccessfully": "Settings saved successfully",
|
||||
"back": "Back",
|
||||
"nickname": "Nickname",
|
||||
"registration": "Registration",
|
||||
"createvehicle": "Create Vehicle",
|
||||
"make": "Make / Company",
|
||||
"model": "Model",
|
||||
"yearmanufacture": "Year of Manufacture",
|
||||
"enginesize": "Engine Size (in cc)",
|
||||
"mysqlconnstr": "Mysql Connection String",
|
||||
"testconn": "Test Connection",
|
||||
"migrate": "Migrate",
|
||||
"init": {
|
||||
"migrateclarkson": "Migrate from Clarkson",
|
||||
"migrateclarksondesc": "If you have an existing Clarkson deployment and you want to migrate your data from that, press the following button.",
|
||||
"freshinstall": "Fresh Install",
|
||||
"freshinstalldesc": "If you want a fresh install of Hammond, press the following button.",
|
||||
"clarkson": {
|
||||
"desc": "<p>You need to make sure that this deployment of Hammond can access the MySQL database used by Clarkson.</p><p>If that is not directly possible, you can make a copy of that database somewhere accessible from this instance.</p><p>Once that is done, enter the connection string to the MySQL instance in the following format.</p><p>All the users imported from Clarkson will have their username as their email in Clarkson database and pasword set to<span class='' style='font-weight:bold'>hammond</span></p><code>user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local</code><br/><br/>",
|
||||
"success": "We have successfully migrated the data from Clarkson. You will be redirected to the login screen shortly where you can login using your existing email and password : hammond"
|
||||
},
|
||||
"fresh": {
|
||||
"setupadminuser": "Setup Admin Users",
|
||||
"yourpassword": "Your Password",
|
||||
"youremail": "Your Email",
|
||||
"yourname": "Your Name",
|
||||
"success": "You have been registered successfully. You will be redirected to the login screen shortly where you can login and start using the system."
|
||||
}
|
||||
},
|
||||
"profile": "Profile",
|
||||
"processedon": "Processed on",
|
||||
"enable": "Enable",
|
||||
"disable": "Disable",
|
||||
"confirm": "Go Ahead",
|
||||
"labelforfile": "Label for this file"
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
faTimesCircle,
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
|
||||
import i18n from './i18n';
|
||||
|
||||
import App from './app.vue'
|
||||
|
||||
@@ -54,6 +55,7 @@ library.add(
|
||||
faUserFriends,
|
||||
faTimesCircle
|
||||
)
|
||||
|
||||
Vue.use(Buefy, {
|
||||
defaultIconComponent: 'vue-fontawesome',
|
||||
defaultIconPack: 'fas',
|
||||
@@ -73,6 +75,7 @@ const app = new Vue({
|
||||
store,
|
||||
|
||||
render: (h) => h(App),
|
||||
i18n,
|
||||
}).$mount('#app')
|
||||
|
||||
// If running e2e tests...
|
||||
|
||||
@@ -23,7 +23,7 @@ export default {
|
||||
<template v-if="resource">
|
||||
{{ resource }}
|
||||
</template>
|
||||
Not Found
|
||||
{{ $t('notfound') }}
|
||||
</h1>
|
||||
</Layout>
|
||||
</template>
|
||||
|
||||
@@ -32,8 +32,7 @@ export default {
|
||||
<template>
|
||||
<Layout v-if="offlineConfirmed">
|
||||
<h1 :class="$style.title">
|
||||
The page timed out while loading. Are you sure you're still connected to
|
||||
the Internet?
|
||||
{{ $t('timeout') }}
|
||||
</h1>
|
||||
</Layout>
|
||||
<LoadingView v-else />
|
||||
|
||||
@@ -95,7 +95,7 @@ export default {
|
||||
.put(`/api/vehicles/${this.selectedVehicle.id}/expenses/${this.expense.id}`, this.expenseModel)
|
||||
.then((data) => {
|
||||
this.$buefy.toast.open({
|
||||
message: 'Expense Updated Successfully',
|
||||
message: this.$t('expensesavedsuccessfully'),
|
||||
type: 'is-success',
|
||||
duration: 3000,
|
||||
})
|
||||
@@ -120,7 +120,7 @@ export default {
|
||||
.post(`/api/vehicles/${this.selectedVehicle.id}/expenses`, this.expenseModel)
|
||||
.then((data) => {
|
||||
this.$buefy.toast.open({
|
||||
message: 'Expense Created Successfully',
|
||||
message: this.$t('expensesavedsuccessfully'),
|
||||
type: 'is-success',
|
||||
duration: 3000,
|
||||
})
|
||||
@@ -152,7 +152,7 @@ export default {
|
||||
<Layout>
|
||||
<div class="columns">
|
||||
<div class="column is-two-thirds">
|
||||
<h1 class="title">Create Expense</h1>
|
||||
<h1 class="title">{{ $t('createexpense') }}</h1>
|
||||
<h1 class="subtitle">
|
||||
{{ [selectedVehicle.nickname, selectedVehicle.registration, selectedVehicle.make, selectedVehicle.model].join(' | ') }}
|
||||
</h1>
|
||||
@@ -162,41 +162,41 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
<form @submit.prevent="createExpense">
|
||||
<b-field label="Select a vehicle">
|
||||
<b-select v-model="selectedVehicle" placeholder="Vehicle" required expanded :disabled="expense.id">
|
||||
<b-field :label="this.$t('selectvehicle')">
|
||||
<b-select v-model="selectedVehicle" :placeholder="this.$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="Expense by">
|
||||
<b-select v-model="expenseModel.userId" placeholder="User" required expanded :disabled="expense.id">
|
||||
<b-field :label="this.$t('expenseby')">
|
||||
<b-select v-model="expenseModel.userId" :placeholder="this.$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="Expense Date">
|
||||
<b-field :label="this.$t('expensedate')">
|
||||
<b-datepicker
|
||||
v-model="expenseModel.date"
|
||||
:date-formatter="formatDate"
|
||||
placeholder="Click to select..."
|
||||
:placeholder="this.$t('clicktoselect')"
|
||||
icon="calendar"
|
||||
:max-date="new Date()"
|
||||
>
|
||||
</b-datepicker>
|
||||
</b-field>
|
||||
<b-field label="Expense Type*">
|
||||
<b-field :label="this.$t('expensetype') + `*`">
|
||||
<b-input v-model="expenseModel.expenseType" expanded required></b-input>
|
||||
</b-field>
|
||||
|
||||
<b-field label="Total Amount Paid">
|
||||
<b-field :label="this.$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="Odometer Reading">
|
||||
<b-field :label="this.$t('odometer')">
|
||||
<p class="control">
|
||||
<span class="button is-static">{{ me.distanceUnitDetail.short }}</span>
|
||||
</p>
|
||||
@@ -204,19 +204,19 @@ export default {
|
||||
</b-field>
|
||||
|
||||
<b-field>
|
||||
<b-switch v-model="showMore">Fill more details</b-switch>
|
||||
<b-switch v-model="showMore">{{ $t('fillmoredetails') }}</b-switch>
|
||||
</b-field>
|
||||
<fieldset v-if="showMore">
|
||||
<b-field label="Comments">
|
||||
<b-field :label="this.$t('details')">
|
||||
<b-input v-model="expenseModel.comments" type="textarea" expanded></b-input>
|
||||
</b-field>
|
||||
</fieldset>
|
||||
<b-field>
|
||||
<b-switch v-if="quickEntry" v-model="processQuickEntry">Mark selected Quick Entry as processed</b-switch>
|
||||
<b-switch v-if="quickEntry" v-model="processQuickEntry">{{ $t('markquickentryprocessed') }}</b-switch>
|
||||
</b-field>
|
||||
<br />
|
||||
<b-field>
|
||||
<b-button tag="input" native-type="submit" :disabled="tryingToCreate" type="is-primary" label="Create Expense" expanded> </b-button>
|
||||
<b-button tag="input" native-type="submit" :value="this.$t('save')" :disabled="tryingToCreate" type="is-primary" label="Create Expense" expanded> </b-button>
|
||||
</b-field>
|
||||
</form>
|
||||
</Layout>
|
||||
|
||||
@@ -126,7 +126,7 @@ export default {
|
||||
.put(`/api/vehicles/${this.selectedVehicle.id}/fillups/${this.fillup.id}`, this.fillupModel)
|
||||
.then((data) => {
|
||||
this.$buefy.toast.open({
|
||||
message: 'Fillup Updated Successfully',
|
||||
message: this.$t('fillupsavedsuccessfully'),
|
||||
type: 'is-success',
|
||||
duration: 3000,
|
||||
})
|
||||
@@ -153,7 +153,7 @@ export default {
|
||||
.post(`/api/vehicles/${this.selectedVehicle.id}/fillups`, this.fillupModel)
|
||||
.then((data) => {
|
||||
this.$buefy.toast.open({
|
||||
message: 'Fillup Created Successfully',
|
||||
message: this.$t('fillupsavedsuccessfully'),
|
||||
type: 'is-success',
|
||||
duration: 3000,
|
||||
})
|
||||
@@ -181,46 +181,44 @@ export default {
|
||||
|
||||
<template>
|
||||
<Layout>
|
||||
<div class="has-text-centered">
|
||||
<div class="columns">
|
||||
<div class="column is-two-thirds">
|
||||
<h1 class="title">Create Fillup</h1>
|
||||
<h1 class="subtitle">
|
||||
{{ [selectedVehicle.nickname, selectedVehicle.registration, selectedVehicle.make, selectedVehicle.model].join(' | ') }}
|
||||
</h1>
|
||||
</div>
|
||||
<div class="column is-one-thirds">
|
||||
<QuickEntryDisplay v-model="quickEntry" :user="user" />
|
||||
</div>
|
||||
<div class="columns">
|
||||
<div class="column is-two-thirds">
|
||||
<h1 class="title">{{ $t('createfillup') }}</h1>
|
||||
<h1 class="subtitle">
|
||||
{{ [selectedVehicle.nickname, selectedVehicle.registration, selectedVehicle.make, selectedVehicle.model].join(' | ') }}
|
||||
</h1>
|
||||
</div>
|
||||
<div class="column is-one-thirds">
|
||||
<QuickEntryDisplay v-model="quickEntry" :user="user" />
|
||||
</div>
|
||||
</div>
|
||||
<form class="" @submit.prevent="createFillup">
|
||||
<b-field label="Select a vehicle">
|
||||
<b-select v-model="selectedVehicle" placeholder="Vehicle" required expanded :disabled="fillup.id">
|
||||
<b-field :label="this.$t('selectvehicle')">
|
||||
<b-select v-model="selectedVehicle" :placeholder="this.$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="Expense by">
|
||||
<b-select v-model="fillupModel.userId" placeholder="User" required expanded :disabled="fillup.id">
|
||||
<b-field :label="this.$t('expenseby')">
|
||||
<b-select v-model="fillupModel.userId" :placeholder="this.$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="Fillup Date">
|
||||
<b-field :label="this.$t('fillupdate')">
|
||||
<b-datepicker
|
||||
v-model="fillupModel.date"
|
||||
:date-formatter="formatDate"
|
||||
placeholder="Click to select..."
|
||||
placeholder="this.$t('clicktoselect')"
|
||||
icon="calendar"
|
||||
trap-focus
|
||||
:max-date="new Date()"
|
||||
>
|
||||
</b-datepicker>
|
||||
</b-field>
|
||||
<b-field label="Fuel Subtype">
|
||||
<b-field :label="this.$t('fuelsubtype')">
|
||||
<b-autocomplete
|
||||
v-model="fillupModel.fuelSubType"
|
||||
:data="filteredFuelSubtypes"
|
||||
@@ -231,55 +229,55 @@ export default {
|
||||
>
|
||||
</b-autocomplete>
|
||||
</b-field>
|
||||
<b-field label="Quantity*" addons>
|
||||
<b-field :label="this.$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="Fuel Unit" required>
|
||||
<b-select v-model="fillupModel.fuelUnit" :placeholder="this.$t('fuelunit')" required>
|
||||
<option v-for="(option, key) in fuelUnitMasters" :key="key" :value="key">
|
||||
{{ option.long }}
|
||||
{{ $t('unit.long.' + option.long) }}
|
||||
</option>
|
||||
</b-select>
|
||||
</b-field>
|
||||
<b-field :label="'Price per ' + vehicle.fuelUnitDetail.short + '*'"
|
||||
<b-field :label="this.$t('per', { '0': this.$t('price'), '1': vehicle.fuelUnitDetail.short })"
|
||||
><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="Total Amount Paid">
|
||||
<b-field :label="this.$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="Odometer Reading">
|
||||
<b-field :label="this.$t('odometer')">
|
||||
<p class="control">
|
||||
<span class="button is-static">{{ me.distanceUnitDetail.short }}</span>
|
||||
</p>
|
||||
<b-input v-model.number="fillupModel.odoReading" type="number" min="0" expanded required></b-input>
|
||||
</b-field>
|
||||
<b-field>
|
||||
<b-checkbox v-model="fillupModel.isTankFull">Did you get a full tank?</b-checkbox>
|
||||
<b-checkbox v-model="fillupModel.isTankFull">{{ $t('getafulltank') }}</b-checkbox>
|
||||
</b-field>
|
||||
<b-field>
|
||||
<b-checkbox v-model="fillupModel.hasMissedFillup">Did you miss the fillup entry before this one?</b-checkbox>
|
||||
<b-checkbox v-model="fillupModel.hasMissedFillup">{{ $t('missfillupbefore') }}</b-checkbox>
|
||||
</b-field>
|
||||
<b-field>
|
||||
<b-switch v-model="showMore">Fill more details</b-switch>
|
||||
<b-switch v-model="showMore">{{ $t('fillmoredetails') }}</b-switch>
|
||||
</b-field>
|
||||
<fieldset v-if="showMore">
|
||||
<b-field label="Filling Station Name">
|
||||
<b-field :label="this.$t('fillingstation')">
|
||||
<b-input v-model="fillupModel.fillingStation" type="text" expanded></b-input>
|
||||
</b-field>
|
||||
<b-field label="Comments">
|
||||
<b-field :label="this.$t('comments')">
|
||||
<b-input v-model="fillupModel.comments" type="textarea" expanded></b-input>
|
||||
</b-field>
|
||||
</fieldset>
|
||||
<b-field>
|
||||
<b-switch v-if="quickEntry" v-model="processQuickEntry">Mark selected Quick Entry as processed</b-switch>
|
||||
<b-switch v-if="quickEntry" v-model="processQuickEntry">{{ $t('markquickentryprocessed') }}</b-switch>
|
||||
</b-field>
|
||||
<br />
|
||||
<b-field>
|
||||
<b-button tag="input" native-type="submit" :disabled="tryingToCreate" type="is-primary" label="Create Fillup" expanded> </b-button>
|
||||
<b-button tag="input" native-type="submit" :disabled="tryingToCreate" type="is-primary" :value="this.$t('save')" :label="this.$t('createfillup')" expanded> </b-button>
|
||||
<p v-if="authError">
|
||||
There was an error logging in to your account.
|
||||
</p>
|
||||
|
||||
@@ -74,7 +74,7 @@ export default {
|
||||
.put(`/api/vehicles/${this.vehicle.id}`, this.vehicleModel)
|
||||
.then((data) => {
|
||||
this.$buefy.toast.open({
|
||||
message: 'Vehicle Updated Successfully',
|
||||
message: this.$t('vehiclesavedsuccessfully'),
|
||||
type: 'is-success',
|
||||
duration: 3000,
|
||||
})
|
||||
@@ -96,7 +96,7 @@ export default {
|
||||
.post(`/api/vehicles`, this.vehicleModel)
|
||||
.then((data) => {
|
||||
this.$buefy.toast.open({
|
||||
message: 'Vehicle Created Successfully',
|
||||
message: this.$t('vehiclesavedsuccessfully'),
|
||||
type: 'is-success',
|
||||
duration: 3000,
|
||||
})
|
||||
@@ -123,57 +123,57 @@ export default {
|
||||
<Layout>
|
||||
<div class="columns">
|
||||
<div class="column is-three-quarters">
|
||||
<h1 class="title">Create Vehicle</h1>
|
||||
<h1 class="title">{{ $t('createvehicle') }}</h1>
|
||||
</div>
|
||||
<div class="column is-one-quarter">
|
||||
<router-link tag="b-button" type="is-primary" to="/">
|
||||
Back to Vehicle
|
||||
{{ $t('back') }}
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
<form @submit.prevent="createVehicle">
|
||||
<b-field label="Nickname*">
|
||||
<b-field :label="this.$t('nickname') + `*`">
|
||||
<b-input v-model="vehicleModel.nickname" type="text" expanded required></b-input>
|
||||
</b-field>
|
||||
<b-field label="Registration*">
|
||||
<b-field :label="this.$t('registration') + `*`">
|
||||
<b-input v-model="vehicleModel.registration" type="text" expanded required></b-input>
|
||||
</b-field>
|
||||
<b-field label="Fuel Type*">
|
||||
<b-select v-model.number="vehicleModel.fuelType" placeholder="Fuel Type" required expanded>
|
||||
<b-field :label="this.$t('fueltype') + `*`">
|
||||
<b-select v-model.number="vehicleModel.fuelType" :placeholder="this.$t('fueltype')" required expanded>
|
||||
<option v-for="(option, key) in fuelTypeMasters" :key="key" :value="key">
|
||||
{{ option.long }}
|
||||
{{ $t('fuel.' + option.long) }}
|
||||
</option>
|
||||
</b-select>
|
||||
</b-field>
|
||||
|
||||
<b-field label="Fuel Unit*">
|
||||
<b-select v-model.number="vehicleModel.fuelUnit" placeholder="Fuel Unit" required expanded>
|
||||
<b-field :label="this.$t('fuelunit') + `*`">
|
||||
<b-select v-model.number="vehicleModel.fuelUnit" :placeholder="this.$t('fuelunit')" required expanded>
|
||||
<option v-for="(option, key) in fuelUnitMasters" :key="key" :value="key">
|
||||
{{ option.long }}
|
||||
{{ $t('unit.long.' + option.long) }}
|
||||
</option>
|
||||
</b-select>
|
||||
</b-field>
|
||||
|
||||
<b-field label="Make / Company*">
|
||||
<b-field :label="this.$t('make') + `*`">
|
||||
<b-input v-model="vehicleModel.make" type="text" required expanded></b-input>
|
||||
</b-field>
|
||||
<b-field label="Model*">
|
||||
<b-field :label="this.$t('model') + `*`">
|
||||
<b-input v-model="vehicleModel.model" type="text" required expanded></b-input>
|
||||
</b-field>
|
||||
<b-field label="Year Of Manufacture">
|
||||
<b-field :label="this.$t('yearmanufacture') + `*`">
|
||||
<b-input v-model.number="vehicleModel.yearOfManufacture" type="number" expanded number></b-input>
|
||||
</b-field>
|
||||
<b-field label="Engine Size (in cc)">
|
||||
<b-field :label="this.$t('yearmanufacture')">
|
||||
<b-input v-model.number="vehicleModel.engineSize" type="number" expanded number></b-input>
|
||||
</b-field>
|
||||
|
||||
<br />
|
||||
<b-field>
|
||||
<b-button tag="input" native-type="submit" :disabled="tryingToCreate" type="is-primary" label="Create Vehicle" expanded>
|
||||
<b-button tag="input" native-type="submit" :disabled="tryingToCreate" type="is-primary" :value="this.$t('save')" :label="this.$t('createvehicle')" expanded>
|
||||
<BaseIcon v-if="tryingToCreate" name="sync" spin />
|
||||
</b-button>
|
||||
<p v-if="authError">
|
||||
There was an error logging in to your account.
|
||||
{{ $t('loginerror') }}
|
||||
</p>
|
||||
</b-field>
|
||||
</form>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script>
|
||||
import currencyFormtter from 'currency-formatter'
|
||||
import currencyFormatter from 'currency-formatter'
|
||||
|
||||
import appConfig from '@src/app.config'
|
||||
import Layout from '@layouts/main.vue'
|
||||
@@ -53,7 +53,7 @@ export default {
|
||||
return parseAndFormatDate(date)
|
||||
},
|
||||
formatCurrency(number) {
|
||||
return currencyFormtter.format(number, { code: this.me.currency })
|
||||
return currencyFormatter.format(number, { code: this.me.currency })
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -62,14 +62,13 @@ export default {
|
||||
<template>
|
||||
<Layout>
|
||||
<b-notification v-if="myVehicles.length === 0" type="is-warning is-light" :closable="false">
|
||||
<div class="columns">
|
||||
<div class="columns is-three-quarters">
|
||||
<div class="column">
|
||||
It seems you have not yet created a vehicle in the system. Start by creating an entry for
|
||||
one of the vehicles you want to track.
|
||||
{{ $t('novehicles') }}
|
||||
</div>
|
||||
<div class="column" :class="!isMobile ? 'has-text-right' : ''">
|
||||
<div class="column is-one-quarter" :class="!isMobile ? 'has-text-right' : ''">
|
||||
<b-button type="is-warning" class="" tag="router-link" :to="`/vehicles/create`"
|
||||
>Create Now</b-button
|
||||
>{{ $t('createnow') }}</b-button
|
||||
></div
|
||||
>
|
||||
</div>
|
||||
@@ -81,15 +80,11 @@ export default {
|
||||
>
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
{{
|
||||
`You have ${unprocessedQuickEntries.length} quick ${
|
||||
unprocessedQuickEntries.length === 1 ? 'entry' : 'entries'
|
||||
} pending to be processed.`
|
||||
}}
|
||||
{{ $tc('unprocessedquickentries', unprocessedQuickEntries.length, { '0': unprocessedQuickEntries.length }) }}
|
||||
</div>
|
||||
<div class="column" :class="!isMobile ? 'has-text-right' : ''">
|
||||
<b-button type="is-warning" class="is-small" tag="router-link" :to="`/quickEntries`"
|
||||
>Process Now</b-button
|
||||
>{{ $t('show') }}</b-button
|
||||
></div
|
||||
>
|
||||
</div>
|
||||
@@ -99,10 +94,10 @@ export default {
|
||||
<br />
|
||||
<section>
|
||||
<div class="columns" :class="isMobile ? 'has-text-centered' : ''"
|
||||
><div class="column is-three-quarters"> <h1 class="title">Your Vehicles</h1></div>
|
||||
><div class="column is-three-quarters"> <h1 class="title">{{ $t('yourvehicles') }}</h1></div>
|
||||
<div class="column is-one-quarter buttons" :class="!isMobile ? 'has-text-right' : ''">
|
||||
<b-button type="is-primary" tag="router-link" :to="`/vehicles/create`"
|
||||
>Add Vehicle</b-button
|
||||
>{{ $t('addvehicle') }}</b-button
|
||||
>
|
||||
</div></div
|
||||
>
|
||||
@@ -125,7 +120,7 @@ export default {
|
||||
<div class="content">
|
||||
<table class="table">
|
||||
<div class="columns">
|
||||
<div class="column is-one-third">Last Fillup</div>
|
||||
<div class="column is-one-third">{{ $t('lastfillup') }}</div>
|
||||
<div class="column"
|
||||
>{{ formatDate(vehicle.fillups[0].date) }} <br />
|
||||
{{ `${formatCurrency(vehicle.fillups[0].totalAmount)}` }} ({{
|
||||
@@ -136,7 +131,7 @@ export default {
|
||||
</div>
|
||||
|
||||
<div class="columns">
|
||||
<div class="column is-one-third">Odometer</div>
|
||||
<div class="column is-one-third">{{ $t('odometer') }}</div>
|
||||
<div class="column">
|
||||
<template v-if="vehicle.fillups.length">
|
||||
{{ vehicle.fillups[0].odoReading }} {{
|
||||
@@ -150,12 +145,12 @@ export default {
|
||||
</div>
|
||||
<footer class="card-footer">
|
||||
<router-link class="card-footer-item" :to="'/vehicles/' + vehicle.id">
|
||||
Details
|
||||
{{ $t('details') }}
|
||||
</router-link>
|
||||
<router-link class="card-footer-item" :to="`/vehicles/${vehicle.id}/fillup`">
|
||||
Add Fillup </router-link
|
||||
{{ $t('addfillup') }} </router-link
|
||||
><router-link class="card-footer-item" :to="`/vehicles/${vehicle.id}/expense`">
|
||||
Add Expense
|
||||
{{ $t('addexpense') }}
|
||||
</router-link>
|
||||
</footer>
|
||||
</b-collapse>
|
||||
|
||||
@@ -20,17 +20,17 @@ export default {
|
||||
<Layout>
|
||||
<div class="columns box"
|
||||
><div class="column">
|
||||
<h1 class="title">Import data into Hammond</h1>
|
||||
<p class="subtitle">Choose from the following options to import data into Fuelly</p>
|
||||
<h1 class="title">{{ $t('importdata') }}</h1>
|
||||
<p class="subtitle">{{ $t('importdatadesc') }}</p>
|
||||
</div></div
|
||||
>
|
||||
<br />
|
||||
<div class="columns">
|
||||
<div class="box column is-one-third" to="/import-fuelly">
|
||||
<h1 class="title">Fuelly</h1>
|
||||
<p>If you have been using Fuelly to store your vehicle data, export the CSV file from Fuelly and click here to import.</p>
|
||||
<p>{{ $t('importcsv', { 'name': 'Fuelly' }) }}</p>
|
||||
<br />
|
||||
<b-button type="is-primary" tag="router-link" to="/import/fuelly">Import</b-button>
|
||||
<b-button type="is-primary" tag="router-link" to="/import/fuelly">{{ $t('import') }}</b-button>
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
|
||||
@@ -62,11 +62,11 @@ export default {
|
||||
var message = ''
|
||||
if (this.migrationMode === 'clarkson') {
|
||||
message =
|
||||
'We have successfully migrated the data from Clarkson. You will be redirected to the login screen shortly where you can login using your existing email and password : hammond'
|
||||
this.$t('init.clarkson.success')
|
||||
}
|
||||
if (this.migrationMode === 'fresh') {
|
||||
message =
|
||||
'You have been registered successfully. You will be redirected to the login screen shortly where you can login and start using the system.'
|
||||
this.$t('init.fresh.success')
|
||||
}
|
||||
this.$buefy.toast.open({
|
||||
duration: 10000,
|
||||
@@ -163,68 +163,57 @@ export default {
|
||||
<template>
|
||||
<Layout>
|
||||
<div v-if="!migrationMode" class="box">
|
||||
<h1 class="title">Migrate from Clarkson</h1>
|
||||
<h1 class="title">{{ $t('init.migrateclarkson') }}</h1>
|
||||
<p>
|
||||
If you have an existing Clarkson deployment and you want to migrate your data from that, press the following button.
|
||||
{{ $t('init.migrateclarksondesc') }}
|
||||
</p>
|
||||
<br />
|
||||
<b-field> <b-button type="is-primary" @click="migrationMode = 'clarkson'">Migrate from Clarkson</b-button></b-field>
|
||||
<b-field> <b-button type="is-primary" @click="migrationMode = 'clarkson'">{{ $t('init.migrateclarkson') }}</b-button></b-field>
|
||||
</div>
|
||||
<div v-if="!migrationMode" class="box">
|
||||
<h1 class="title">Fresh Install</h1>
|
||||
<h1 class="title">{{ $t('init.freshinstall') }}</h1>
|
||||
<p>
|
||||
If you want a fresh install of Hammond, press the following button.
|
||||
{{ $t('init.freshinstalldesc') }}
|
||||
</p>
|
||||
<br />
|
||||
<b-field>
|
||||
<b-button type="is-primary" @click="migrationMode = 'fresh'">Fresh Install</b-button>
|
||||
<b-button type="is-primary" @click="migrationMode = 'fresh'">{{ $t('init.freshinstall') }}</b-button>
|
||||
</b-field>
|
||||
</div>
|
||||
<div v-if="migrationMode === 'clarkson'" class="box content">
|
||||
<h1 class="title">Migrate from Clarkson</h1>
|
||||
<p>You need to make sure that this deployment of Hammond can access the MySQL database used by Clarkson.</p>
|
||||
<p>If that is not directly possible, you can make a copy of that database somewhere accessible from this instance.</p>
|
||||
<p>Once that is done, enter the connection string to the MySQL instance in the following format.</p>
|
||||
<p
|
||||
>All the users imported from Clarkson will have their username as their email in Clarkson database and pasword set to
|
||||
<span class="" style="font-weight:bold">hammond</span></p
|
||||
>
|
||||
<code>
|
||||
user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local
|
||||
</code>
|
||||
<br />
|
||||
<br />
|
||||
<h1 class="title">{{ $t('init.migrateclarkson') }}</h1>
|
||||
<p v-html="$t('init.clarkson.desc')"></p>
|
||||
<b-notification v-if="connectionError" type="is-danger" role="alert" :closable="false">
|
||||
{{ connectionError }}
|
||||
</b-notification>
|
||||
|
||||
<b-field addons label="Mysql Connection String">
|
||||
<b-field addons :label="this.$t('mysqlconnstr')">
|
||||
<b-input v-model="url" required></b-input>
|
||||
</b-field>
|
||||
|
||||
<div class="buttons">
|
||||
<b-button v-if="!testSuccess" type="is-primary" :disabled="isWorking" @click="testConnection">Test Connection</b-button
|
||||
><b-button v-if="testSuccess" type="is-success" :disabled="isWorking" @click="migrate">Migrate</b-button>
|
||||
<b-button type="is-danger is-light" @click="resetMigrationMode">Cancel</b-button>
|
||||
<b-button v-if="!testSuccess" type="is-primary" :disabled="isWorking" @click="testConnection">{{ $t('testconn') }}</b-button>
|
||||
<b-button v-if="testSuccess" type="is-success" :disabled="isWorking" @click="migrate">{{ $t('migrate') }}</b-button>
|
||||
<b-button type="is-danger is-light" @click="resetMigrationMode">{{ $t('cancel') }}</b-button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="migrationMode === 'fresh'" class="box content">
|
||||
<h1 class="title">Setup Admin Users</h1>
|
||||
<h1 class="title">{{ $t('init.fresh.setupadminuser') }}</h1>
|
||||
<form @submit.prevent="register">
|
||||
<b-field label="Your Name">
|
||||
<b-field :label="this.$t('init.fresh.yourname')">
|
||||
<b-input v-model="registerModel.name" required></b-input>
|
||||
</b-field>
|
||||
<b-field label="Your Email">
|
||||
<b-field :label="this.$t('init.fresh.youremail')">
|
||||
<b-input v-model="registerModel.email" type="email" required></b-input>
|
||||
</b-field>
|
||||
<b-field label="Your Password">
|
||||
<b-field :label="this.$t('init.fresh.yourpassword')">
|
||||
<b-input v-model="registerModel.password" type="password" required minlength="8" password-reveal></b-input>
|
||||
</b-field>
|
||||
<b-field label="Currency">
|
||||
<b-field :label="this.$t('currency')">
|
||||
<b-autocomplete
|
||||
v-model="registerModel.currency"
|
||||
:custom-formatter="formatCurrency"
|
||||
placeholder="Currency"
|
||||
:placeholder="this.$t('currency')"
|
||||
:data="filteredCurrencyMasters"
|
||||
:keep-first="true"
|
||||
:open-on-focus="true"
|
||||
@@ -232,8 +221,8 @@ export default {
|
||||
@select="(option) => (selected = option)"
|
||||
></b-autocomplete>
|
||||
</b-field>
|
||||
<b-field label="Distance Unit">
|
||||
<b-select v-model.number="registerModel.distanceUnit" placeholder="Distance Unit" required expanded>
|
||||
<b-field :label="this.$t('distanceunit')">
|
||||
<b-select v-model.number="registerModel.distanceUnit" :placeholder="this.$t('distanceunit')" required expanded>
|
||||
<option v-for="(option, key) in distanceUnitMasters" :key="key" :value="key">
|
||||
{{ `${option.long} (${option.short})` }}
|
||||
</option>
|
||||
@@ -241,9 +230,9 @@ export default {
|
||||
</b-field>
|
||||
<br />
|
||||
<div class="buttons">
|
||||
<b-button type="is-primary" native-type="submit" tag="input"></b-button>
|
||||
<b-button type="is-primary" native-type="submit" tag="input" :value="this.$t('save')"></b-button>
|
||||
|
||||
<b-button type="is-danger is-light" @click="resetMigrationMode">Cancel</b-button>
|
||||
<b-button type="is-danger is-light" @click="resetMigrationMode">{{ $t('cancel') }}</b-button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -24,8 +24,8 @@ export default {
|
||||
return process.env.NODE_ENV === 'production'
|
||||
? {}
|
||||
: {
|
||||
username: 'Enter your username',
|
||||
password: 'Enter your password',
|
||||
username: this.$t('enterusername'),
|
||||
password: this.$t('enterpassword'),
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -67,17 +67,17 @@ export default {
|
||||
<template>
|
||||
<Layout>
|
||||
<form @submit.prevent="tryToLogIn">
|
||||
<b-field label="Email"> <b-input v-model="username" tag="b-input" name="username" type="email" :placeholder="placeholders.username"/></b-field>
|
||||
<b-field label="Password">
|
||||
<b-field :label="$t('email')"> <b-input v-model="username" tag="b-input" name="username" type="email" :placeholder="placeholders.username"/></b-field>
|
||||
<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" :disabled="tryingToLogIn" type="is-primary">
|
||||
<b-button tag="input" native-type="submit" :value="$t('login')" :disabled="tryingToLogIn" type="is-primary">
|
||||
<BaseIcon v-if="tryingToLogIn" name="sync" spin />
|
||||
<span v-else>
|
||||
Log in
|
||||
{{ $t('login') }}
|
||||
</span>
|
||||
</b-button>
|
||||
<p v-if="authError"> There was an error logging in to your account. {{ errorMessage }} </p>
|
||||
<p v-if="authError"> {{ $t('loginerror', { msg: errorMessage }) }}</p>
|
||||
</form>
|
||||
</Layout>
|
||||
</template>
|
||||
|
||||
@@ -28,7 +28,7 @@ export default {
|
||||
<h1>
|
||||
<BaseIcon name="user" />
|
||||
{{ user.name }}
|
||||
Profile
|
||||
{{ $t('profile') }}
|
||||
</h1>
|
||||
<pre>{{ user }}</pre>
|
||||
</Layout>
|
||||
|
||||
@@ -41,7 +41,7 @@ export default {
|
||||
store.dispatch('vehicles/setQuickEntryAsProcessed', { id: entry.id }).then((data) => {})
|
||||
},
|
||||
deleteQuickEntry(entry) {
|
||||
var sure = confirm('This will delete this Quick Entry. This step cannot be reversed. Are you sure?')
|
||||
var sure = confirm(this.$t('deletequickentry'))
|
||||
if (sure) {
|
||||
store.dispatch('vehicles/deleteQuickEntry', { id: entry.id }).then((data) => {})
|
||||
}
|
||||
@@ -59,9 +59,9 @@ export default {
|
||||
|
||||
<template>
|
||||
<Layout>
|
||||
<h1 class="title">Quick Entries</h1>
|
||||
<h1 class="title">{{ $tc('quickentry', 2) }}</h1>
|
||||
<b-field>
|
||||
<b-switch v-if="unprocessedQuickEntries.length" v-model="showUnprocessedOnly">Show unprocessed only</b-switch>
|
||||
<b-switch v-if="unprocessedQuickEntries.length" v-model="showUnprocessedOnly">{{ $t('showunprocessed') }}</b-switch>
|
||||
</b-field>
|
||||
<div v-for="(chunk, index) in chunkedQuickEntries" :key="index" class="tile is-ancestor">
|
||||
<div v-for="entry in chunk" :key="entry.id" class="tile is-parent" :class="{ 'is-4': quickEntries.length <= 3 }">
|
||||
@@ -71,7 +71,7 @@ export default {
|
||||
<div class="card-header-title">
|
||||
{{ parseAndFormatDateTime(entry.createdAt) }}
|
||||
</div>
|
||||
<b-tag v-if="entry.processDate === null" class="is-align-content-center" type="is-primary">unprocessed</b-tag>
|
||||
<b-tag v-if="entry.processDate === null" class="is-align-content-center" type="is-primary">{{ $t('unprocessed') }}</b-tag>
|
||||
</div>
|
||||
<div class="card-image">
|
||||
<!-- prettier-ignore -->
|
||||
@@ -87,22 +87,22 @@ export default {
|
||||
>
|
||||
<footer class="card-footer">
|
||||
<router-link v-if="entry.processDate === null && vehicles.length" :to="`/vehicles/${vehicles[0].id}/fillup`" class="card-footer-item"
|
||||
>Create Fillup</router-link
|
||||
>{{ $t('addfillup') }}</router-link
|
||||
>
|
||||
<router-link v-if="entry.processDate === null && vehicles.length" :to="`/vehicles/${vehicles[0].id}/expense`" class="card-footer-item"
|
||||
>Create Expense</router-link
|
||||
>{{ $t('addexpense') }}</router-link
|
||||
>
|
||||
|
||||
<a v-if="entry.processDate === null" class="card-footer-item" @click="markProcessed(entry)">Mark Processed</a>
|
||||
<p v-else class="card-footer-item">Processed on {{ parseAndFormatDateTime(entry.processDate) }}</p>
|
||||
<a class="card-footer-item" type="is-danger" @click="deleteQuickEntry(entry)"> Delete</a>
|
||||
<a v-if="entry.processDate === null" class="card-footer-item" @click="markProcessed(entry)">{{ $t('processed') }}</a>
|
||||
<p v-else class="card-footer-item">{{ $t('processedon') }} {{ parseAndFormatDateTime(entry.processDate) }}</p>
|
||||
<a class="card-footer-item" type="is-danger" @click="deleteQuickEntry(entry)"> {{ $t('delete') }}</a>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!quickEntries.length" class="box">
|
||||
<p>No Quick Entries right now.</p>
|
||||
<p>{{ $tc('quickentry',0) }}</p>
|
||||
</div>
|
||||
</Layout>
|
||||
</template>
|
||||
|
||||
@@ -106,7 +106,7 @@ export default {
|
||||
.dispatch(`utils/saveUserSettings`, { settings: this.settingsModel })
|
||||
.then((data) => {
|
||||
this.$buefy.toast.open({
|
||||
message: 'Settings saved successfully',
|
||||
message: this.$t('settingssaved'),
|
||||
type: 'is-success',
|
||||
duration: 3000,
|
||||
})
|
||||
@@ -132,18 +132,18 @@ export default {
|
||||
|
||||
<template>
|
||||
<Layout>
|
||||
<h1 class="title">Your Settings</h1>
|
||||
<h1 class="title">{{ $t('yoursettings') }}</h1>
|
||||
<div class="columns"
|
||||
><div class="column">
|
||||
<form class="box " @submit.prevent="saveSettings">
|
||||
<h1 class="subtitle">
|
||||
These will be used as default values whenever you create a new fillup or expense.
|
||||
</h1>
|
||||
<b-field label="Currency">
|
||||
<b-field :label="$t('currency')">
|
||||
<b-autocomplete
|
||||
v-model="settingsModel.currency"
|
||||
:custom-formatter="formatCurrency"
|
||||
placeholder="Currency"
|
||||
:placeholder="$t('currency')"
|
||||
:data="filteredCurrencyMasters"
|
||||
:keep-first="true"
|
||||
:open-on-focus="true"
|
||||
@@ -151,14 +151,14 @@ export default {
|
||||
@select="(option) => (selected = option)"
|
||||
></b-autocomplete>
|
||||
</b-field>
|
||||
<b-field label="Distance Unit">
|
||||
<b-field :label="$t('distanceunit')">
|
||||
<b-select v-model.number="settingsModel.distanceUnit" placeholder="Distance Unit" required expanded>
|
||||
<option v-for="(option, key) in distanceUnitMasters" :key="key" :value="key">
|
||||
{{ `${option.long} (${option.short})` }}
|
||||
</option>
|
||||
</b-select>
|
||||
</b-field>
|
||||
<b-field label="Date Format">
|
||||
<b-field :label="$t('dateformat')">
|
||||
<b-select v-model.number="settingsModel.dateFormat" placeholder="Date Format" required expanded>
|
||||
<option v-for="option in dateFormatMasters" :key="option" :value="option">
|
||||
{{ `${option}` }}
|
||||
@@ -167,25 +167,25 @@ export default {
|
||||
</b-field>
|
||||
<br />
|
||||
<b-field>
|
||||
<b-button tag="input" native-type="submit" :disabled="tryingToSave" type="is-primary" value="Save" expanded> </b-button>
|
||||
<b-button tag="input" native-type="submit" :disabled="tryingToSave" type="is-primary" :value="$t('save')" expanded> </b-button>
|
||||
</b-field>
|
||||
</form>
|
||||
</div>
|
||||
<div class="column">
|
||||
<form class="box" @submit.prevent="changePassword">
|
||||
<h1 class="subtitle">Change password</h1>
|
||||
<b-field label="Old Password">
|
||||
<h1 class="subtitle">{{ $t('changepassword') }}</h1>
|
||||
<b-field :label="$t('oldpassword')">
|
||||
<b-input v-model="changePassModel.old" required minlength="6" password-reveal type="password"></b-input>
|
||||
</b-field>
|
||||
<b-field label="New Password">
|
||||
<b-field :label="$t('newpassword')">
|
||||
<b-input v-model="changePassModel.new" required minlength="6" password-reveal type="password"></b-input>
|
||||
</b-field>
|
||||
<b-field label="Repeat New Password">
|
||||
<b-field :label="$t('repeatnewpassword')">
|
||||
<b-input v-model="changePassModel.renew" required minlength="6" password-reveal type="password"></b-input>
|
||||
</b-field>
|
||||
<p v-if="!passwordValid" class="help is-danger">Password values don't match</p>
|
||||
<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="Change Password" expanded> </b-button>
|
||||
<b-button tag="input" native-type="submit" :disabled="!passwordValid" type="is-primary" :value="$t('changepassword')" expanded> </b-button>
|
||||
</b-field>
|
||||
</form>
|
||||
</div>
|
||||
@@ -193,7 +193,7 @@ export default {
|
||||
<hr />
|
||||
<div class="columns">
|
||||
<div class="twelve">
|
||||
<h3 class="title">More Info</h3>
|
||||
<h3 class="title">{{ $t('moreinfo') }}</h3>
|
||||
<p style="font-style: italic;">
|
||||
This project is under active development which means I release new updates very frequently. I will eventually build the version
|
||||
management/update checking mechanism. Until then it is recommended that you use something like watchtower which will automatically update
|
||||
@@ -202,7 +202,7 @@ export default {
|
||||
<br />
|
||||
<table class="table is-hoverable">
|
||||
<tr>
|
||||
<td>Current Version</td>
|
||||
<td>{{ $t('currentversion') }}</td>
|
||||
<td>2022.07.06</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -210,7 +210,7 @@ export default {
|
||||
<td><a href="https://github.com/akhilrex/hammond" target="_blank">https://github.com/akhilrex/hammond</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Found a bug</td>
|
||||
<td>{{ $t('foundabug') }}</td>
|
||||
<td
|
||||
><a
|
||||
href="https://github.com/akhilrex/hammond/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc"
|
||||
@@ -221,7 +221,7 @@ export default {
|
||||
>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Feature Request</td>
|
||||
<td>{{ $t('featurerequest') }}</td>
|
||||
<td
|
||||
><a
|
||||
href="https://github.com/akhilrex/hammond/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc"
|
||||
@@ -232,8 +232,8 @@ export default {
|
||||
>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Support the developer</td>
|
||||
<td><a href="https://www.buymeacoffee.com/akhilrex" target="_blank" rel="noopener noreferrer">Buy him a beer!</a></td>
|
||||
<td>{{ $t('supportthedeveloper') }}</td>
|
||||
<td><a href="https://www.buymeacoffee.com/akhilrex" target="_blank" rel="noopener noreferrer">{{ $t('buyhimabeer') }}</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@@ -37,7 +37,7 @@ export default {
|
||||
.dispatch(`utils/saveSettings`, { settings: this.settingsModel })
|
||||
.then((data) => {
|
||||
this.$buefy.toast.open({
|
||||
message: 'Settings saved successfully',
|
||||
message: this.$t('settingssaved'),
|
||||
type: 'is-success',
|
||||
duration: 3000,
|
||||
})
|
||||
@@ -63,24 +63,24 @@ export default {
|
||||
<div class="">
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
<h1 class="title">Site Settings</h1>
|
||||
<h1 class="title">{{ $t('menu.sitesettings') }}</h1>
|
||||
<h1 class="subtitle">
|
||||
Update site level settings. These will be used as default values for new users.
|
||||
{{ $t('sitesettingdesc') }}
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<form class="" @submit.prevent="saveSettings">
|
||||
<b-field label="Currency">
|
||||
<b-select v-model="settingsModel.currency" placeholder="Currency" required expanded>
|
||||
<b-field :label="this.$t('currency')">
|
||||
<b-select v-model="settingsModel.currency" :placeholder="this.$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="Distance Unit">
|
||||
<b-select v-model.number="settingsModel.distanceUnit" placeholder="Distance Unit" required expanded>
|
||||
<b-field :label="this.$t('distanceunit')">
|
||||
<b-select v-model.number="settingsModel.distanceUnit" :placeholder="this.$t('distanceunit')" required expanded>
|
||||
<option v-for="(option, key) in distanceUnitMasters" :key="key" :value="key">
|
||||
{{ `${option.long} (${option.short})` }}
|
||||
</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="Save" expanded> </b-button>
|
||||
<b-button tag="input" native-type="submit" :disabled="tryingToSave" type="is-primary" :value="this.$t('save')" expanded> </b-button>
|
||||
</b-field>
|
||||
</form>
|
||||
</Layout>
|
||||
|
||||
@@ -55,18 +55,18 @@ export default {
|
||||
},
|
||||
changeDisabledStatus(userId,status){
|
||||
this.$buefy.dialog.confirm({
|
||||
title: status?'Disable User':"Enable User",
|
||||
message: 'Are you sure you want to do this?',
|
||||
cancelText: 'Cancel',
|
||||
confirmText: 'Go Ahead',
|
||||
title: status ? this.$t('disable') : this.$t('enable'),
|
||||
message: this.$t('areyousure'),
|
||||
cancelText: this.$t('cancel'),
|
||||
confirmText: this.$t('confirm'),
|
||||
onConfirm: () => {
|
||||
|
||||
var url = `/api/users/${userId}/${status?"disable":"enable"}`
|
||||
var url = `/api/users/${userId}/${status ? "disable" : "enable"}`
|
||||
axios
|
||||
.post(url, {})
|
||||
.then((data) => {
|
||||
this.$buefy.toast.open({
|
||||
message: status?"User disabled successfully":'User enabled successfully',
|
||||
message: status ? this.$t('userdisabledsuccessfully') : this.$t('userenabledsuccessfully'),
|
||||
type: 'is-success',
|
||||
duration: 3000,
|
||||
})
|
||||
@@ -103,7 +103,7 @@ export default {
|
||||
if (success) {
|
||||
this.$buefy.toast.open({
|
||||
duration: 10000,
|
||||
message: 'User Created Successfully',
|
||||
message: this.$t('usercreatedsuccessfully'),
|
||||
position: 'is-bottom',
|
||||
type: 'is-success',
|
||||
})
|
||||
@@ -129,22 +129,22 @@ export default {
|
||||
<Layout>
|
||||
<div class="box">
|
||||
<div class="columns">
|
||||
<div class="column is-three-quarters"> <h1 class="title is-4">Users</h1> </div>
|
||||
<div class="column is-three-quarters"> <h1 class="title is-4">{{ $t('menu.users') }}</h1> </div>
|
||||
<div class="column is-one-quarter">
|
||||
<b-button type="is-primary" @click="showUserForm = true">Add User</b-button>
|
||||
<b-button type="is-primary" @click="showUserForm = true">{{ $t('adduser') }}</b-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="showUserForm" class="box content">
|
||||
<h1 class="title">Create New User</h1>
|
||||
<h1 class="title">{{ $t('createnewuser') }}</h1>
|
||||
<form @submit.prevent="register">
|
||||
<b-field label="Name">
|
||||
<b-field :label="this.$t('name')">
|
||||
<b-input v-model="registerModel.name" required></b-input>
|
||||
</b-field>
|
||||
<b-field label="Email">
|
||||
<b-field :label="this.$t('email')">
|
||||
<b-input v-model="registerModel.email" type="email" required></b-input>
|
||||
</b-field>
|
||||
<b-field label="Password">
|
||||
<b-field :label="this.$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="Role">
|
||||
<b-select v-model.number="registerModel.role" placeholder="Role" required expanded>
|
||||
<b-field :label="this.$t('role')">
|
||||
<b-select v-model.number="registerModel.role" :placeholder="this.$t('placeholder')" required expanded>
|
||||
<option v-for="(option, key) in roleMasters" :key="key" :value="key">
|
||||
{{ `${option.long}` }}
|
||||
</option>
|
||||
</b-select>
|
||||
</b-field>
|
||||
<b-field label="Currency">
|
||||
<b-select v-model="registerModel.currency" placeholder="Currency" required expanded>
|
||||
<b-field :label="this.$t('currency')">
|
||||
<b-select v-model="registerModel.currency" :placeholder="this.$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="Distance Unit">
|
||||
<b-field :label="this.$t('distanceunit')">
|
||||
<b-select
|
||||
v-model.number="registerModel.distanceUnit"
|
||||
placeholder="Distance Unit"
|
||||
:placeholder="this.$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"></b-button>
|
||||
<b-button type="is-primary" native-type="submit" tag="input" :value="this.$t('save')"></b-button>
|
||||
|
||||
<b-button type="is-danger is-light" @click="resetUserForm">Cancel</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="Name">
|
||||
{{ `${props.row.name}` }} <template v-if="props.row.id === user.id">(You)</template>
|
||||
<b-table-column v-slot="props" field="name" :label="this.$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="Email">
|
||||
<b-table-column v-slot="props" field="email" :label="this.$t('email')">
|
||||
{{ `${props.row.email}` }}
|
||||
</b-table-column>
|
||||
<b-table-column v-slot="props" field="role" label="Role">
|
||||
<b-table-column v-slot="props" field="role" :label="this.$t('role')">
|
||||
{{ `${props.row.roleDetail.short}` }}
|
||||
</b-table-column>
|
||||
<b-table-column v-slot="props" field="createdAt" label="Created" sortable date>
|
||||
<b-table-column v-slot="props" field="createdAt" :label="this.$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.long === 'USER'" @click="changeDisabledStatus(props.row.id, false)">Enable</b-button>
|
||||
<b-button type="is-danger" v-if="!props.row.isDisabled && props.row.roleDetail.long === 'USER'" @click="changeDisabledStatus(props.row.id, true)">Disable</b-button>
|
||||
<b-button type="is-success" v-if="props.row.isDisabled && props.row.roleDetail.long === 'USER'" @click="changeDisabledStatus(props.row.id, false)">{{ $t('enable') }}</b-button>
|
||||
<b-button type="is-danger" v-if="!props.row.isDisabled && props.row.roleDetail.long === 'USER'" @click="changeDisabledStatus(props.row.id, true)">{{ $t('disable') }}</b-button>
|
||||
</b-table-column>
|
||||
</b-table>
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,7 @@ import { parseAndFormatDate } from '@utils/format-date'
|
||||
import { mapState } from 'vuex'
|
||||
import { addDays, addMonths } from 'date-fns'
|
||||
import axios from 'axios'
|
||||
import currencyFormtter from 'currency-formatter'
|
||||
import currencyFormatter from 'currency-formatter'
|
||||
import store from '@state/store'
|
||||
import ShareVehicle from '@components/shareVehicle.vue'
|
||||
import MileageChart from '@components/mileageChart.vue'
|
||||
@@ -40,12 +40,12 @@ export default {
|
||||
stats: null,
|
||||
users: [],
|
||||
dateRangeOptions: [
|
||||
{ label: 'This week', value: 'this_week' },
|
||||
{ label: 'This month', value: 'this_month' },
|
||||
{ label: 'Past 30 days', value: 'past_30_days' },
|
||||
{ label: 'Past 3 months', value: 'past_3_months' },
|
||||
{ label: 'This year', value: 'this_year' },
|
||||
{ label: 'All Time', value: 'all_time' },
|
||||
{ label: this.$t('thisweek'), value: 'this_week' },
|
||||
{ label: this.$t('thismonth'), value: 'this_month' },
|
||||
{ label: this.$tc('pastxdays', 30), value: 'past_30_days' },
|
||||
{ label: this.$tc('pastxmonths', 3), value: 'past_3_months' },
|
||||
{ label: this.$t('thisyear'), value: 'this_year' },
|
||||
{ label: this.$t('alltime'), value: 'all_time' },
|
||||
],
|
||||
dateRangeOption: 'past_30_days',
|
||||
}
|
||||
@@ -61,32 +61,32 @@ export default {
|
||||
return this.stats.map((x) => {
|
||||
return [
|
||||
{
|
||||
label: 'Currency',
|
||||
label: this.$t('currency'),
|
||||
value: x.currency,
|
||||
},
|
||||
{
|
||||
label: 'Total Expenditure',
|
||||
label: this.$t('totalexpenses'),
|
||||
value: this.formatCurrency(x.expenditureTotal, x.currency),
|
||||
},
|
||||
{
|
||||
label: 'Fillup Costs',
|
||||
label: this.$t('fillupcost'),
|
||||
value: `${this.formatCurrency(x.expenditureFillups, x.currency)} (${x.countFillups})`,
|
||||
},
|
||||
{
|
||||
label: 'Other Expenses',
|
||||
label: this.$t('otherexpenses'),
|
||||
value: `${this.formatCurrency(x.expenditureExpenses, x.currency)} (${x.countExpenses})`,
|
||||
},
|
||||
{
|
||||
label: 'Avg Fillup Expense',
|
||||
label: this.$t('avgfillupexpense'),
|
||||
value: `${this.formatCurrency(x.avgFillupCost, x.currency)}`,
|
||||
},
|
||||
{
|
||||
label: 'Avg Fillup Qty',
|
||||
label: this.$t('avgfillupqty'),
|
||||
value: `${x.avgFuelQty} ${this.vehicle.fuelUnitDetail.short}`,
|
||||
},
|
||||
{
|
||||
label: 'Avg Fuel Cost',
|
||||
value: `${this.formatCurrency(x.avgFuelPrice, x.currency)} per ${this.vehicle.fuelUnitDetail.short}`,
|
||||
label: this.$t('avgfuelcost'),
|
||||
value: this.$t('per', {'0': this.formatCurrency(x.avgFuelPrice, x.currency), '1': this.vehicle.fuelUnitDetail.short}),
|
||||
},
|
||||
]
|
||||
})
|
||||
@@ -240,7 +240,7 @@ export default {
|
||||
if (!currencyCode) {
|
||||
currencyCode = this.me.currency
|
||||
}
|
||||
return currencyFormtter.format(number, { code: currencyCode })
|
||||
return currencyFormatter.format(number, { code: currencyCode })
|
||||
},
|
||||
columnTdAttrs(row, column) {
|
||||
return null
|
||||
@@ -300,18 +300,18 @@ export default {
|
||||
<template>
|
||||
<Layout>
|
||||
<div class="columns box">
|
||||
<div class="column is-two-thirds" :class="isMobile ? 'has-text-centered' : ''">
|
||||
<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, vehicle.fuelTypeDetail.long].join(' | ') }}
|
||||
{{ [vehicle.make, vehicle.model, this.$t('fuel.' + vehicle.fuelTypeDetail.short)].join(' | ') }}
|
||||
|
||||
<template v-if="users.length > 1">
|
||||
| Shared with :
|
||||
| {{ $t("sharedwith") }} :
|
||||
{{
|
||||
users
|
||||
.map((x) => {
|
||||
if (x.userId === me.id) {
|
||||
return 'You'
|
||||
return this.$t('you')
|
||||
} else {
|
||||
return x.name
|
||||
}
|
||||
@@ -321,13 +321,13 @@ export default {
|
||||
</template>
|
||||
</p>
|
||||
</div>
|
||||
<div class="column is-one-third buttons has-text-centered">
|
||||
<b-button type="is-primary" tag="router-link" :to="`/vehicles/${vehicle.id}/fillup`">Add Fillup</b-button>
|
||||
<b-button type="is-primary" tag="router-link" :to="`/vehicles/${vehicle.id}/expense`">Add Expense</b-button>
|
||||
<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
|
||||
v-if="vehicle.isOwner"
|
||||
tag="router-link"
|
||||
title="Edit Vehicle"
|
||||
:title="$t('editvehicle')"
|
||||
:to="{
|
||||
name: 'vehicle-edit',
|
||||
props: { vehicle: vehicle },
|
||||
@@ -336,10 +336,10 @@ export default {
|
||||
>
|
||||
<b-icon pack="fas" icon="edit" type="is-info"> </b-icon
|
||||
></b-button>
|
||||
<b-button v-if="vehicle.isOwner" title="Share vehicle" @click="showShareVehicleModal">
|
||||
<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>
|
||||
<b-button v-if="vehicle.isOwner" title="Delete Vehicle" @click="deleteVehicle">
|
||||
<b-button v-if="vehicle.isOwner" :title="$t('deletevehicle')" @click="deleteVehicle">
|
||||
<b-icon pack="fas" icon="trash" type="is-danger"> </b-icon
|
||||
></b-button>
|
||||
</div>
|
||||
@@ -353,45 +353,45 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<h1 class="title is-4">Past Fillups</h1>
|
||||
<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="Date" :td-attrs="columnTdAttrs" sortable date>
|
||||
<b-table-column v-slot="props" field="date" :label="this.$t('date')" :td-attrs="columnTdAttrs" sortable date>
|
||||
{{ formatDate(props.row.date) }}
|
||||
</b-table-column>
|
||||
<b-table-column v-slot="props" field="fuelSubType" label="Fuel Sub Type" :td-attrs="columnTdAttrs">
|
||||
<b-table-column v-slot="props" field="fuelSubType" :label="this.$t('fuelsubtype')" :td-attrs="columnTdAttrs">
|
||||
{{ props.row.fuelSubType }}
|
||||
</b-table-column>
|
||||
<b-table-column v-slot="props" field="fuelQuantity" label="Qty." :td-attrs="hiddenMobile" numeric>
|
||||
<b-table-column v-slot="props" field="fuelQuantity" :label="this.$t('quantity')" :td-attrs="hiddenMobile" numeric>
|
||||
{{ `${props.row.fuelQuantity} ${props.row.fuelUnitDetail.short}` }}
|
||||
</b-table-column>
|
||||
<b-table-column
|
||||
v-slot="props"
|
||||
field="perUnitPrice"
|
||||
:label="'Price per ' + vehicle.fuelUnitDetail.short"
|
||||
:label="this.$t('per', { '0': this.$t('price'), '1': vehicle.fuelUnitDetail.short })"
|
||||
: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="Total" :td-attrs="hiddenDesktop" sortable numeric>
|
||||
<b-table-column v-if="isMobile" v-slot="props" field="totalAmount" :label="this.$t('total')" :td-attrs="hiddenDesktop" sortable numeric>
|
||||
{{ `${me.currency} ${props.row.totalAmount}` }} ({{ `${props.row.fuelQuantity} ${props.row.fuelUnitDetail.short}` }} @
|
||||
{{ `${me.currency} ${props.row.perUnitPrice}` }})
|
||||
</b-table-column>
|
||||
<b-table-column v-if="!isMobile" v-slot="props" field="totalAmount" label="Total" :td-attrs="hiddenMobile" sortable numeric>
|
||||
<b-table-column v-if="!isMobile" v-slot="props" field="totalAmount" :label="this.$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="Tank Full" :td-attrs="hiddenMobile">
|
||||
<b-table-column v-slot="props" width="20" field="isTankFull" :label="this.$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="Odometer Reading" :td-attrs="hiddenMobile" numeric>
|
||||
<b-table-column v-slot="props" field="odoReading" :label="this.$t('odometer')" :td-attrs="hiddenMobile" numeric>
|
||||
{{ `${props.row.odoReading} ${me.distanceUnitDetail.short}` }}
|
||||
</b-table-column>
|
||||
<b-table-column v-slot="props" field="fillingStation" label="Fillup Station" :td-attrs="hiddenMobile">
|
||||
<b-table-column v-slot="props" field="fillingStation" :label="this.$t('gasstation')" :td-attrs="hiddenMobile">
|
||||
{{ `${props.row.fillingStation}` }}
|
||||
</b-table-column>
|
||||
<b-table-column v-slot="props" field="userId" label="By" :td-attrs="hiddenMobile">
|
||||
<b-table-column v-slot="props" field="userId" :label="this.$t('by')" :td-attrs="hiddenMobile">
|
||||
{{ `${props.row.user.name}` }}
|
||||
</b-table-column>
|
||||
<b-table-column v-slot="props">
|
||||
@@ -406,11 +406,11 @@ export default {
|
||||
>
|
||||
<b-icon pack="fas" icon="edit" type="is-info"> </b-icon
|
||||
></b-button>
|
||||
<b-button type="is-ghost" title="Delete this fillup" @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>
|
||||
<template v-slot:empty> No Fillups so far</template>
|
||||
<template v-slot:empty> {{ $t('nofillups') }}</template>
|
||||
<template v-slot:detail="props">
|
||||
<p>{{ props.row.id }}</p>
|
||||
</template>
|
||||
@@ -418,25 +418,25 @@ export default {
|
||||
</div>
|
||||
<br />
|
||||
<div class="box">
|
||||
<h1 class="title is-4">Past Expenses</h1>
|
||||
<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="Date" :td-attrs="columnTdAttrs" date>
|
||||
<b-table-column v-slot="props" field="date" :label="this.$t('date')" :td-attrs="columnTdAttrs" date>
|
||||
{{ formatDate(props.row.date) }}
|
||||
</b-table-column>
|
||||
<b-table-column v-slot="props" field="expenseType" label="Expense Type">
|
||||
<b-table-column v-slot="props" field="expenseType" :label="this.$t('expensetype')">
|
||||
{{ `${props.row.expenseType}` }}
|
||||
</b-table-column>
|
||||
|
||||
<b-table-column v-slot="props" field="amount" label="Total" :td-attrs="hiddenMobile" sortable numeric>
|
||||
<b-table-column v-slot="props" field="amount" :label="this.$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="Odometer Reading" :td-attrs="columnTdAttrs" numeric>
|
||||
<b-table-column v-slot="props" field="odoReading" :label="this.$t('odometer')" :td-attrs="columnTdAttrs" numeric>
|
||||
{{ `${props.row.odoReading} ${me.distanceUnitDetail.short}` }}
|
||||
</b-table-column>
|
||||
|
||||
<b-table-column v-slot="props" field="userId" label="By" :td-attrs="columnTdAttrs">
|
||||
<b-table-column v-slot="props" field="userId" :label="this.$t('by')" :td-attrs="columnTdAttrs">
|
||||
{{ `${props.row.user.name}` }}
|
||||
</b-table-column>
|
||||
<b-table-column v-slot="props">
|
||||
@@ -451,20 +451,20 @@ export default {
|
||||
>
|
||||
<b-icon pack="fas" icon="edit" type="is-info"> </b-icon
|
||||
></b-button>
|
||||
<b-button type="is-ghost" title="Delete this expense" @click="deleteExpense(props.row.id)">
|
||||
<b-button type="is-ghost" :title="$t('deleteexpense')" @click="deleteExpense(props.row.id)">
|
||||
<b-icon pack="fas" icon="trash" type="is-danger"> </b-icon
|
||||
></b-button>
|
||||
</b-table-column>
|
||||
<template v-slot:empty> No Expenses so far</template>
|
||||
<template v-slot:empty> {{ $t('noexpenses') }}</template>
|
||||
</b-table>
|
||||
</div>
|
||||
<br />
|
||||
<div class="box">
|
||||
<div class="columns">
|
||||
<div class="column is-three-quarters"> <h1 class="title is-4">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">
|
||||
Add Attachment
|
||||
{{ $t('addattachment') }}
|
||||
</b-button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -478,7 +478,7 @@ export default {
|
||||
<b-upload v-model="file" class="file-label" required>
|
||||
<span class="file-cta">
|
||||
<b-icon class="file-icon" icon="upload"></b-icon>
|
||||
<span class="file-label">Choose File</span>
|
||||
<span class="file-label">{{ $t('choosefile') }}</span>
|
||||
</span>
|
||||
<span v-if="file" class="file-name" :class="isMobile ? 'file-name-mobile' : 'file-name-desktop'">
|
||||
{{ file.name }}
|
||||
@@ -486,7 +486,7 @@ export default {
|
||||
</b-upload>
|
||||
</b-field>
|
||||
<b-field>
|
||||
<b-input v-model="title" required placeholder="Label for this file"></b-input>
|
||||
<b-input v-model="title" required :placeholder="this.$t('labelforfile')"></b-input>
|
||||
</b-field>
|
||||
|
||||
<b-field class="buttons">
|
||||
@@ -510,24 +510,24 @@ export default {
|
||||
</div>
|
||||
|
||||
<b-table :data="attachments" hoverable mobile-cards>
|
||||
<b-table-column v-slot="props" field="title" label="Title" :td-attrs="columnTdAttrs">
|
||||
<b-table-column v-slot="props" field="title" :label="this.$t('title')" :td-attrs="columnTdAttrs">
|
||||
{{ `${props.row.title}` }}
|
||||
</b-table-column>
|
||||
|
||||
<b-table-column v-slot="props" field="originalName" label="Name" :td-attrs="columnTdAttrs">
|
||||
<b-table-column v-slot="props" field="originalName" :label="this.$t('name')" :td-attrs="columnTdAttrs">
|
||||
{{ `${props.row.originalName}` }}
|
||||
</b-table-column>
|
||||
<b-table-column v-slot="props" field="id" label="Download" :td-attrs="columnTdAttrs">
|
||||
<b-table-column v-slot="props" field="id" :label="this.$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>
|
||||
</b-table-column>
|
||||
<template v-slot:empty> No Attachments so far</template>
|
||||
<template v-slot:empty> {{ $t('noattachments') }}</template>
|
||||
</b-table>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div class="columns">
|
||||
<div class="column" :class="isMobile ? 'has-text-centered' : ''"> <h1 class="title">Stats</h1></div>
|
||||
<div class="column" :class="isMobile ? 'has-text-centered' : ''"> <h1 class="title">{{ $t('statistics') }}</h1></div>
|
||||
<div class="column">
|
||||
<b-select v-model="dateRangeOption" class="is-pulled-right is-medium">
|
||||
<option v-for="option in dateRangeOptions" :key="option.value" :value="option.value">
|
||||
|
||||
Reference in New Issue
Block a user