user settings supports language and date&time format

This commit is contained in:
MaysWind
2023-06-04 21:08:48 +08:00
parent 999ca6274c
commit 0a106026dd
33 changed files with 1082 additions and 285 deletions
+8 -3
View File
@@ -398,10 +398,15 @@ func printUserInfo(user *models.User) {
fmt.Printf("[Nickname] %s\n", user.Nickname) fmt.Printf("[Nickname] %s\n", user.Nickname)
fmt.Printf("[Password] %s\n", user.Password) fmt.Printf("[Password] %s\n", user.Password)
fmt.Printf("[Salt] %s\n", user.Salt) fmt.Printf("[Salt] %s\n", user.Salt)
fmt.Printf("[DefaultCurrency] %s\n", user.DefaultCurrency)
fmt.Printf("[DefaultAccountId] %d\n", user.DefaultAccountId) fmt.Printf("[DefaultAccountId] %d\n", user.DefaultAccountId)
fmt.Printf("[FirstDayOfWeek] %s\n", user.FirstDayOfWeek) fmt.Printf("[TransactionEditScope] %s (%d)\n", user.TransactionEditScope, user.TransactionEditScope)
fmt.Printf("[TransactionEditScope] %s\n", user.TransactionEditScope) fmt.Printf("[Language] %s\n", user.Language)
fmt.Printf("[DefaultCurrency] %s\n", user.DefaultCurrency)
fmt.Printf("[FirstDayOfWeek] %s (%d)\n", user.FirstDayOfWeek, user.FirstDayOfWeek)
fmt.Printf("[LongDateFormat] %s (%d)\n", user.LongDateFormat, user.LongDateFormat)
fmt.Printf("[ShortDateFormat] %s (%d)\n", user.ShortDateFormat, user.ShortDateFormat)
fmt.Printf("[LongTimeFormat] %s (%d)\n", user.LongTimeFormat, user.LongTimeFormat)
fmt.Printf("[ShortTimeFormat] %s (%d)\n", user.ShortTimeFormat, user.ShortTimeFormat)
fmt.Printf("[Deleted] %t\n", user.Deleted) fmt.Printf("[Deleted] %t\n", user.Deleted)
fmt.Printf("[EmailVerified] %t\n", user.EmailVerified) fmt.Printf("[EmailVerified] %t\n", user.EmailVerified)
fmt.Printf("[CreatedAt] %s (%d)\n", utils.FormatUnixTimeToLongDateTimeInServerTimezone(user.CreatedUnixTime), user.CreatedUnixTime) fmt.Printf("[CreatedAt] %s (%d)\n", utils.FormatUnixTimeToLongDateTimeInServerTimezone(user.CreatedUnixTime), user.CreatedUnixTime)
+57 -15
View File
@@ -57,6 +57,7 @@ func (a *UsersApi) UserRegisterHandler(c *core.Context) (interface{}, *errs.Erro
Email: userRegisterReq.Email, Email: userRegisterReq.Email,
Nickname: userRegisterReq.Nickname, Nickname: userRegisterReq.Nickname,
Password: userRegisterReq.Password, Password: userRegisterReq.Password,
Language: userRegisterReq.Language,
DefaultCurrency: userRegisterReq.DefaultCurrency, DefaultCurrency: userRegisterReq.DefaultCurrency,
FirstDayOfWeek: userRegisterReq.FirstDayOfWeek, FirstDayOfWeek: userRegisterReq.FirstDayOfWeek,
TransactionEditScope: models.TRANSACTION_EDIT_SCOPE_ALL, TransactionEditScope: models.TRANSACTION_EDIT_SCOPE_ALL,
@@ -161,12 +162,6 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.Context) (interface{}, *errs
anythingUpdate = true anythingUpdate = true
} }
if userUpdateReq.DefaultCurrency != "" && userUpdateReq.DefaultCurrency != user.DefaultCurrency {
user.DefaultCurrency = userUpdateReq.DefaultCurrency
userNew.DefaultCurrency = userUpdateReq.DefaultCurrency
anythingUpdate = true
}
if userUpdateReq.DefaultAccountId > 0 && userUpdateReq.DefaultAccountId != user.DefaultAccountId { if userUpdateReq.DefaultAccountId > 0 && userUpdateReq.DefaultAccountId != user.DefaultAccountId {
accounts, err := a.accounts.GetAccountsByAccountIds(uid, []int64{userUpdateReq.DefaultAccountId}) accounts, err := a.accounts.GetAccountsByAccountIds(uid, []int64{userUpdateReq.DefaultAccountId})
@@ -179,14 +174,6 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.Context) (interface{}, *errs
anythingUpdate = true anythingUpdate = true
} }
if userUpdateReq.FirstDayOfWeek != nil && *userUpdateReq.FirstDayOfWeek != user.FirstDayOfWeek {
user.FirstDayOfWeek = *userUpdateReq.FirstDayOfWeek
userNew.FirstDayOfWeek = *userUpdateReq.FirstDayOfWeek
anythingUpdate = true
} else {
userNew.FirstDayOfWeek = models.WEEKDAY_INVALID
}
if userUpdateReq.TransactionEditScope != nil && *userUpdateReq.TransactionEditScope != user.TransactionEditScope { if userUpdateReq.TransactionEditScope != nil && *userUpdateReq.TransactionEditScope != user.TransactionEditScope {
user.TransactionEditScope = *userUpdateReq.TransactionEditScope user.TransactionEditScope = *userUpdateReq.TransactionEditScope
userNew.TransactionEditScope = *userUpdateReq.TransactionEditScope userNew.TransactionEditScope = *userUpdateReq.TransactionEditScope
@@ -195,11 +182,66 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.Context) (interface{}, *errs
userNew.TransactionEditScope = models.TRANSACTION_EDIT_SCOPE_INVALID userNew.TransactionEditScope = models.TRANSACTION_EDIT_SCOPE_INVALID
} }
modifyUserLanguage := false
if userUpdateReq.Language != user.Language {
user.Language = userUpdateReq.Language
userNew.Language = userUpdateReq.Language
modifyUserLanguage = true
anythingUpdate = true
}
if userUpdateReq.DefaultCurrency != "" && userUpdateReq.DefaultCurrency != user.DefaultCurrency {
user.DefaultCurrency = userUpdateReq.DefaultCurrency
userNew.DefaultCurrency = userUpdateReq.DefaultCurrency
anythingUpdate = true
}
if userUpdateReq.FirstDayOfWeek != nil && *userUpdateReq.FirstDayOfWeek != user.FirstDayOfWeek {
user.FirstDayOfWeek = *userUpdateReq.FirstDayOfWeek
userNew.FirstDayOfWeek = *userUpdateReq.FirstDayOfWeek
anythingUpdate = true
} else {
userNew.FirstDayOfWeek = models.WEEKDAY_INVALID
}
if userUpdateReq.LongDateFormat != nil && *userUpdateReq.LongDateFormat != user.LongDateFormat {
user.LongDateFormat = *userUpdateReq.LongDateFormat
userNew.LongDateFormat = *userUpdateReq.LongDateFormat
anythingUpdate = true
} else {
userNew.LongDateFormat = models.LONG_DATE_FORMAT_INVALID
}
if userUpdateReq.ShortDateFormat != nil && *userUpdateReq.ShortDateFormat != user.ShortDateFormat {
user.ShortDateFormat = *userUpdateReq.ShortDateFormat
userNew.ShortDateFormat = *userUpdateReq.ShortDateFormat
anythingUpdate = true
} else {
userNew.ShortDateFormat = models.SHORT_DATE_FORMAT_INVALID
}
if userUpdateReq.LongTimeFormat != nil && *userUpdateReq.LongTimeFormat != user.LongTimeFormat {
user.LongTimeFormat = *userUpdateReq.LongTimeFormat
userNew.LongTimeFormat = *userUpdateReq.LongTimeFormat
anythingUpdate = true
} else {
userNew.LongTimeFormat = models.LONG_TIME_FORMAT_INVALID
}
if userUpdateReq.ShortTimeFormat != nil && *userUpdateReq.ShortTimeFormat != user.ShortTimeFormat {
user.ShortTimeFormat = *userUpdateReq.ShortTimeFormat
userNew.ShortTimeFormat = *userUpdateReq.ShortTimeFormat
anythingUpdate = true
} else {
userNew.ShortTimeFormat = models.SHORT_TIME_FORMAT_INVALID
}
if !anythingUpdate { if !anythingUpdate {
return nil, errs.ErrNothingWillBeUpdated return nil, errs.ErrNothingWillBeUpdated
} }
keyProfileUpdated, err := a.users.UpdateUser(userNew) keyProfileUpdated, err := a.users.UpdateUser(userNew, modifyUserLanguage)
if err != nil { if err != nil {
log.ErrorfWithRequestId(c, "[users.UserUpdateProfileHandler] failed to update user \"uid:%d\", because %s", user.Uid, err.Error()) log.ErrorfWithRequestId(c, "[users.UserUpdateProfileHandler] failed to update user \"uid:%d\", because %s", user.Uid, err.Error())
+1 -1
View File
@@ -142,7 +142,7 @@ func (l *UserDataCli) ModifyUserPassword(c *cli.Context, username string, passwo
Password: password, Password: password,
} }
_, err = l.users.UpdateUser(userNew) _, err = l.users.UpdateUser(userNew, false)
if err != nil { if err != nil {
log.BootErrorf("[user_data.ModifyUserPassword] failed to update user \"%s\" password, because %s", user.Username, err.Error()) log.BootErrorf("[user_data.ModifyUserPassword] failed to update user \"%s\" password, because %s", user.Username, err.Error())
+162
View File
@@ -0,0 +1,162 @@
package models
import "fmt"
// WeekDay represents week day
type WeekDay byte
// Week days
const (
WEEKDAY_SUNDAY WeekDay = 0
WEEKDAY_MONDAY WeekDay = 1
WEEKDAY_TUESDAY WeekDay = 2
WEEKDAY_WEDNESDAY WeekDay = 3
WEEKDAY_THURSDAY WeekDay = 4
WEEKDAY_FRIDAY WeekDay = 5
WEEKDAY_SATURDAY WeekDay = 6
WEEKDAY_INVALID WeekDay = 255
)
// String returns a textual representation of the week day enum
func (d WeekDay) String() string {
switch d {
case WEEKDAY_SUNDAY:
return "Sunday"
case WEEKDAY_MONDAY:
return "Monday"
case WEEKDAY_TUESDAY:
return "Tuesday"
case WEEKDAY_WEDNESDAY:
return "Wednesday"
case WEEKDAY_THURSDAY:
return "Thursday"
case WEEKDAY_FRIDAY:
return "Friday"
case WEEKDAY_SATURDAY:
return "Saturday"
case WEEKDAY_INVALID:
return "Invalid"
default:
return fmt.Sprintf("Invalid(%d)", int(d))
}
}
// LongDateFormat represents long date format
type LongDateFormat byte
// Long Date Format
const (
LONG_DATE_FORMAT_DEFAULT LongDateFormat = 0
LONG_DATE_FORMAT_YYYY_M_D LongDateFormat = 1
LONG_DATE_FORMAT_M_D_YYYY LongDateFormat = 2
LONG_DATE_FORMAT_D_M_YYYY LongDateFormat = 3
LONG_DATE_FORMAT_INVALID LongDateFormat = 255
)
// String returns a textual representation of the long date format enum
func (f LongDateFormat) String() string {
switch f {
case LONG_DATE_FORMAT_DEFAULT:
return "Default"
case LONG_DATE_FORMAT_YYYY_M_D:
return "YYYY_MM_D"
case LONG_DATE_FORMAT_M_D_YYYY:
return "M_D_YYYY"
case LONG_DATE_FORMAT_D_M_YYYY:
return "D_M_YYYY"
case LONG_DATE_FORMAT_INVALID:
return "Invalid"
default:
return fmt.Sprintf("Invalid(%d)", int(f))
}
}
// ShortDateFormat represents short date format
type ShortDateFormat byte
// Short Date Format
const (
SHORT_DATE_FORMAT_DEFAULT ShortDateFormat = 0
SHORT_DATE_FORMAT_YYYY_M_D ShortDateFormat = 1
SHORT_DATE_FORMAT_M_D_YYYY ShortDateFormat = 2
SHORT_DATE_FORMAT_D_M_YYYY ShortDateFormat = 3
SHORT_DATE_FORMAT_INVALID ShortDateFormat = 255
)
// String returns a textual representation of the short date format enum
func (f ShortDateFormat) String() string {
switch f {
case SHORT_DATE_FORMAT_DEFAULT:
return "Default"
case SHORT_DATE_FORMAT_YYYY_M_D:
return "YYYY_MM_D"
case SHORT_DATE_FORMAT_M_D_YYYY:
return "M_D_YYYY"
case SHORT_DATE_FORMAT_D_M_YYYY:
return "D_M_YYYY"
case SHORT_DATE_FORMAT_INVALID:
return "Invalid"
default:
return fmt.Sprintf("Invalid(%d)", int(f))
}
}
// LongTimeFormat represents long time format
type LongTimeFormat byte
// Long Time Format
const (
LONG_TIME_FORMAT_DEFAULT LongTimeFormat = 0
LONG_TIME_FORMAT_HH_MM_SS LongTimeFormat = 1
LONG_TIME_FORMAT_A_HH_MM_SS LongTimeFormat = 2
LONG_TIME_FORMAT_HH_MM_SS_A LongTimeFormat = 3
LONG_TIME_FORMAT_INVALID LongTimeFormat = 255
)
// String returns a textual representation of the long time format enum
func (f LongTimeFormat) String() string {
switch f {
case LONG_TIME_FORMAT_DEFAULT:
return "Default"
case LONG_TIME_FORMAT_HH_MM_SS:
return "HH_MM_SS"
case LONG_TIME_FORMAT_A_HH_MM_SS:
return "A_HH_MM_SS"
case LONG_TIME_FORMAT_HH_MM_SS_A:
return "HH_MM_SS_A"
case LONG_TIME_FORMAT_INVALID:
return "Invalid"
default:
return fmt.Sprintf("Invalid(%d)", int(f))
}
}
// ShortTimeFormat represents short time format
type ShortTimeFormat byte
// Short Time Format
const (
SHORT_TIME_FORMAT_DEFAULT ShortTimeFormat = 0
SHORT_TIME_FORMAT_HH_MM ShortTimeFormat = 1
SHORT_TIME_FORMAT_A_HH_MM ShortTimeFormat = 2
SHORT_TIME_FORMAT_HH_MM_A ShortTimeFormat = 3
SHORT_TIME_FORMAT_INVALID ShortTimeFormat = 255
)
// String returns a textual representation of the short time format enum
func (f ShortTimeFormat) String() string {
switch f {
case SHORT_TIME_FORMAT_DEFAULT:
return "Default"
case SHORT_TIME_FORMAT_HH_MM:
return "HH_MM"
case SHORT_TIME_FORMAT_A_HH_MM:
return "A_HH_MM"
case SHORT_TIME_FORMAT_HH_MM_A:
return "HH_MM_A"
case SHORT_TIME_FORMAT_INVALID:
return "Invalid"
default:
return fmt.Sprintf("Invalid(%d)", int(f))
}
}
+43 -51
View File
@@ -7,45 +7,6 @@ import (
"github.com/mayswind/ezbookkeeping/pkg/utils" "github.com/mayswind/ezbookkeeping/pkg/utils"
) )
// WeekDay represents week day
type WeekDay byte
// Week days
const (
WEEKDAY_SUNDAY WeekDay = 0
WEEKDAY_MONDAY WeekDay = 1
WEEKDAY_TUESDAY WeekDay = 2
WEEKDAY_WEDNESDAY WeekDay = 3
WEEKDAY_THURSDAY WeekDay = 4
WEEKDAY_FRIDAY WeekDay = 5
WEEKDAY_SATURDAY WeekDay = 6
WEEKDAY_INVALID WeekDay = 255
)
// String returns a textual representation of the week day enum
func (d WeekDay) String() string {
switch d {
case WEEKDAY_SUNDAY:
return "Sunday"
case WEEKDAY_MONDAY:
return "Monday"
case WEEKDAY_TUESDAY:
return "Tuesday"
case WEEKDAY_WEDNESDAY:
return "Wednesday"
case WEEKDAY_THURSDAY:
return "Thursday"
case WEEKDAY_FRIDAY:
return "Friday"
case WEEKDAY_SATURDAY:
return "Saturday"
case WEEKDAY_INVALID:
return "Invalid"
default:
return fmt.Sprintf("Invalid(%d)", int(d))
}
}
// TransactionEditScope represents the scope which transaction can be edited // TransactionEditScope represents the scope which transaction can be edited
type TransactionEditScope byte type TransactionEditScope byte
@@ -93,10 +54,15 @@ type User struct {
Nickname string `xorm:"VARCHAR(64) NOT NULL"` Nickname string `xorm:"VARCHAR(64) NOT NULL"`
Password string `xorm:"VARCHAR(64) NOT NULL"` Password string `xorm:"VARCHAR(64) NOT NULL"`
Salt string `xorm:"VARCHAR(10) NOT NULL"` Salt string `xorm:"VARCHAR(10) NOT NULL"`
DefaultCurrency string `xorm:"VARCHAR(3) NOT NULL"`
DefaultAccountId int64 DefaultAccountId int64
FirstDayOfWeek WeekDay `xorm:"TINYINT NOT NULL"`
TransactionEditScope TransactionEditScope `xorm:"TINYINT NOT NULL"` TransactionEditScope TransactionEditScope `xorm:"TINYINT NOT NULL"`
Language string `xorm:"VARCHAR(10)"`
DefaultCurrency string `xorm:"VARCHAR(3) NOT NULL"`
FirstDayOfWeek WeekDay `xorm:"TINYINT NOT NULL"`
LongDateFormat LongDateFormat `xorm:"TINYINT"`
ShortDateFormat ShortDateFormat `xorm:"TINYINT"`
LongTimeFormat LongTimeFormat `xorm:"TINYINT"`
ShortTimeFormat ShortTimeFormat `xorm:"TINYINT"`
Deleted bool `xorm:"NOT NULL"` Deleted bool `xorm:"NOT NULL"`
EmailVerified bool `xorm:"NOT NULL"` EmailVerified bool `xorm:"NOT NULL"`
CreatedUnixTime int64 CreatedUnixTime int64
@@ -110,10 +76,15 @@ type UserBasicInfo struct {
Username string `json:"username"` Username string `json:"username"`
Email string `json:"email"` Email string `json:"email"`
Nickname string `json:"nickname"` Nickname string `json:"nickname"`
DefaultCurrency string `json:"defaultCurrency"`
DefaultAccountId int64 `json:"defaultAccountId,string"` DefaultAccountId int64 `json:"defaultAccountId,string"`
FirstDayOfWeek WeekDay `json:"firstDayOfWeek"`
TransactionEditScope TransactionEditScope `json:"transactionEditScope"` TransactionEditScope TransactionEditScope `json:"transactionEditScope"`
Language string `json:"language"`
DefaultCurrency string `json:"defaultCurrency"`
FirstDayOfWeek WeekDay `json:"firstDayOfWeek"`
LongDateFormat LongDateFormat `json:"longDateFormat"`
ShortDateFormat ShortDateFormat `json:"shortDateFormat"`
LongTimeFormat LongTimeFormat `json:"longTimeFormat"`
ShortTimeFormat ShortTimeFormat `json:"shortTimeFormat"`
} }
// UserLoginRequest represents all parameters of user login request // UserLoginRequest represents all parameters of user login request
@@ -128,6 +99,7 @@ type UserRegisterRequest struct {
Email string `json:"email" binding:"required,notBlank,max=100,validEmail"` Email string `json:"email" binding:"required,notBlank,max=100,validEmail"`
Nickname string `json:"nickname" binding:"required,notBlank,max=64"` Nickname string `json:"nickname" binding:"required,notBlank,max=64"`
Password string `json:"password" binding:"required,min=6,max=128"` Password string `json:"password" binding:"required,min=6,max=128"`
Language string `json:"language" binding:"required,min=2,max=16"`
DefaultCurrency string `json:"defaultCurrency" binding:"required,len=3,validCurrency"` DefaultCurrency string `json:"defaultCurrency" binding:"required,len=3,validCurrency"`
FirstDayOfWeek WeekDay `json:"firstDayOfWeek" binding:"min=0,max=6"` FirstDayOfWeek WeekDay `json:"firstDayOfWeek" binding:"min=0,max=6"`
} }
@@ -138,10 +110,15 @@ type UserProfileUpdateRequest struct {
Nickname string `json:"nickname" binding:"omitempty,notBlank,max=64"` Nickname string `json:"nickname" binding:"omitempty,notBlank,max=64"`
Password string `json:"password" binding:"omitempty,min=6,max=128"` Password string `json:"password" binding:"omitempty,min=6,max=128"`
OldPassword string `json:"oldPassword" binding:"omitempty,min=6,max=128"` OldPassword string `json:"oldPassword" binding:"omitempty,min=6,max=128"`
DefaultCurrency string `json:"defaultCurrency" binding:"omitempty,len=3,validCurrency"`
DefaultAccountId int64 `json:"defaultAccountId,string" binding:"omitempty,min=1"` DefaultAccountId int64 `json:"defaultAccountId,string" binding:"omitempty,min=1"`
FirstDayOfWeek *WeekDay `json:"firstDayOfWeek" binding:"omitempty,min=0,max=6"`
TransactionEditScope *TransactionEditScope `json:"transactionEditScope" binding:"omitempty,min=0,max=7"` TransactionEditScope *TransactionEditScope `json:"transactionEditScope" binding:"omitempty,min=0,max=7"`
Language string `json:"language" binding:"omitempty,min=2,max=16"`
DefaultCurrency string `json:"defaultCurrency" binding:"omitempty,len=3,validCurrency"`
FirstDayOfWeek *WeekDay `json:"firstDayOfWeek" binding:"omitempty,min=0,max=6"`
LongDateFormat *LongDateFormat `json:"longDateFormat" binding:"omitempty,min=0,max=3"`
ShortDateFormat *ShortDateFormat `json:"shortDateFormat" binding:"omitempty,min=0,max=3"`
LongTimeFormat *LongTimeFormat `json:"longTimeFormat" binding:"omitempty,min=0,max=3"`
ShortTimeFormat *ShortTimeFormat `json:"shortTimeFormat" binding:"omitempty,min=0,max=3"`
} }
// UserProfileUpdateResponse represents the data returns to frontend after updating profile // UserProfileUpdateResponse represents the data returns to frontend after updating profile
@@ -155,10 +132,15 @@ type UserProfileResponse struct {
Username string `json:"username"` Username string `json:"username"`
Email string `json:"email"` Email string `json:"email"`
Nickname string `json:"nickname"` Nickname string `json:"nickname"`
DefaultCurrency string `json:"defaultCurrency"`
DefaultAccountId int64 `json:"defaultAccountId,string"` DefaultAccountId int64 `json:"defaultAccountId,string"`
FirstDayOfWeek WeekDay `json:"firstDayOfWeek"`
TransactionEditScope TransactionEditScope `json:"transactionEditScope"` TransactionEditScope TransactionEditScope `json:"transactionEditScope"`
Language string `json:"language"`
DefaultCurrency string `json:"defaultCurrency"`
FirstDayOfWeek WeekDay `json:"firstDayOfWeek"`
LongDateFormat LongDateFormat `json:"longDateFormat"`
ShortDateFormat ShortDateFormat `json:"shortDateFormat"`
LongTimeFormat LongTimeFormat `json:"longTimeFormat"`
ShortTimeFormat ShortTimeFormat `json:"shortTimeFormat"`
LastLoginAt int64 `json:"lastLoginAt"` LastLoginAt int64 `json:"lastLoginAt"`
} }
@@ -210,10 +192,15 @@ func (u *User) ToUserBasicInfo() *UserBasicInfo {
Username: u.Username, Username: u.Username,
Email: u.Email, Email: u.Email,
Nickname: u.Nickname, Nickname: u.Nickname,
DefaultCurrency: u.DefaultCurrency,
DefaultAccountId: u.DefaultAccountId, DefaultAccountId: u.DefaultAccountId,
FirstDayOfWeek: u.FirstDayOfWeek,
TransactionEditScope: u.TransactionEditScope, TransactionEditScope: u.TransactionEditScope,
Language: u.Language,
DefaultCurrency: u.DefaultCurrency,
FirstDayOfWeek: u.FirstDayOfWeek,
LongDateFormat: u.LongDateFormat,
ShortDateFormat: u.ShortDateFormat,
LongTimeFormat: u.LongTimeFormat,
ShortTimeFormat: u.ShortTimeFormat,
} }
} }
@@ -223,10 +210,15 @@ func (u *User) ToUserProfileResponse() *UserProfileResponse {
Username: u.Username, Username: u.Username,
Email: u.Email, Email: u.Email,
Nickname: u.Nickname, Nickname: u.Nickname,
DefaultCurrency: u.DefaultCurrency,
DefaultAccountId: u.DefaultAccountId, DefaultAccountId: u.DefaultAccountId,
FirstDayOfWeek: u.FirstDayOfWeek,
TransactionEditScope: u.TransactionEditScope, TransactionEditScope: u.TransactionEditScope,
Language: u.Language,
DefaultCurrency: u.DefaultCurrency,
FirstDayOfWeek: u.FirstDayOfWeek,
LongDateFormat: u.LongDateFormat,
ShortDateFormat: u.ShortDateFormat,
LongTimeFormat: u.LongTimeFormat,
ShortTimeFormat: u.ShortTimeFormat,
LastLoginAt: u.LastLoginUnixTime, LastLoginAt: u.LastLoginUnixTime,
} }
} }
+27 -7
View File
@@ -150,7 +150,7 @@ func (s *UserService) CreateUser(user *models.User) error {
} }
// UpdateUser saves an existed user model to database // UpdateUser saves an existed user model to database
func (s *UserService) UpdateUser(user *models.User) (keyProfileUpdated bool, err error) { func (s *UserService) UpdateUser(user *models.User, modifyUserLanguage bool) (keyProfileUpdated bool, err error) {
if user.Uid <= 0 { if user.Uid <= 0 {
return false, errs.ErrUserIdInvalid return false, errs.ErrUserIdInvalid
} }
@@ -186,20 +186,40 @@ func (s *UserService) UpdateUser(user *models.User) (keyProfileUpdated bool, err
updateCols = append(updateCols, "nickname") updateCols = append(updateCols, "nickname")
} }
if user.DefaultCurrency != "" {
updateCols = append(updateCols, "default_currency")
}
if user.DefaultAccountId > 0 { if user.DefaultAccountId > 0 {
updateCols = append(updateCols, "default_account_id") updateCols = append(updateCols, "default_account_id")
} }
if models.TRANSACTION_EDIT_SCOPE_NONE <= user.TransactionEditScope && user.TransactionEditScope <= models.TRANSACTION_EDIT_SCOPE_THIS_YEAR_OR_LATER {
updateCols = append(updateCols, "transaction_edit_scope")
}
if modifyUserLanguage || user.Language != "" {
updateCols = append(updateCols, "language")
}
if user.DefaultCurrency != "" {
updateCols = append(updateCols, "default_currency")
}
if models.WEEKDAY_SUNDAY <= user.FirstDayOfWeek && user.FirstDayOfWeek <= models.WEEKDAY_SATURDAY { if models.WEEKDAY_SUNDAY <= user.FirstDayOfWeek && user.FirstDayOfWeek <= models.WEEKDAY_SATURDAY {
updateCols = append(updateCols, "first_day_of_week") updateCols = append(updateCols, "first_day_of_week")
} }
if models.TRANSACTION_EDIT_SCOPE_NONE <= user.TransactionEditScope && user.TransactionEditScope <= models.TRANSACTION_EDIT_SCOPE_THIS_YEAR_OR_LATER { if models.LONG_DATE_FORMAT_DEFAULT <= user.LongDateFormat && user.LongDateFormat <= models.LONG_DATE_FORMAT_D_M_YYYY {
updateCols = append(updateCols, "transaction_edit_scope") updateCols = append(updateCols, "long_date_format")
}
if models.SHORT_DATE_FORMAT_DEFAULT <= user.ShortDateFormat && user.ShortDateFormat <= models.SHORT_DATE_FORMAT_D_M_YYYY {
updateCols = append(updateCols, "short_date_format")
}
if models.LONG_TIME_FORMAT_DEFAULT <= user.LongTimeFormat && user.LongTimeFormat <= models.LONG_TIME_FORMAT_HH_MM_SS_A {
updateCols = append(updateCols, "long_time_format")
}
if models.SHORT_TIME_FORMAT_DEFAULT <= user.ShortTimeFormat && user.ShortTimeFormat <= models.SHORT_TIME_FORMAT_HH_MM_A {
updateCols = append(updateCols, "short_time_format")
} }
user.UpdatedUnixTime = now user.UpdatedUnixTime = now
+11 -5
View File
@@ -75,14 +75,20 @@ export default {
} }
}, },
created() { created() {
if (this.$user.isUserLogined()) { const self = this;
if (!this.$settings.isEnableApplicationLock()) {
if (self.$user.isUserLogined()) {
if (!self.$settings.isEnableApplicationLock()) {
// refresh token if user is logined // refresh token if user is logined
this.$store.dispatch('refreshTokenAndRevokeOldToken'); self.$store.dispatch('refreshTokenAndRevokeOldToken').then(response => {
if (response.user && response.user.language) {
self.$locale.setLanguage(response.user.language);
}
});
// auto refresh exchange rates data // auto refresh exchange rates data
if (this.$settings.isAutoUpdateExchangeRatesData()) { if (self.$settings.isAutoUpdateExchangeRatesData()) {
this.$store.dispatch('getLatestExchangeRates', { silent: true, force: false }); self.$store.dispatch('getLatestExchangeRates', { silent: true, force: false });
} }
} }
} }
@@ -95,16 +95,15 @@ export default {
return this.$utilities.arrangeArrayWithNewStartIndex(this.$locale.getAllMinWeekdayNames(), this.firstDayOfWeek); return this.$utilities.arrangeArrayWithNewStartIndex(this.$locale.getAllMinWeekdayNames(), this.firstDayOfWeek);
}, },
is24Hour() { is24Hour() {
const datetimeFormat = this.$t('format.datetime.long'); return this.$locale.isLongTime24HourFormat();
return this.$utilities.is24HourFormat(datetimeFormat);
}, },
beginDateTime() { beginDateTime() {
const actualBeginUnixTime = this.$utilities.getActualUnixTimeForStore(this.$utilities.getUnixTime(this.dateRange[0]), this.$utilities.getTimezoneOffsetMinutes(), this.$utilities.getBrowserTimezoneOffsetMinutes()); const actualBeginUnixTime = this.$utilities.getActualUnixTimeForStore(this.$utilities.getUnixTime(this.dateRange[0]), this.$utilities.getTimezoneOffsetMinutes(), this.$utilities.getBrowserTimezoneOffsetMinutes());
return this.$utilities.formatUnixTime(actualBeginUnixTime, this.$t('format.datetime.long')); return this.$utilities.formatUnixTime(actualBeginUnixTime, this.$locale.getLongDateTimeFormat());
}, },
endDateTime() { endDateTime() {
const actualEndUnixTime = this.$utilities.getActualUnixTimeForStore(this.$utilities.getUnixTime(this.dateRange[1]), this.$utilities.getTimezoneOffsetMinutes(), this.$utilities.getBrowserTimezoneOffsetMinutes()); const actualEndUnixTime = this.$utilities.getActualUnixTimeForStore(this.$utilities.getUnixTime(this.dateRange[1]), this.$utilities.getTimezoneOffsetMinutes(), this.$utilities.getBrowserTimezoneOffsetMinutes());
return this.$utilities.formatUnixTime(actualEndUnixTime, this.$t('format.datetime.long')); return this.$utilities.formatUnixTime(actualEndUnixTime, this.$locale.getLongDateTimeFormat());
}, },
presetRanges() { presetRanges() {
const presetRanges = []; const presetRanges = [];
@@ -70,8 +70,7 @@ export default {
return this.$utilities.arrangeArrayWithNewStartIndex(this.$locale.getAllMinWeekdayNames(), this.firstDayOfWeek); return this.$utilities.arrangeArrayWithNewStartIndex(this.$locale.getAllMinWeekdayNames(), this.firstDayOfWeek);
}, },
is24Hour() { is24Hour() {
const datetimeFormat = this.$t('format.datetime.long'); return this.$locale.isLongTime24HourFormat();
return this.$utilities.is24HourFormat(datetimeFormat);
} }
}, },
methods: { methods: {
+109 -1
View File
@@ -39,6 +39,96 @@ const allWeekDaysArray = [
allWeekDays.Saturday allWeekDays.Saturday
]; ];
const allLongDateFormat = {
YYYYMMDD: {
type: 1,
key: 'yyyy_mm_dd'
},
MMDDYYYY: {
type: 2,
key: 'mm_dd_yyyy'
},
DDMMYYYY: {
type: 3,
key: 'dd_mm_yyyy'
}
};
const allLongDateFormatArray = [
allLongDateFormat.YYYYMMDD,
allLongDateFormat.MMDDYYYY,
allLongDateFormat.DDMMYYYY
];
const allShortDateFormat = {
YYYYMMDD: {
type: 1,
key: 'yyyy_mm_dd'
},
MMDDYYYY: {
type: 2,
key: 'mm_dd_yyyy'
},
DDMMYYYY: {
type: 3,
key: 'dd_mm_yyyy'
}
};
const allShortDateFormatArray = [
allShortDateFormat.YYYYMMDD,
allShortDateFormat.MMDDYYYY,
allShortDateFormat.DDMMYYYY
];
const allLongTimeFormat = {
HHMMSS: {
type: 1,
key: 'hh_mm_ss',
is24HourFormat: true
},
AHHMMSS: {
type: 2,
key: 'a_hh_mm_ss',
is24HourFormat: false
},
HHMMSSA: {
type: 3,
key: 'hh_mm_ss_a',
is24HourFormat: false
}
};
const allLongTimeFormatArray = [
allLongTimeFormat.HHMMSS,
allLongTimeFormat.AHHMMSS,
allLongTimeFormat.HHMMSSA
];
const allShortTimeFormat = {
HHMM: {
type: 1,
key: 'hh_mm',
is24HourFormat: true
},
AHHMM: {
type: 2,
key: 'a_hh_mm',
is24HourFormat: false
},
HHMMA: {
type: 3,
key: 'hh_mm_a',
is24HourFormat: false
}
};
const allShortTimeFormatArray = [
allShortTimeFormat.HHMM,
allShortTimeFormat.AHHMM,
allShortTimeFormat.HHMMA
];
const allDateRanges = { const allDateRanges = {
All: { All: {
type: 0, type: 0,
@@ -91,10 +181,28 @@ const allDateRanges = {
}; };
const defaultFirstDayOfWeek = allWeekDays.Sunday.type; const defaultFirstDayOfWeek = allWeekDays.Sunday.type;
const defaultLongDateFormat = allLongDateFormat.YYYYMMDD;
const defaultShortDateFormat = allShortDateFormat.YYYYMMDD;
const defaultLongTimeFormat = allLongTimeFormat.HHMMSS;
const defaultShortTimeFormat = allShortTimeFormat.HHMM;
const defaultDateTimeFormatValue = 0;
export default { export default {
allWeekDays: allWeekDays, allWeekDays: allWeekDays,
allWeekDaysArray: allWeekDaysArray, allWeekDaysArray: allWeekDaysArray,
allLongDateFormat: allLongDateFormat,
allLongDateFormatArray: allLongDateFormatArray,
allShortDateFormat: allShortDateFormat,
allShortDateFormatArray: allShortDateFormatArray,
allLongTimeFormat: allLongTimeFormat,
allLongTimeFormatArray: allLongTimeFormatArray,
allShortTimeFormat: allShortTimeFormat,
allShortTimeFormatArray: allShortTimeFormatArray,
allDateRanges: allDateRanges, allDateRanges: allDateRanges,
defaultFirstDayOfWeek: defaultFirstDayOfWeek defaultFirstDayOfWeek: defaultFirstDayOfWeek,
defaultLongDateFormat: defaultLongDateFormat,
defaultShortDateFormat: defaultShortDateFormat,
defaultLongTimeFormat: defaultLongTimeFormat,
defaultShortTimeFormat: defaultShortTimeFormat,
defaultDateTimeFormatValue: defaultDateTimeFormatValue,
}; };
+114
View File
@@ -1,4 +1,5 @@
import { defaultLanguage, allLanguages } from '../locales/index.js'; import { defaultLanguage, allLanguages } from '../locales/index.js';
import datetime from "../consts/datetime.js";
import timezone from "../consts/timezone.js"; import timezone from "../consts/timezone.js";
import currency from "../consts/currency.js"; import currency from "../consts/currency.js";
import settings from "./settings.js"; import settings from "./settings.js";
@@ -250,6 +251,88 @@ export function getAllMinWeekdayNames(translateFn) {
]; ];
} }
export function getAllLongDateFormats(translateFn) {
const defaultLongDateFormatTypeName = translateFn('default.longDateFormat');
return getDateTimeFormats(translateFn, datetime.allLongDateFormat, datetime.allLongDateFormatArray, 'format.longDate', defaultLongDateFormatTypeName, datetime.defaultLongDateFormat);
}
export function getAllShortDateFormats(translateFn) {
const defaultShortDateFormatTypeName = translateFn('default.shortDateFormat');
return getDateTimeFormats(translateFn, datetime.allShortDateFormat, datetime.allShortDateFormatArray, 'format.shortDate', defaultShortDateFormatTypeName, datetime.defaultShortDateFormat);
}
export function getAllLongTimeFormats(translateFn) {
const defaultLongTimeFormatTypeName = translateFn('default.longTimeFormat');
return getDateTimeFormats(translateFn, datetime.allLongTimeFormat, datetime.allLongTimeFormatArray, 'format.longTime', defaultLongTimeFormatTypeName, datetime.defaultLongTimeFormat);
}
export function getAllShortTimeFormats(translateFn) {
const defaultShortTimeFormatTypeName = translateFn('default.shortTimeFormat');
return getDateTimeFormats(translateFn, datetime.allShortTimeFormat, datetime.allShortTimeFormatArray, 'format.shortTime', defaultShortTimeFormatTypeName, datetime.defaultShortTimeFormat);
}
export function getI18nLongDateFormat(translateFn, formatTypeValue) {
const defaultLongDateFormatTypeName = translateFn('default.longDateFormat');
return getDateTimeFormat(translateFn, datetime.allLongDateFormat, datetime.allLongDateFormatArray, 'format.longDate', defaultLongDateFormatTypeName, datetime.defaultLongDateFormat, formatTypeValue);
}
export function getI18nShortDateFormat(translateFn, formatTypeValue) {
const defaultShortDateFormatTypeName = translateFn('default.shortDateFormat');
return getDateTimeFormat(translateFn, datetime.allShortDateFormat, datetime.allShortDateFormatArray, 'format.shortDate', defaultShortDateFormatTypeName, datetime.defaultShortDateFormat, formatTypeValue);
}
export function getI18nLongYearFormat(translateFn, formatTypeValue) {
const defaultLongDateFormatTypeName = translateFn('default.longDateFormat');
return getDateTimeFormat(translateFn, datetime.allLongDateFormat, datetime.allLongDateFormatArray, 'format.longYear', defaultLongDateFormatTypeName, datetime.defaultLongDateFormat, formatTypeValue);
}
export function getI18nShortYearFormat(translateFn, formatTypeValue) {
const defaultShortDateFormatTypeName = translateFn('default.shortDateFormat');
return getDateTimeFormat(translateFn, datetime.allShortDateFormat, datetime.allShortDateFormatArray, 'format.shortYear', defaultShortDateFormatTypeName, datetime.defaultShortDateFormat, formatTypeValue);
}
export function getI18nLongYearMonthFormat(translateFn, formatTypeValue) {
const defaultLongDateFormatTypeName = translateFn('default.longDateFormat');
return getDateTimeFormat(translateFn, datetime.allLongDateFormat, datetime.allLongDateFormatArray, 'format.longYearMonth', defaultLongDateFormatTypeName, datetime.defaultLongDateFormat, formatTypeValue);
}
export function getI18nShortYearMonthFormat(translateFn, formatTypeValue) {
const defaultShortDateFormatTypeName = translateFn('default.shortDateFormat');
return getDateTimeFormat(translateFn, datetime.allShortDateFormat, datetime.allShortDateFormatArray, 'format.shortYearMonth', defaultShortDateFormatTypeName, datetime.defaultShortDateFormat, formatTypeValue);
}
export function getI18nLongMonthDayFormat(translateFn, formatTypeValue) {
const defaultLongDateFormatTypeName = translateFn('default.longDateFormat');
return getDateTimeFormat(translateFn, datetime.allLongDateFormat, datetime.allLongDateFormatArray, 'format.longMonthDay', defaultLongDateFormatTypeName, datetime.defaultLongDateFormat, formatTypeValue);
}
export function getI18nShortMonthDayFormat(translateFn, formatTypeValue) {
const defaultShortDateFormatTypeName = translateFn('default.shortDateFormat');
return getDateTimeFormat(translateFn, datetime.allShortDateFormat, datetime.allShortDateFormatArray, 'format.shortMonthDay', defaultShortDateFormatTypeName, datetime.defaultShortDateFormat, formatTypeValue);
}
export function getI18nLongTimeFormat(translateFn, formatTypeValue) {
const defaultLongTimeFormatTypeName = translateFn('default.longTimeFormat');
return getDateTimeFormat(translateFn, datetime.allLongTimeFormat, datetime.allLongTimeFormatArray, 'format.longTime', defaultLongTimeFormatTypeName, datetime.defaultLongTimeFormat, formatTypeValue);
}
export function getI18nShortTimeFormat(translateFn, formatTypeValue) {
const defaultShortTimeFormatTypeName = translateFn('default.shortTimeFormat');
return getDateTimeFormat(translateFn, datetime.allShortTimeFormat, datetime.allShortTimeFormatArray, 'format.shortTime', defaultShortTimeFormatTypeName, datetime.defaultShortTimeFormat, formatTypeValue);
}
export function isLongTime24HourFormat(translateFn, formatTypeValue) {
const defaultLongTimeFormatTypeName = translateFn('default.longTimeFormat');
const type = utilities.getDateTimeFormatType(datetime.allLongTimeFormat, datetime.allLongTimeFormatArray, defaultLongTimeFormatTypeName, datetime.defaultLongTimeFormat, formatTypeValue);
return type.is24HourFormat;
}
export function isShortTime24HourFormat(translateFn, formatTypeValue) {
const defaultShortTimeFormatTypeName = translateFn('default.shortTimeFormat');
const type = utilities.getDateTimeFormatType(datetime.allShortTimeFormat, datetime.allShortTimeFormatArray, defaultShortTimeFormatTypeName, datetime.defaultShortTimeFormat, formatTypeValue);
return type.is24HourFormat;
}
export function getAllTimezones(includeSystemDefault, translateFn) { export function getAllTimezones(includeSystemDefault, translateFn) {
const defaultTimezoneOffset = utilities.getTimezoneOffset(); const defaultTimezoneOffset = utilities.getTimezoneOffset();
const defaultTimezoneOffsetMinutes = utilities.getTimezoneOffsetMinutes(); const defaultTimezoneOffsetMinutes = utilities.getTimezoneOffsetMinutes();
@@ -462,3 +545,34 @@ function getLocaleFromLanguageAlias(alias) {
return null; return null;
} }
function getDateTimeFormats(translateFn, allFormatMap, allFormatArray, localeFormatPathPrefix, localeDefaultFormatTypeName, systemDefaultFormatType) {
const defaultFormat = getDateTimeFormat(translateFn, allFormatMap, allFormatArray,
localeFormatPathPrefix, localeDefaultFormatTypeName, systemDefaultFormatType, datetime.defaultDateTimeFormatValue);
const ret = [];
ret.push({
type: datetime.defaultDateTimeFormatValue,
format: defaultFormat,
displayName: `${translateFn('Language Default')} (${utilities.formatTime(utilities.getCurrentDateTime(), defaultFormat)})`
});
for (let i = 0; i < allFormatArray.length; i++) {
const formatType = allFormatArray[i];
const format = translateFn(`${localeFormatPathPrefix}.${formatType.key}`);
ret.push({
type: formatType.type,
format: format,
displayName: utilities.formatTime(utilities.getCurrentDateTime(), format)
});
}
return ret;
}
function getDateTimeFormat(translateFn, allFormatMap, allFormatArray, localeFormatPathPrefix, localeDefaultFormatTypeName, systemDefaultFormatType, formatTypeValue) {
const type = utilities.getDateTimeFormatType(allFormatMap, allFormatArray,
localeDefaultFormatTypeName, systemDefaultFormatType, formatTypeValue);
return translateFn(`${localeFormatPathPrefix}.${type.key}`);
}
+10 -4
View File
@@ -87,12 +87,13 @@ export default {
} }
}); });
}, },
register: ({ username, email, nickname, password, defaultCurrency, firstDayOfWeek }) => { register: ({ username, email, nickname, password, language, defaultCurrency, firstDayOfWeek }) => {
return axios.post('register.json', { return axios.post('register.json', {
username, username,
email, email,
nickname, nickname,
password, password,
language,
defaultCurrency, defaultCurrency,
firstDayOfWeek firstDayOfWeek
}); });
@@ -135,16 +136,21 @@ export default {
getProfile: () => { getProfile: () => {
return axios.get('v1/users/profile/get.json'); return axios.get('v1/users/profile/get.json');
}, },
updateProfile: ({ email, nickname, password, oldPassword, defaultCurrency, defaultAccountId, firstDayOfWeek, transactionEditScope }) => { updateProfile: ({ email, nickname, password, oldPassword, defaultAccountId, transactionEditScope, language, defaultCurrency, firstDayOfWeek, longDateFormat, shortDateFormat, longTimeFormat, shortTimeFormat }) => {
return axios.post('v1/users/profile/update.json', { return axios.post('v1/users/profile/update.json', {
email, email,
nickname, nickname,
password, password,
oldPassword, oldPassword,
defaultCurrency,
defaultAccountId, defaultAccountId,
transactionEditScope,
language,
defaultCurrency,
firstDayOfWeek, firstDayOfWeek,
transactionEditScope longDateFormat,
shortDateFormat,
longTimeFormat,
shortTimeFormat
}); });
}, },
get2FAStatus: () => { get2FAStatus: () => {
-3
View File
@@ -7,7 +7,6 @@ const settingsLocalStorageKey = 'ebk_app_settings';
const serverSettingsCookieKey = 'ebk_server_settings'; const serverSettingsCookieKey = 'ebk_server_settings';
const defaultSettings = { const defaultSettings = {
lang: 'en',
timeZone: '', timeZone: '',
debug: false, debug: false,
applicationLock: false, applicationLock: false,
@@ -129,8 +128,6 @@ function clearSettings() {
export default { export default {
isProduction: () => process.env.NODE_ENV === 'production', isProduction: () => process.env.NODE_ENV === 'production',
getLanguage: () => getOriginalOption('lang'),
setLanguage: value => setOption('lang', value),
getTimezone: () => getOption('timeZone'), getTimezone: () => getOption('timeZone'),
setTimezone: value => setOption('timeZone', value), setTimezone: value => setOption('timeZone', value),
isEnableDebug: () => getOption('debug'), isEnableDebug: () => getOption('debug'),
+10 -10
View File
@@ -89,16 +89,6 @@ export function parseDateFromUnixTime(unixTime, utcOffset, currentUtcOffset) {
return moment.unix(unixTime); return moment.unix(unixTime);
} }
export function is24HourFormat(format) {
if (format.indexOf('HH') >= 0 && format.indexOf('hh') < 0) {
return true;
} else if (format.indexOf('HH') < 0 && format.indexOf('hh') >= 0) {
return false;
}
return true;
}
export function formatUnixTime(unixTime, format, utcOffset, currentUtcOffset) { export function formatUnixTime(unixTime, format, utcOffset, currentUtcOffset) {
return parseDateFromUnixTime(unixTime, utcOffset, currentUtcOffset).format(format); return parseDateFromUnixTime(unixTime, utcOffset, currentUtcOffset).format(format);
} }
@@ -214,6 +204,16 @@ export function getThisYearLastUnixTime() {
return moment.unix(getThisYearFirstUnixTime()).add(1, 'years').subtract(1, 'seconds').unix(); return moment.unix(getThisYearFirstUnixTime()).add(1, 'years').subtract(1, 'seconds').unix();
} }
export function getDateTimeFormatType(allFormatMap, allFormatArray, localeDefaultFormatTypeName, systemDefaultFormatType, formatTypeValue) {
if (formatTypeValue > dateTimeConstants.defaultDateTimeFormatValue && allFormatArray[formatTypeValue - 1] && allFormatArray[formatTypeValue - 1].key) {
return allFormatArray[formatTypeValue - 1];
} else if (formatTypeValue === dateTimeConstants.defaultDateTimeFormatValue && allFormatMap[localeDefaultFormatTypeName] && allFormatMap[localeDefaultFormatTypeName].key) {
return allFormatMap[localeDefaultFormatTypeName];
} else {
return systemDefaultFormatType;
}
}
export function getShiftedDateRange(minTime, maxTime, scale) { export function getShiftedDateRange(minTime, maxTime, scale) {
const minDateTime = parseDateFromUnixTime(minTime).set({ second: 0, millisecond: 0 }); const minDateTime = parseDateFromUnixTime(minTime).set({ second: 0, millisecond: 0 });
const maxDateTime = parseDateFromUnixTime(maxTime).set({ second: 59, millisecond: 999 }); const maxDateTime = parseDateFromUnixTime(maxTime).set({ second: 59, millisecond: 999 });
+2 -2
View File
@@ -31,7 +31,6 @@ import {
getCurrentUnixTime, getCurrentUnixTime,
getCurrentDateTime, getCurrentDateTime,
parseDateFromUnixTime, parseDateFromUnixTime,
is24HourFormat,
formatUnixTime, formatUnixTime,
formatTime, formatTime,
getUnixTime, getUnixTime,
@@ -55,6 +54,7 @@ import {
getThisMonthLastUnixTime, getThisMonthLastUnixTime,
getThisYearFirstUnixTime, getThisYearFirstUnixTime,
getThisYearLastUnixTime, getThisYearLastUnixTime,
getDateTimeFormatType,
getShiftedDateRange, getShiftedDateRange,
getDateRangeByDateType, getDateRangeByDateType,
isDateRangeMatchFullYears, isDateRangeMatchFullYears,
@@ -123,7 +123,6 @@ export default {
getCurrentUnixTime, getCurrentUnixTime,
getCurrentDateTime, getCurrentDateTime,
parseDateFromUnixTime, parseDateFromUnixTime,
is24HourFormat,
formatUnixTime, formatUnixTime,
formatTime, formatTime,
getUnixTime, getUnixTime,
@@ -147,6 +146,7 @@ export default {
getThisMonthLastUnixTime, getThisMonthLastUnixTime,
getThisYearFirstUnixTime, getThisYearFirstUnixTime,
getThisYearLastUnixTime, getThisYearLastUnixTime,
getDateTimeFormatType,
getShiftedDateRange, getShiftedDateRange,
getDateRangeByDateType, getDateRangeByDateType,
isDateRangeMatchFullYears, isDateRangeMatchFullYears,
+61 -18
View File
@@ -6,31 +6,62 @@ export default {
}, },
'default': { 'default': {
'currency': 'USD', 'currency': 'USD',
'firstDayOfWeek': 'Sunday' 'firstDayOfWeek': 'Sunday',
'longDateFormat': 'MMDDYYYY',
'shortDateFormat': 'MMDDYYYY',
'longTimeFormat': 'HHMMSSA',
'shortTimeFormat': 'HHMMA'
}, },
'format': { // The type of date or time format is moment format, ref: https://momentjs.com/docs/#/displaying/ 'format': { // The type of date or time format is moment format, ref: https://momentjs.com/docs/#/displaying/
'date': { 'longDate': {
'long': 'M/D/YYYY', 'yyyy_mm_dd': 'YYYY MMMM DD',
'short': 'M/D/YYYY' 'mm_dd_yyyy': 'MMMM D, YYYY',
'dd_mm_yyyy': 'D MMMM, YYYY'
}, },
'datetime': { 'shortDate': {
'long': 'M/D/YYYY hh:mm:ss A', 'yyyy_mm_dd': 'YYYY-M-D',
'long-without-second': 'M/D/YYYY hh:mm A', 'mm_dd_yyyy': 'M/D/YYYY',
'dd_mm_yyyy': 'D/M/YYYY'
}, },
'year': { 'longYear': { // used in home page
'long': 'YYYY', 'yyyy_mm_dd': 'YYYY',
'short': 'YYYY' 'mm_dd_yyyy': 'YYYY',
'dd_mm_yyyy': 'YYYY'
}, },
'yearMonth': { 'shortYear': {// used in transaction statistics page
'long': 'YYYY-M', 'yyyy_mm_dd': 'YYYY',
'short': 'YYYY-M' 'mm_dd_yyyy': 'YYYY',
'dd_mm_yyyy': 'YYYY'
}, },
'monthDay': { 'longYearMonth': { // used in transaction list page
'long': 'M/D', 'yyyy_mm_dd': 'YYYY MMMM',
'short': 'M/D' 'mm_dd_yyyy': 'MMMM, YYYY',
'dd_mm_yyyy': 'MMMM, YYYY'
}, },
'hourMinute': { 'shortYearMonth': { // used in transaction statistics page
'long': 'hh:mm A' 'yyyy_mm_dd': 'YYYY-M',
'mm_dd_yyyy': 'MMM, YYYY',
'dd_mm_yyyy': 'MMM, YYYY'
},
'longMonthDay': { // used in home page
'yyyy_mm_dd': 'MMMM D',
'mm_dd_yyyy': 'MMMM D',
'dd_mm_yyyy': 'D MMMM'
},
'shortMonthDay': { // should be similar to the shortDate. it would be next to the shortDate content on the transaction statistics page
'yyyy_mm_dd': 'M/D',
'mm_dd_yyyy': 'M/D',
'dd_mm_yyyy': 'D/M'
},
'longTime': {
'hh_mm_ss': 'HH:mm:ss',
'a_hh_mm_ss': 'A hh:mm:ss',
'hh_mm_ss_a': 'hh:mm:ss A'
},
'shortTime': {
'hh_mm': 'HH:mm',
'a_hh_mm': 'A hh:mm',
'hh_mm_a': 'hh:mm A'
}, },
'currency': { 'currency': {
'symbol': '{symbol} {amount}' 'symbol': '{symbol} {amount}'
@@ -41,6 +72,12 @@ export default {
'exportFilename': 'ezBookkeeping_{nickname}_export_data' 'exportFilename': 'ezBookkeeping_{nickname}_export_data'
}, },
'datetime': { 'datetime': {
'AM': {
'upperCase': 'AM'
},
'PM': {
'upperCase': 'PM'
},
'Monday': { 'Monday': {
'min': 'Mo', 'min': 'Mo',
'short': 'Mon', 'short': 'Mon',
@@ -657,6 +694,7 @@ export default {
'None': 'None', 'None': 'None',
'Not Specified': 'Not Specified', 'Not Specified': 'Not Specified',
'No results': 'No results', 'No results': 'No results',
'Unknown': 'Unknown',
'Done': 'Done', 'Done': 'Done',
'Continue': 'Continue', 'Continue': 'Continue',
'Status': 'Status', 'Status': 'Status',
@@ -727,6 +765,10 @@ export default {
'Default Currency': 'Default Currency', 'Default Currency': 'Default Currency',
'Default Account': 'Default Account', 'Default Account': 'Default Account',
'First Day of Week': 'First Day of Week', 'First Day of Week': 'First Day of Week',
'Long Date Format': 'Long Date Format',
'Short Date Format': 'Short Date Format',
'Long Time Format': 'Long Time Format',
'Short Time Format': 'Short Time Format',
'Editable Transaction Scope': 'Editable Transaction Scope', 'Editable Transaction Scope': 'Editable Transaction Scope',
'Today or later': 'Today or later', 'Today or later': 'Today or later',
'Recent 24 hours or later': 'Recent 24 hours or later', 'Recent 24 hours or later': 'Recent 24 hours or later',
@@ -894,6 +936,7 @@ export default {
'Language': 'Language', 'Language': 'Language',
'Timezone': 'Timezone', 'Timezone': 'Timezone',
'System Default': 'System Default', 'System Default': 'System Default',
'Language Default': 'Language Default',
'Auto Update Exchange Rates Data': 'Auto Update Exchange Rates Data', 'Auto Update Exchange Rates Data': 'Auto Update Exchange Rates Data',
'Auto Get Current Geographic Location': 'Auto Get Current Geographic Location', 'Auto Get Current Geographic Location': 'Auto Get Current Geographic Location',
'Enable Thousands Separator': 'Enable Thousands Separator', 'Enable Thousands Separator': 'Enable Thousands Separator',
-2
View File
@@ -1,5 +1,3 @@
import 'moment/dist/locale/zh-cn.js';
import en from './en.js' import en from './en.js'
import zhHans from './zh_Hans.js' import zhHans from './zh_Hans.js'
+61 -18
View File
@@ -6,31 +6,62 @@ export default {
}, },
'default': { 'default': {
'currency': 'CNY', 'currency': 'CNY',
'firstDayOfWeek': 'Monday' 'firstDayOfWeek': 'Monday',
'longDateFormat': 'YYYYMMDD',
'shortDateFormat': 'YYYYMMDD',
'longTimeFormat': 'HHMMSS',
'shortTimeFormat': 'HHMM'
}, },
'format': { 'format': {
'date': { 'longDate': {
'long': 'YYYY年M月D日', 'yyyy_mm_dd': 'YYYY年M月D日',
'short': 'YYYY-M-D' 'mm_dd_yyyy': 'M/D/YYYY',
'dd_mm_yyyy': 'D/M/YYYY'
}, },
'datetime': { 'shortDate': {
'long': 'YYYY年M月D日 HH:mm:ss', 'yyyy_mm_dd': 'YYYY-M-D',
'long-without-second': 'YYYY年M月D日 HH:mm', 'mm_dd_yyyy': 'M/D/YYYY',
'dd_mm_yyyy': 'D/M/YYYY'
}, },
'year': { 'longYear': {
'long': 'YYYY年', 'yyyy_mm_dd': 'YYYY年',
'short': 'YYYY' 'mm_dd_yyyy': 'YYYY',
'dd_mm_yyyy': 'YYYY年'
}, },
'yearMonth': { 'shortYear': {
'long': 'YYYY年M月', 'yyyy_mm_dd': 'YYYY',
'short': 'YYYY-M' 'mm_dd_yyyy': 'YYYY',
'dd_mm_yyyy': 'YYYY'
}, },
'monthDay': { 'longYearMonth': {
'long': 'M月D日', 'yyyy_mm_dd': 'YYYY年M月',
'short': 'M-D' 'mm_dd_yyyy': 'M/YYYY',
'dd_mm_yyyy': 'M/YYYY'
}, },
'hourMinute': { 'shortYearMonth': {
'long': 'HH:mm' 'yyyy_mm_dd': 'YYYY-M',
'mm_dd_yyyy': 'M/YYYY',
'dd_mm_yyyy': 'M/YYYY'
},
'longMonthDay': {
'yyyy_mm_dd': 'M月D日',
'mm_dd_yyyy': 'M/D',
'dd_mm_yyyy': 'D/M'
},
'shortMonthDay': {
'yyyy_mm_dd': 'M-D',
'mm_dd_yyyy': 'M/D',
'dd_mm_yyyy': 'D/M'
},
'longTime': {
'hh_mm_ss': 'HH:mm:ss',
'a_hh_mm_ss': 'A hh:mm:ss',
'hh_mm_ss_a': 'hh:mm:ss A'
},
'shortTime': {
'hh_mm': 'HH:mm',
'a_hh_mm': 'A hh:mm',
'hh_mm_a': 'hh:mm A'
}, },
'currency': { 'currency': {
'symbol': '{symbol} {amount}' 'symbol': '{symbol} {amount}'
@@ -41,6 +72,12 @@ export default {
'exportFilename': 'ezBookkeeping_{nickname}_导出数据' 'exportFilename': 'ezBookkeeping_{nickname}_导出数据'
}, },
'datetime': { 'datetime': {
'AM': {
'upperCase': '上午'
},
'PM': {
'upperCase': '下午'
},
'Monday': { 'Monday': {
'min': '一', 'min': '一',
'short': '周一', 'short': '周一',
@@ -657,6 +694,7 @@ export default {
'None': '无', 'None': '无',
'Not Specified': '未指定', 'Not Specified': '未指定',
'No results': '无结果', 'No results': '无结果',
'Unknown': '未知',
'Done': '完成', 'Done': '完成',
'Continue': '继续', 'Continue': '继续',
'Status': '状态', 'Status': '状态',
@@ -727,6 +765,10 @@ export default {
'Default Currency': '默认货币', 'Default Currency': '默认货币',
'Default Account': '默认账户', 'Default Account': '默认账户',
'First Day of Week': '每周第一天', 'First Day of Week': '每周第一天',
'Long Date Format': '长日期格式',
'Short Date Format': '短日期格式',
'Long Time Format': '长时间格式',
'Short Time Format': '短时间格式',
'Editable Transaction Scope': '可编辑交易范围', 'Editable Transaction Scope': '可编辑交易范围',
'Today or later': '今天或更晚', 'Today or later': '今天或更晚',
'Recent 24 hours or later': '最近24小时或更晚', 'Recent 24 hours or later': '最近24小时或更晚',
@@ -894,6 +936,7 @@ export default {
'Language': '语言', 'Language': '语言',
'Timezone': '时区', 'Timezone': '时区',
'System Default': '系统默认', 'System Default': '系统默认',
'Language Default': '语言默认',
'Auto Update Exchange Rates Data': '自动更新汇率数据', 'Auto Update Exchange Rates Data': '自动更新汇率数据',
'Auto Get Current Geographic Location': '自动获取当前地理位置', 'Auto Get Current Geographic Location': '自动获取当前地理位置',
'Enable Thousands Separator': '启用千位分隔符', 'Enable Thousands Separator': '启用千位分隔符',
+61 -7
View File
@@ -104,6 +104,22 @@ import {
getAllLongWeekdayNames, getAllLongWeekdayNames,
getAllShortWeekdayNames, getAllShortWeekdayNames,
getAllMinWeekdayNames, getAllMinWeekdayNames,
getAllLongDateFormats,
getAllShortDateFormats,
getAllLongTimeFormats,
getAllShortTimeFormats,
getI18nLongDateFormat,
getI18nShortDateFormat,
getI18nLongTimeFormat,
getI18nShortTimeFormat,
getI18nLongYearFormat,
getI18nShortYearFormat,
getI18nLongYearMonthFormat,
getI18nShortYearMonthFormat,
getI18nLongMonthDayFormat,
getI18nShortMonthDayFormat,
isLongTime24HourFormat,
isShortTime24HourFormat,
getAllTimezones, getAllTimezones,
getAllCurrencies, getAllCurrencies,
getDisplayCurrency, getDisplayCurrency,
@@ -186,10 +202,22 @@ app.use(store);
app.use(i18n); app.use(i18n);
function setLanguage(locale) { function setLanguage(locale) {
if (settings.getLanguage() !== locale) { if (!locale) {
settings.setLanguage(locale); locale = getDefaultLanguage();
logger.info(`No specified language, use browser default language ${locale}`);
} }
if (!getLanguageInfo(locale)) {
logger.warn(`Not found language ${locale}`);
return null;
}
if (i18n.global.locale === locale) {
return locale;
}
logger.info(`Apply current language to ${locale}`);
i18n.global.locale = locale; i18n.global.locale = locale;
moment.updateLocale(locale, { moment.updateLocale(locale, {
months : app.config.globalProperties.$locale.getAllLongMonthNames(), months : app.config.globalProperties.$locale.getAllLongMonthNames(),
@@ -197,6 +225,13 @@ function setLanguage(locale) {
weekdays : app.config.globalProperties.$locale.getAllLongWeekdayNames(), weekdays : app.config.globalProperties.$locale.getAllLongWeekdayNames(),
weekdaysShort : app.config.globalProperties.$locale.getAllShortWeekdayNames(), weekdaysShort : app.config.globalProperties.$locale.getAllShortWeekdayNames(),
weekdaysMin : app.config.globalProperties.$locale.getAllMinWeekdayNames(), weekdaysMin : app.config.globalProperties.$locale.getAllMinWeekdayNames(),
meridiem: function (hours) {
if (hours > 11) {
return i18n.global.t('datetime.PM.upperCase');
} else {
return i18n.global.t('datetime.AM.upperCase');
}
}
}); });
services.setLocale(locale); services.setLocale(locale);
document.querySelector('html').setAttribute('lang', locale); document.querySelector('html').setAttribute('lang', locale);
@@ -225,12 +260,13 @@ function setTimezone(timezone) {
} }
function initLocale() { function initLocale() {
if (settings.getLanguage()) { const lastUserLanguage = store.getters.currentUserLanguage;
logger.info(`Current language is ${settings.getLanguage()}`);
setLanguage(settings.getLanguage()); if (lastUserLanguage && getLanguageInfo(lastUserLanguage)) {
logger.info(`Last user language is ${lastUserLanguage}`);
setLanguage(lastUserLanguage);
} else { } else {
logger.info(`No language is set, use browser default ${getDefaultLanguage()}`); setLanguage(null);
setLanguage(getDefaultLanguage());
} }
if (settings.getTimezone()) { if (settings.getTimezone()) {
@@ -296,6 +332,24 @@ app.config.globalProperties.$locale = {
getAllLongWeekdayNames: () => getAllLongWeekdayNames(i18n.global.t), getAllLongWeekdayNames: () => getAllLongWeekdayNames(i18n.global.t),
getAllShortWeekdayNames: () => getAllShortWeekdayNames(i18n.global.t), getAllShortWeekdayNames: () => getAllShortWeekdayNames(i18n.global.t),
getAllMinWeekdayNames: () => getAllMinWeekdayNames(i18n.global.t), getAllMinWeekdayNames: () => getAllMinWeekdayNames(i18n.global.t),
getAllLongDateFormats: () => getAllLongDateFormats(i18n.global.t),
getAllShortDateFormats: () => getAllShortDateFormats(i18n.global.t),
getAllLongTimeFormats: () => getAllLongTimeFormats(i18n.global.t),
getAllShortTimeFormats: () => getAllShortTimeFormats(i18n.global.t),
getLongDateTimeFormat: () => getI18nLongDateFormat(i18n.global.t, store.getters.currentUserLongDateFormat) + ' ' + getI18nLongTimeFormat(i18n.global.t, store.getters.currentUserLongTimeFormat),
getShortDateTimeFormat: () => getI18nShortDateFormat(i18n.global.t, store.getters.currentUserShortDateFormat) + ' ' + getI18nShortTimeFormat(i18n.global.t, store.getters.currentUserShortTimeFormat),
getLongDateFormat: () => getI18nLongDateFormat(i18n.global.t, store.getters.currentUserLongDateFormat),
getShortDateFormat: () => getI18nShortDateFormat(i18n.global.t, store.getters.currentUserShortDateFormat),
getLongYearFormat: () => getI18nLongYearFormat(i18n.global.t, store.getters.currentUserLongDateFormat),
getShortYearFormat: () => getI18nShortYearFormat(i18n.global.t, store.getters.currentUserShortDateFormat),
getLongYearMonthFormat: () => getI18nLongYearMonthFormat(i18n.global.t, store.getters.currentUserLongDateFormat),
getShortYearMonthFormat: () => getI18nShortYearMonthFormat(i18n.global.t, store.getters.currentUserShortDateFormat),
getLongMonthDayFormat: () => getI18nLongMonthDayFormat(i18n.global.t, store.getters.currentUserLongDateFormat),
getShortMonthDayFormat: () => getI18nShortMonthDayFormat(i18n.global.t, store.getters.currentUserShortDateFormat),
getLongTimeFormat: () => getI18nLongTimeFormat(i18n.global.t, store.getters.currentUserLongTimeFormat),
getShortTimeFormat: () => getI18nShortTimeFormat(i18n.global.t, store.getters.currentUserShortTimeFormat),
isLongTime24HourFormat: () => isLongTime24HourFormat(i18n.global.t, store.getters.currentUserLongTimeFormat),
isShortTime24HourFormat: () => isShortTime24HourFormat(i18n.global.t, store.getters.currentUserShortTimeFormat),
setLanguage: setLanguage, setLanguage: setLanguage,
getTimezone: settings.getTimezone, getTimezone: settings.getTimezone,
setTimezone: setTimezone, setTimezone: setTimezone,
+18 -3
View File
@@ -73,9 +73,14 @@ import {
clearUserInfoState, clearUserInfoState,
resetState, resetState,
currentUserNickname, currentUserNickname,
currentUserDefaultCurrency,
currentUserDefaultAccountId, currentUserDefaultAccountId,
currentUserLanguage,
currentUserDefaultCurrency,
currentUserFirstDayOfWeek, currentUserFirstDayOfWeek,
currentUserLongDateFormat,
currentUserShortDateFormat,
currentUserLongTimeFormat,
currentUserShortTimeFormat,
} from './user.js'; } from './user.js';
import { import {
@@ -166,8 +171,13 @@ const stores = {
strict: !settings.isProduction(), strict: !settings.isProduction(),
state: { state: {
defaultSetting: { defaultSetting: {
language: '',
currency: currencyConstants.defaultCurrency, currency: currencyConstants.defaultCurrency,
firstDayOfWeek: datetimeConstants.defaultFirstDayOfWeek firstDayOfWeek: datetimeConstants.defaultFirstDayOfWeek,
longDateFormat: 0,
shortDateFormat: 0,
longTimeFormat: 0,
shortTimeFormat: 0
}, },
currentUserInfo: userState.getUserInfo(), currentUserInfo: userState.getUserInfo(),
latestExchangeRates: getExchangeRatesFromLocalStorage(), latestExchangeRates: getExchangeRatesFromLocalStorage(),
@@ -210,9 +220,14 @@ const stores = {
getters: { getters: {
// user // user
currentUserNickname, currentUserNickname,
currentUserDefaultCurrency,
currentUserDefaultAccountId, currentUserDefaultAccountId,
currentUserLanguage,
currentUserDefaultCurrency,
currentUserFirstDayOfWeek, currentUserFirstDayOfWeek,
currentUserLongDateFormat,
currentUserShortDateFormat,
currentUserLongTimeFormat,
currentUserShortTimeFormat,
// exchange rates // exchange rates
exchangeRatesLastUpdateTime, exchangeRatesLastUpdateTime,
+38 -7
View File
@@ -133,6 +133,7 @@ export function register(context, { user }) {
password: user.password, password: user.password,
email: user.email, email: user.email,
nickname: user.nickname, nickname: user.nickname,
language: user.language,
defaultCurrency: user.defaultCurrency, defaultCurrency: user.defaultCurrency,
firstDayOfWeek: user.firstDayOfWeek firstDayOfWeek: user.firstDayOfWeek
}).then(response => { }).then(response => {
@@ -235,10 +236,15 @@ export function updateUserProfile(context, { profile, currentPassword }) {
oldPassword: currentPassword, oldPassword: currentPassword,
email: profile.email, email: profile.email,
nickname: profile.nickname, nickname: profile.nickname,
defaultCurrency: profile.defaultCurrency,
defaultAccountId: profile.defaultAccountId, defaultAccountId: profile.defaultAccountId,
transactionEditScope: profile.transactionEditScope,
language: profile.language,
defaultCurrency: profile.defaultCurrency,
firstDayOfWeek: profile.firstDayOfWeek, firstDayOfWeek: profile.firstDayOfWeek,
transactionEditScope: profile.transactionEditScope longDateFormat: profile.longDateFormat,
shortDateFormat: profile.shortDateFormat,
longTimeFormat: profile.longTimeFormat,
shortTimeFormat: profile.shortTimeFormat
}).then(response => { }).then(response => {
const data = response.data; const data = response.data;
@@ -391,17 +397,42 @@ export function currentUserNickname(state) {
return userInfo.nickname || userInfo.username || null; return userInfo.nickname || userInfo.username || null;
} }
export function currentUserDefaultCurrency(state) {
const userInfo = state.currentUserInfo || {};
return userInfo.defaultCurrency || state.defaultSetting.currency;
}
export function currentUserDefaultAccountId(state) { export function currentUserDefaultAccountId(state) {
const userInfo = state.currentUserInfo || {}; const userInfo = state.currentUserInfo || {};
return userInfo.defaultAccountId || ''; return userInfo.defaultAccountId || '';
} }
export function currentUserLanguage(state) {
const userInfo = state.currentUserInfo || {};
return userInfo.language || state.defaultSetting.language;
}
export function currentUserDefaultCurrency(state) {
const userInfo = state.currentUserInfo || {};
return userInfo.defaultCurrency || state.defaultSetting.currency;
}
export function currentUserFirstDayOfWeek(state) { export function currentUserFirstDayOfWeek(state) {
const userInfo = state.currentUserInfo || {}; const userInfo = state.currentUserInfo || {};
return utilities.isNumber(userInfo.firstDayOfWeek) ? userInfo.firstDayOfWeek : state.defaultSetting.firstDayOfWeek; return utilities.isNumber(userInfo.firstDayOfWeek) ? userInfo.firstDayOfWeek : state.defaultSetting.firstDayOfWeek;
} }
export function currentUserLongDateFormat(state) {
const userInfo = state.currentUserInfo || {};
return utilities.isNumber(userInfo.longDateFormat) ? userInfo.longDateFormat : state.defaultSetting.longDateFormat;
}
export function currentUserShortDateFormat(state) {
const userInfo = state.currentUserInfo || {};
return utilities.isNumber(userInfo.shortDateFormat) ? userInfo.shortDateFormat : state.defaultSetting.shortDateFormat;
}
export function currentUserLongTimeFormat(state) {
const userInfo = state.currentUserInfo || {};
return utilities.isNumber(userInfo.longTimeFormat) ? userInfo.longTimeFormat : state.defaultSetting.longTimeFormat;
}
export function currentUserShortTimeFormat(state) {
const userInfo = state.currentUserInfo || {};
return utilities.isNumber(userInfo.shortTimeFormat) ? userInfo.shortTimeFormat : state.defaultSetting.shortTimeFormat;
}
+1 -1
View File
@@ -51,7 +51,7 @@ export default {
return this.$buildTime; return this.$buildTime;
} }
return this.$utilities.formatUnixTime(this.$buildTime, this.$t('format.datetime.long')); return this.$utilities.formatUnixTime(this.$buildTime, this.$locale.getLongDateTimeFormat());
}, },
licenseLines() { licenseLines() {
return this.$licenses.license.replaceAll(/\r/g, '').split('\n'); return this.$licenses.license.replaceAll(/\r/g, '').split('\n');
+1 -1
View File
@@ -111,7 +111,7 @@ export default {
return ''; return '';
} }
return this.$utilities.formatUnixTime(this.exchangeRatesData.updateTime, this.$t('format.date.long')); return this.$utilities.formatUnixTime(this.exchangeRatesData.updateTime, this.$locale.getLongDateFormat());
}, },
exchangeRateMap() { exchangeRateMap() {
const exchangeRateMap = {}; const exchangeRateMap = {};
+6 -6
View File
@@ -235,19 +235,19 @@ export default {
return { return {
today: { today: {
displayTime: self.$utilities.formatUnixTime(self.dateRange.today.startTime, self.$t('format.date.long')), displayTime: self.$utilities.formatUnixTime(self.dateRange.today.startTime, self.$locale.getLongDateFormat()),
}, },
thisWeek: { thisWeek: {
startTime: self.$utilities.formatUnixTime(self.dateRange.thisWeek.startTime, self.$t('format.monthDay.long')), startTime: self.$utilities.formatUnixTime(self.dateRange.thisWeek.startTime, self.$locale.getLongMonthDayFormat()),
endTime: self.$utilities.formatUnixTime(self.dateRange.thisWeek.endTime, self.$t('format.monthDay.long')) endTime: self.$utilities.formatUnixTime(self.dateRange.thisWeek.endTime, self.$locale.getLongMonthDayFormat())
}, },
thisMonth: { thisMonth: {
displayTime: self.$utilities.formatUnixTime(self.dateRange.thisMonth.startTime, 'MMMM'), displayTime: self.$utilities.formatUnixTime(self.dateRange.thisMonth.startTime, 'MMMM'),
startTime: self.$utilities.formatUnixTime(self.dateRange.thisMonth.startTime, self.$t('format.monthDay.long')), startTime: self.$utilities.formatUnixTime(self.dateRange.thisMonth.startTime, self.$locale.getLongMonthDayFormat()),
endTime: self.$utilities.formatUnixTime(self.dateRange.thisMonth.endTime, self.$t('format.monthDay.long')) endTime: self.$utilities.formatUnixTime(self.dateRange.thisMonth.endTime, self.$locale.getLongMonthDayFormat())
}, },
thisYear: { thisYear: {
displayTime: self.$utilities.formatUnixTime(self.dateRange.thisYear.startTime, self.$t('format.year.long')) displayTime: self.$utilities.formatUnixTime(self.dateRange.thisYear.startTime, self.$locale.getLongYearFormat())
} }
}; };
}, },
+9 -1
View File
@@ -200,6 +200,10 @@ export default {
return; return;
} }
if (authResponse.user && authResponse.user.language) {
self.$locale.setLanguage(authResponse.user.language);
}
if (self.$settings.isAutoUpdateExchangeRatesData()) { if (self.$settings.isAutoUpdateExchangeRatesData()) {
self.$store.dispatch('getLatestExchangeRates', { silent: true, force: false }); self.$store.dispatch('getLatestExchangeRates', { silent: true, force: false });
} }
@@ -244,10 +248,14 @@ export default {
token: self.tempToken, token: self.tempToken,
passcode: self.twoFAVerifyType === 'passcode' ? self.passcode : null, passcode: self.twoFAVerifyType === 'passcode' ? self.passcode : null,
recoveryCode: self.twoFAVerifyType === 'backupcode' ? self.backupCode : null recoveryCode: self.twoFAVerifyType === 'backupcode' ? self.backupCode : null
}).then(() => { }).then(authResponse => {
self.verifying = false; self.verifying = false;
self.$hideLoading(); self.$hideLoading();
if (authResponse.user && authResponse.user.language) {
self.$locale.setLanguage(authResponse.user.language);
}
if (self.$settings.isAutoUpdateExchangeRatesData()) { if (self.$settings.isAutoUpdateExchangeRatesData()) {
self.$store.dispatch('getLatestExchangeRates', { silent: true, force: false }); self.$store.dispatch('getLatestExchangeRates', { silent: true, force: false });
} }
+1 -25
View File
@@ -16,18 +16,6 @@
<f7-block-title>{{ $t('Application') }}</f7-block-title> <f7-block-title>{{ $t('Application') }}</f7-block-title>
<f7-list strong inset dividers> <f7-list strong inset dividers>
<f7-list-item <f7-list-item
:key="currentLocale + '_lang'"
:title="$t('Language')"
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Language'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), popupCloseLinkText: $t('Done') }">
<select v-model="currentLocale">
<option :value="locale"
:key="locale"
v-for="(lang, locale) in allLanguages">{{ lang.displayName }}</option>
</select>
</f7-list-item>
<f7-list-item
:key="currentLocale + '_timezone'"
:title="$t('Timezone')" :title="$t('Timezone')"
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Timezone'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), popupCloseLinkText: $t('Done') }"> smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Timezone'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), popupCloseLinkText: $t('Done') }">
<select v-model="currentTimezone"> <select v-model="currentTimezone">
@@ -57,7 +45,6 @@
</f7-list-item> </f7-list-item>
<f7-list-item <f7-list-item
:key="currentLocale + '_currency_display'"
:title="$t('Currency Display Mode')" :title="$t('Currency Display Mode')"
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Currency Display Mode'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), popupCloseLinkText: $t('Done') }"> smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Currency Display Mode'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), popupCloseLinkText: $t('Done') }">
<select v-model="currencyDisplayMode"> <select v-model="currencyDisplayMode">
@@ -117,20 +104,9 @@ export default {
version() { version() {
return 'v' + this.$version; return 'v' + this.$version;
}, },
allLanguages() {
return this.$locale.getAllLanguageInfos();
},
allTimezones() { allTimezones() {
return this.$locale.getAllTimezones(true); return this.$locale.getAllTimezones(true);
}, },
currentLocale: {
get: function () {
return this.$i18n.locale;
},
set: function (value) {
this.$locale.setLanguage(value);
}
},
currentTimezone: { currentTimezone: {
get: function () { get: function () {
return this.$locale.getTimezone(); return this.$locale.getTimezone();
@@ -144,7 +120,7 @@ export default {
}, },
exchangeRatesLastUpdateDate() { exchangeRatesLastUpdateDate() {
const exchangeRatesLastUpdateTime = this.$store.getters.exchangeRatesLastUpdateTime; const exchangeRatesLastUpdateTime = this.$store.getters.exchangeRatesLastUpdateTime;
return exchangeRatesLastUpdateTime ? this.$utilities.formatUnixTime(exchangeRatesLastUpdateTime, this.$t('format.date.long')) : ''; return exchangeRatesLastUpdateTime ? this.$utilities.formatUnixTime(exchangeRatesLastUpdateTime, this.$locale.getLongDateFormat()) : '';
}, },
isAutoUpdateExchangeRatesData: { isAutoUpdateExchangeRatesData: {
get: function () { get: function () {
+7 -1
View File
@@ -188,6 +188,7 @@ export default {
confirmPassword: '', confirmPassword: '',
email: '', email: '',
nickname: '', nickname: '',
language: self.$i18n.locale,
defaultCurrency: self.$store.state.defaultSetting.currency, defaultCurrency: self.$store.state.defaultSetting.currency,
firstDayOfWeek: self.$constants.datetime.allWeekDays[self.$t('default.firstDayOfWeek')] ? self.$constants.datetime.allWeekDays[self.$t('default.firstDayOfWeek')].type : 0 firstDayOfWeek: self.$constants.datetime.allWeekDays[self.$t('default.firstDayOfWeek')] ? self.$constants.datetime.allWeekDays[self.$t('default.firstDayOfWeek')].type : 0
}, },
@@ -221,6 +222,7 @@ export default {
const isCurrencyDefault = this.user.defaultCurrency === this.$store.state.defaultSetting.currency; const isCurrencyDefault = this.user.defaultCurrency === this.$store.state.defaultSetting.currency;
const isFirstWeekDayDefault = this.user.firstDayOfWeek === (this.$constants.datetime.allWeekDays[this.$t('default.firstDayOfWeek')] ? this.$constants.datetime.allWeekDays[this.$t('default.firstDayOfWeek')].type : 0); const isFirstWeekDayDefault = this.user.firstDayOfWeek === (this.$constants.datetime.allWeekDays[this.$t('default.firstDayOfWeek')] ? this.$constants.datetime.allWeekDays[this.$t('default.firstDayOfWeek')].type : 0);
this.user.language = value;
this.$locale.setLanguage(value); this.$locale.setLanguage(value);
if (isCurrencyDefault) { if (isCurrencyDefault) {
@@ -324,7 +326,7 @@ export default {
self.$store.dispatch('register', { self.$store.dispatch('register', {
user: self.user user: self.user
}).then(() => { }).then(response => {
if (!self.$user.isUserLogined()) { if (!self.$user.isUserLogined()) {
self.submitting = false; self.submitting = false;
self.$hideLoading(); self.$hideLoading();
@@ -339,6 +341,10 @@ export default {
return; return;
} }
if (response.user && response.user.language) {
self.$locale.setLanguage(response.user.language);
}
if (self.$settings.isAutoUpdateExchangeRatesData()) { if (self.$settings.isAutoUpdateExchangeRatesData()) {
self.$store.dispatch('getLatestExchangeRates', { silent: true, force: false }); self.$store.dispatch('getLatestExchangeRates', { silent: true, force: false });
} }
+22 -12
View File
@@ -113,7 +113,11 @@ export default {
self.$hideLoading(); self.$hideLoading();
self.$user.unlockTokenByWebAuthn(id, userName, userSecret); self.$user.unlockTokenByWebAuthn(id, userName, userSecret);
self.$store.dispatch('refreshTokenAndRevokeOldToken'); self.$store.dispatch('refreshTokenAndRevokeOldToken').then(response => {
if (response.user && response.user.language) {
self.$locale.setLanguage(response.user.language);
}
});
if (self.$settings.isAutoUpdateExchangeRatesData()) { if (self.$settings.isAutoUpdateExchangeRatesData()) {
self.$store.dispatch('getLatestExchangeRates', { silent: true, force: false }); self.$store.dispatch('getLatestExchangeRates', { silent: true, force: false });
@@ -136,34 +140,40 @@ export default {
}); });
}, },
unlockByPin(pinCode) { unlockByPin(pinCode) {
if (!this.isPinCodeValid(pinCode)) { const self = this;
if (!self.isPinCodeValid(pinCode)) {
return; return;
} }
if (this.$ui.isModalShowing()) { if (self.$ui.isModalShowing()) {
return; return;
} }
const router = this.f7router; const router = self.f7router;
const user = this.$store.state.currentUserInfo; const user = self.$store.state.currentUserInfo;
if (!user || !user.username) { if (!user || !user.username) {
this.$alert('An error has occurred'); self.$alert('An error has occurred');
return; return;
} }
try { try {
this.$user.unlockTokenByPinCode(user.username, pinCode); self.$user.unlockTokenByPinCode(user.username, pinCode);
this.$store.dispatch('refreshTokenAndRevokeOldToken'); self.$store.dispatch('refreshTokenAndRevokeOldToken').then(response => {
if (response.user && response.user.language) {
self.$locale.setLanguage(response.user.language);
}
});
if (this.$settings.isAutoUpdateExchangeRatesData()) { if (self.$settings.isAutoUpdateExchangeRatesData()) {
this.$store.dispatch('getLatestExchangeRates', { silent: true, force: false }); self.$store.dispatch('getLatestExchangeRates', { silent: true, force: false });
} }
router.refreshPage(); router.refreshPage();
} catch (ex) { } catch (ex) {
this.$logger.error('failed to unlock by pin code', ex); self.$logger.error('failed to unlock by pin code', ex);
this.$toast('PIN code is wrong'); self.$toast('PIN code is wrong');
} }
}, },
relogin() { relogin() {
@@ -217,10 +217,10 @@
</template> </template>
<template #footer> <template #footer>
<div v-if="dateRange.type === allDateRanges.Custom.type && query.dateType === allDateRanges.Custom.type && query.startTime && query.endTime"> <div v-if="dateRange.type === allDateRanges.Custom.type && query.dateType === allDateRanges.Custom.type && query.startTime && query.endTime">
<span>{{ $utilities.formatUnixTime(query.startTime, $t('format.datetime.long-without-second')) }}</span> <span>{{ $utilities.formatUnixTime(query.startTime, $locale.getLongDateTimeFormat()) }}</span>
<span>&nbsp;-&nbsp;</span> <span>&nbsp;-&nbsp;</span>
<br/> <br/>
<span>{{ $utilities.formatUnixTime(query.endTime, $t('format.datetime.long-without-second')) }}</span> <span>{{ $utilities.formatUnixTime(query.endTime, $locale.getLongDateTimeFormat()) }}</span>
</div> </div>
</template> </template>
</f7-list-item> </f7-list-item>
@@ -618,15 +618,15 @@ export default {
} }
if (this.$utilities.isDateRangeMatchFullYears(query.startTime, query.endTime)) { if (this.$utilities.isDateRangeMatchFullYears(query.startTime, query.endTime)) {
const displayStartTime = this.$utilities.formatUnixTime(query.startTime, this.$t('format.year.short')); const displayStartTime = this.$utilities.formatUnixTime(query.startTime, this.$locale.getShortYearFormat());
const displayEndTime = this.$utilities.formatUnixTime(query.endTime, this.$t('format.year.short')); const displayEndTime = this.$utilities.formatUnixTime(query.endTime, this.$locale.getShortYearFormat());
return displayStartTime !== displayEndTime ? `${displayStartTime} ~ ${displayEndTime}` : displayStartTime; return displayStartTime !== displayEndTime ? `${displayStartTime} ~ ${displayEndTime}` : displayStartTime;
} }
if (this.$utilities.isDateRangeMatchFullMonths(query.startTime, query.endTime)) { if (this.$utilities.isDateRangeMatchFullMonths(query.startTime, query.endTime)) {
const displayStartTime = this.$utilities.formatUnixTime(query.startTime, this.$t('format.yearMonth.short')); const displayStartTime = this.$utilities.formatUnixTime(query.startTime, this.$locale.getShortYearMonthFormat());
const displayEndTime = this.$utilities.formatUnixTime(query.endTime, this.$t('format.yearMonth.short')); const displayEndTime = this.$utilities.formatUnixTime(query.endTime, this.$locale.getShortYearMonthFormat());
return displayStartTime !== displayEndTime ? `${displayStartTime} ~ ${displayEndTime}` : displayStartTime; return displayStartTime !== displayEndTime ? `${displayStartTime} ~ ${displayEndTime}` : displayStartTime;
} }
@@ -634,13 +634,13 @@ export default {
const startTimeYear = this.$utilities.getYear(this.$utilities.parseDateFromUnixTime(query.startTime)); const startTimeYear = this.$utilities.getYear(this.$utilities.parseDateFromUnixTime(query.startTime));
const endTimeYear = this.$utilities.getYear(this.$utilities.parseDateFromUnixTime(query.endTime)); const endTimeYear = this.$utilities.getYear(this.$utilities.parseDateFromUnixTime(query.endTime));
const displayStartTime = this.$utilities.formatUnixTime(query.startTime, this.$t('format.date.short')); const displayStartTime = this.$utilities.formatUnixTime(query.startTime, this.$locale.getShortDateFormat());
const displayEndTime = this.$utilities.formatUnixTime(query.endTime, this.$t('format.date.short')); const displayEndTime = this.$utilities.formatUnixTime(query.endTime, this.$locale.getShortDateFormat());
if (displayStartTime === displayEndTime) { if (displayStartTime === displayEndTime) {
return displayStartTime; return displayStartTime;
} else if (startTimeYear === endTimeYear) { } else if (startTimeYear === endTimeYear) {
const displayShortEndTime = this.$utilities.formatUnixTime(query.endTime, this.$t('format.monthDay.short')); const displayShortEndTime = this.$utilities.formatUnixTime(query.endTime, this.$locale.getShortMonthDayFormat());
return `${displayStartTime} ~ ${displayShortEndTime}`; return `${displayStartTime} ~ ${displayShortEndTime}`;
} }
+1 -1
View File
@@ -213,7 +213,7 @@
link="#" no-chevron link="#" no-chevron
:class="{ 'readonly': mode === 'view' }" :class="{ 'readonly': mode === 'view' }"
:header="$t('Transaction Time')" :header="$t('Transaction Time')"
:title="$utilities.formatUnixTime($utilities.getActualUnixTimeForStore(transaction.time, $utilities.getTimezoneOffsetMinutes(), $utilities.getBrowserTimezoneOffsetMinutes()), this.$t('format.datetime.long'))" :title="$utilities.formatUnixTime($utilities.getActualUnixTimeForStore(transaction.time, $utilities.getTimezoneOffsetMinutes(), $utilities.getBrowserTimezoneOffsetMinutes()), $locale.getLongDateTimeFormat())"
@click="showTransactionDateTimeSheet = true" @click="showTransactionDateTimeSheet = true"
> >
<date-time-selection-sheet v-model:show="showTransactionDateTimeSheet" <date-time-selection-sheet v-model:show="showTransactionDateTimeSheet"
+9 -4
View File
@@ -123,7 +123,7 @@
<f7-list-item> <f7-list-item>
<template #title> <template #title>
<small> <small>
<span>{{ $utilities.formatTime(transactionMonthList.yearMonth, $t('format.yearMonth.long')) }}</span> <span>{{ $utilities.formatTime(transactionMonthList.yearMonth, $locale.getLongYearMonthFormat()) }}</span>
</small> </small>
<small class="transaction-amount-statistics" v-if="showTotalAmountInTransactionListPage && transactionMonthList.totalAmount"> <small class="transaction-amount-statistics" v-if="showTotalAmountInTransactionListPage && transactionMonthList.totalAmount">
<span class="text-color-red"> <span class="text-color-red">
@@ -202,7 +202,7 @@
</div> </div>
<div class="item-footer"> <div class="item-footer">
<div class="transaction-footer"> <div class="transaction-footer">
<span>{{ $utilities.formatUnixTime(transaction.time, $t('format.hourMinute.long'), transaction.utcOffset, currentTimezoneOffsetMinutes) }}</span> <span>{{ $utilities.formatUnixTime(transaction.time, $locale.getShortTimeFormat(), transaction.utcOffset, currentTimezoneOffsetMinutes) }}</span>
<span v-if="transaction.utcOffset !== currentTimezoneOffsetMinutes">{{ `(UTC${$utilities.getUtcOffsetByUtcOffsetMinutes(transaction.utcOffset)})` }}</span> <span v-if="transaction.utcOffset !== currentTimezoneOffsetMinutes">{{ `(UTC${$utilities.getUtcOffsetByUtcOffsetMinutes(transaction.utcOffset)})` }}</span>
<span v-if="transaction.sourceAccount">·</span> <span v-if="transaction.sourceAccount">·</span>
<span v-if="transaction.sourceAccount">{{ transaction.sourceAccount.name }}</span> <span v-if="transaction.sourceAccount">{{ transaction.sourceAccount.name }}</span>
@@ -252,10 +252,10 @@
</template> </template>
<template #footer> <template #footer>
<div v-if="dateRange.type === $constants.datetime.allDateRanges.Custom.type && query.dateType === $constants.datetime.allDateRanges.Custom.type && query.minTime && query.maxTime"> <div v-if="dateRange.type === $constants.datetime.allDateRanges.Custom.type && query.dateType === $constants.datetime.allDateRanges.Custom.type && query.minTime && query.maxTime">
<span>{{ $utilities.formatUnixTime(query.minTime, $t('format.datetime.long-without-second')) }}</span> <span>{{ $utilities.formatUnixTime(query.minTime, $locale.getLongDateTimeFormat()) }}</span>
<span>&nbsp;-&nbsp;</span> <span>&nbsp;-&nbsp;</span>
<br/> <br/>
<span>{{ $utilities.formatUnixTime(query.maxTime, $t('format.datetime.long-without-second')) }}</span> <span>{{ $utilities.formatUnixTime(query.maxTime, $locale.getLongDateTimeFormat()) }}</span>
</div> </div>
</template> </template>
</f7-list-item> </f7-list-item>
@@ -840,6 +840,11 @@ export default {
</script> </script>
<style> <style>
.list.transaction-amount-list .transaction-amount-statistics {
overflow: hidden;
text-overflow: ellipsis;
}
.list.transaction-amount-list .transaction-amount-statistics > span { .list.transaction-amount-list .transaction-amount-statistics > span {
margin-left: 8px; margin-left: 8px;
font-weight: normal; font-weight: normal;
+1 -1
View File
@@ -72,7 +72,7 @@ export default {
deviceType: this.$t(token.isCurrent ? 'Current' : 'Other Device'), deviceType: this.$t(token.isCurrent ? 'Current' : 'Other Device'),
deviceInfo: this.$utilities.parseDeviceInfo(token.userAgent), deviceInfo: this.$utilities.parseDeviceInfo(token.userAgent),
icon: this.getTokenIcon(token), icon: this.getTokenIcon(token),
createdAt: this.$utilities.formatUnixTime(token.createdAt, this.$t('format.datetime.long')) createdAt: this.$utilities.formatUnixTime(token.createdAt, this.$locale.getLongDateTimeFormat())
}); });
} }
+218 -60
View File
@@ -16,12 +16,20 @@
</f7-list> </f7-list>
<f7-list strong inset dividers class="margin-vertical skeleton-text" v-if="loading"> <f7-list strong inset dividers class="margin-vertical skeleton-text" v-if="loading">
<f7-list-item class="list-item-with-header-and-title list-item-no-item-after" header="Default Currency" title="Currency" link="#"></f7-list-item>
<f7-list-item class="list-item-with-header-and-title list-item-no-item-after" header="Default Account" title="Not Specified"></f7-list-item> <f7-list-item class="list-item-with-header-and-title list-item-no-item-after" header="Default Account" title="Not Specified"></f7-list-item>
<f7-list-item class="list-item-with-header-and-title list-item-no-item-after" header="First Day of Week" title="Week Day" link="#"></f7-list-item>
<f7-list-item class="list-item-with-header-and-title list-item-no-item-after" header="Editable Transaction Scope" title="All" link="#"></f7-list-item> <f7-list-item class="list-item-with-header-and-title list-item-no-item-after" header="Editable Transaction Scope" title="All" link="#"></f7-list-item>
</f7-list> </f7-list>
<f7-list strong inset dividers class="margin-vertical skeleton-text" v-if="loading">
<f7-list-item class="list-item-with-header-and-title list-item-no-item-after" header="Default Language" title="Language" link="#"></f7-list-item>
<f7-list-item class="list-item-with-header-and-title list-item-no-item-after" header="Default Currency" title="Currency" link="#"></f7-list-item>
<f7-list-item class="list-item-with-header-and-title list-item-no-item-after" header="First Day of Week" title="Week Day" link="#"></f7-list-item>
<f7-list-item class="list-item-with-header-and-title list-item-no-item-after" header="Long Date Format" title="YYYY-MM-DD" link="#"></f7-list-item>
<f7-list-item class="list-item-with-header-and-title list-item-no-item-after" header="Short Date Format" title="YYYY-MM-DD" link="#"></f7-list-item>
<f7-list-item class="list-item-with-header-and-title list-item-no-item-after" header="Long Time Format" title="HH:mm:ss" link="#"></f7-list-item>
<f7-list-item class="list-item-with-header-and-title list-item-no-item-after" header="Short Time Format" title="HH:mm" link="#"></f7-list-item>
</f7-list>
<f7-list form strong inset dividers class="margin-vertical" v-if="!loading"> <f7-list form strong inset dividers class="margin-vertical" v-if="!loading">
<f7-list-input <f7-list-input
type="password" type="password"
@@ -63,24 +71,6 @@
</f7-list> </f7-list>
<f7-list form strong inset dividers class="margin-vertical" v-if="!loading"> <f7-list form strong inset dividers class="margin-vertical" v-if="!loading">
<f7-list-item
class="list-item-with-header-and-title list-item-no-item-after"
:header="$t('Default Currency')"
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Currency Name'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), pageTitle: $t('Default Currency'), popupCloseLinkText: $t('Done') }"
>
<template #title>
<f7-block class="no-padding no-margin">
<span>{{ $t(`currency.${newProfile.defaultCurrency}`) }}&nbsp;</span>
<small class="smaller">{{ newProfile.defaultCurrency }}</small>
</f7-block>
</template>
<select autocomplete="transaction-currency" v-model="newProfile.defaultCurrency">
<option :value="currency.code"
:key="currency.code"
v-for="currency in allCurrencies">{{ currency.displayName }}</option>
</select>
</f7-list-item>
<f7-list-item <f7-list-item
class="list-item-with-header-and-title" class="list-item-with-header-and-title"
link="#" no-chevron link="#" no-chevron
@@ -103,19 +93,6 @@
</two-column-list-item-selection-sheet> </two-column-list-item-selection-sheet>
</f7-list-item> </f7-list-item>
<f7-list-item
class="list-item-with-header-and-title list-item-no-item-after"
:header="$t('First Day of Week')"
:title="getDayOfWeekName(newProfile.firstDayOfWeek)"
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Date'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), pageTitle: $t('First Day of Week'), popupCloseLinkText: $t('Done') }"
>
<select v-model="newProfile.firstDayOfWeek">
<option :value="weekDay.type"
:key="weekDay.type"
v-for="weekDay in allWeekDays">{{ $t(`datetime.${weekDay.name}.long`) }}</option>
</select>
</f7-list-item>
<f7-list-item <f7-list-item
class="list-item-with-header-and-title list-item-no-item-after" class="list-item-with-header-and-title list-item-no-item-after"
:header="$t('Editable Transaction Scope')" :header="$t('Editable Transaction Scope')"
@@ -132,6 +109,105 @@
<f7-list-item class="ebk-list-item-error-info" v-if="extendInputIsInvalid" :footer="$t(extendInputInvalidProblemMessage)"></f7-list-item> <f7-list-item class="ebk-list-item-error-info" v-if="extendInputIsInvalid" :footer="$t(extendInputInvalidProblemMessage)"></f7-list-item>
</f7-list> </f7-list>
<f7-list form strong inset dividers class="margin-vertical" v-if="!loading">
<f7-list-item
class="list-item-with-header-and-title list-item-no-item-after"
:header="$t('Language')"
:title="currentLanguageName"
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Language'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), pageTitle: $t('Language'), popupCloseLinkText: $t('Done') }">
<select v-model="newProfile.language">
<option :value="language.code"
:key="language.code"
v-for="language in allLanguages">{{ language.displayName }}</option>
</select>
</f7-list-item>
<f7-list-item
class="list-item-with-header-and-title list-item-no-item-after"
:header="$t('Default Currency')"
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Currency Name'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), pageTitle: $t('Default Currency'), popupCloseLinkText: $t('Done') }"
>
<template #title>
<f7-block class="no-padding no-margin">
<span>{{ $t(`currency.${newProfile.defaultCurrency}`) }}&nbsp;</span>
<small class="smaller">{{ newProfile.defaultCurrency }}</small>
</f7-block>
</template>
<select autocomplete="transaction-currency" v-model="newProfile.defaultCurrency">
<option :value="currency.code"
:key="currency.code"
v-for="currency in allCurrencies">{{ currency.displayName }}</option>
</select>
</f7-list-item>
<f7-list-item
class="list-item-with-header-and-title list-item-no-item-after"
:header="$t('First Day of Week')"
:title="currentDayOfWeekName"
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Date'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), pageTitle: $t('First Day of Week'), popupCloseLinkText: $t('Done') }"
>
<select v-model="newProfile.firstDayOfWeek">
<option :value="weekDay.type"
:key="weekDay.type"
v-for="weekDay in allWeekDays">{{ $t(`datetime.${weekDay.name}.long`) }}</option>
</select>
</f7-list-item>
<f7-list-item
class="list-item-with-header-and-title list-item-no-item-after"
:header="$t('Long Date Format')"
:title="$utilities.getNameByKeyValue(allLongDateFormats, newProfile.longDateFormat, 'type', 'displayName')"
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Long Date Format'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), pageTitle: $t('Long Date Format'), popupCloseLinkText: $t('Done') }"
>
<select v-model="newProfile.longDateFormat">
<option :value="format.type"
:key="format.type"
v-for="format in allLongDateFormats">{{ format.displayName }}</option>
</select>
</f7-list-item>
<f7-list-item
class="list-item-with-header-and-title list-item-no-item-after"
:header="$t('Short Date Format')"
:title="$utilities.getNameByKeyValue(allShortDateFormats, newProfile.shortDateFormat, 'type', 'displayName')"
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Short Date Format'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), pageTitle: $t('Short Date Format'), popupCloseLinkText: $t('Done') }"
>
<select v-model="newProfile.shortDateFormat">
<option :value="format.type"
:key="format.type"
v-for="format in allShortDateFormats">{{ format.displayName }}</option>
</select>
</f7-list-item>
<f7-list-item
class="list-item-with-header-and-title list-item-no-item-after"
:header="$t('Long Time Format')"
:title="$utilities.getNameByKeyValue(allLongTimeFormats, newProfile.longTimeFormat, 'type', 'displayName')"
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Long Time Format'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), pageTitle: $t('Long Time Format'), popupCloseLinkText: $t('Done') }"
>
<select v-model="newProfile.longTimeFormat">
<option :value="format.type"
:key="format.type"
v-for="format in allLongTimeFormats">{{ format.displayName }}</option>
</select>
</f7-list-item>
<f7-list-item
class="list-item-with-header-and-title list-item-no-item-after"
:header="$t('Short Time Format')"
:title="$utilities.getNameByKeyValue(allShortTimeFormats, newProfile.shortTimeFormat, 'type', 'displayName')"
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Long Time Format'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), pageTitle: $t('Short Time Format'), popupCloseLinkText: $t('Done') }"
>
<select v-model="newProfile.shortTimeFormat">
<option :value="format.type"
:key="format.type"
v-for="format in allShortTimeFormats">{{ format.displayName }}</option>
</select>
</f7-list-item>
<f7-list-item class="ebk-list-item-error-info" v-if="langAndRegionInputIsInvalid" :footer="$t(langAndRegionInputInvalidProblemMessage)"></f7-list-item>
</f7-list>
<password-input-sheet :title="$t('Modify Password')" <password-input-sheet :title="$t('Modify Password')"
:hint="$t('Please enter your current password when modifying your password')" :hint="$t('Please enter your current password when modifying your password')"
:confirm-disabled="saving" :confirm-disabled="saving"
@@ -155,18 +231,28 @@ export default {
confirmPassword: '', confirmPassword: '',
email: '', email: '',
nickname: '', nickname: '',
defaultCurrency: '',
defaultAccountId: '', defaultAccountId: '',
transactionEditScope: 1,
language: '',
defaultCurrency: '',
firstDayOfWeek: 0, firstDayOfWeek: 0,
transactionEditScope: 1 longDateFormat: 0,
shortDateFormat: 0,
longTimeFormat: 0,
shortTimeFormat: 0
}, },
oldProfile: { oldProfile: {
email: '', email: '',
nickname: '', nickname: '',
defaultCurrency: '',
defaultAccountId: '', defaultAccountId: '',
transactionEditScope: 1,
language: '',
defaultCurrency: '',
firstDayOfWeek: 0, firstDayOfWeek: 0,
transactionEditScope: 1 longDateFormat: 0,
shortDateFormat: 0,
longTimeFormat: 0,
shortTimeFormat: 0
}, },
currentPassword: '', currentPassword: '',
loading: true, loading: true,
@@ -177,6 +263,30 @@ export default {
}; };
}, },
computed: { computed: {
allLanguages() {
const ret = [];
const allLanguageInfo = this.$locale.getAllLanguageInfos();
ret.push({
code: '',
displayName: this.$t('System Default')
});
for (let code in allLanguageInfo) {
if (!Object.prototype.hasOwnProperty.call(allLanguageInfo, code)) {
continue;
}
const languageInfo = allLanguageInfo[code];
ret.push({
code: code,
displayName: languageInfo.displayName
});
}
return ret;
},
allCurrencies() { allCurrencies() {
return this.$locale.getAllCurrencies(); return this.$locale.getAllCurrencies();
}, },
@@ -192,6 +302,18 @@ export default {
allWeekDays() { allWeekDays() {
return this.$constants.datetime.allWeekDays; return this.$constants.datetime.allWeekDays;
}, },
allLongDateFormats() {
return this.$locale.getAllLongDateFormats();
},
allShortDateFormats() {
return this.$locale.getAllShortDateFormats();
},
allLongTimeFormats() {
return this.$locale.getAllLongTimeFormats();
},
allShortTimeFormats() {
return this.$locale.getAllShortTimeFormats();
},
allTransactionEditScopeTypes() { allTransactionEditScopeTypes() {
return [{ return [{
value: 0, value: 0,
@@ -216,6 +338,20 @@ export default {
name: 'This year or later' name: 'This year or later'
}]; }];
}, },
currentLanguageName() {
for (let i = 0; i < this.allLanguages.length; i++) {
if (this.allLanguages[i].code === this.newProfile.language) {
return this.allLanguages[i].displayName;
}
}
return this.$t('Unknown');
},
currentDayOfWeekName() {
const weekName = this.$utilities.getNameByKeyValue(this.$constants.datetime.allWeekDays, this.newProfile.firstDayOfWeek, 'type', 'name');
const i18nWeekNameKey = `datetime.${weekName}.long`;
return this.$t(i18nWeekNameKey);
},
inputIsNotChanged() { inputIsNotChanged() {
return !!this.inputIsNotChangedProblemMessage; return !!this.inputIsNotChangedProblemMessage;
}, },
@@ -225,16 +361,24 @@ export default {
extendInputIsInvalid() { extendInputIsInvalid() {
return !!this.extendInputInvalidProblemMessage; return !!this.extendInputInvalidProblemMessage;
}, },
langAndRegionInputIsInvalid() {
return !!this.langAndRegionInputInvalidProblemMessage;
},
inputIsNotChangedProblemMessage() { inputIsNotChangedProblemMessage() {
if (!this.newProfile.password && !this.newProfile.confirmPassword && !this.newProfile.email && !this.newProfile.nickname) { if (!this.newProfile.password && !this.newProfile.confirmPassword && !this.newProfile.email && !this.newProfile.nickname) {
return 'Nothing has been modified'; return 'Nothing has been modified';
} else if (!this.newProfile.password && !this.newProfile.confirmPassword && } else if (!this.newProfile.password && !this.newProfile.confirmPassword &&
this.newProfile.email === this.oldProfile.email && this.newProfile.email === this.oldProfile.email &&
this.newProfile.nickname === this.oldProfile.nickname && this.newProfile.nickname === this.oldProfile.nickname &&
this.newProfile.defaultCurrency === this.oldProfile.defaultCurrency &&
this.newProfile.defaultAccountId === this.oldProfile.defaultAccountId && this.newProfile.defaultAccountId === this.oldProfile.defaultAccountId &&
this.newProfile.transactionEditScope === this.oldProfile.transactionEditScope &&
this.newProfile.language === this.oldProfile.language &&
this.newProfile.defaultCurrency === this.oldProfile.defaultCurrency &&
this.newProfile.firstDayOfWeek === this.oldProfile.firstDayOfWeek && this.newProfile.firstDayOfWeek === this.oldProfile.firstDayOfWeek &&
this.newProfile.transactionEditScope === this.oldProfile.transactionEditScope) { this.newProfile.longDateFormat === this.oldProfile.longDateFormat &&
this.newProfile.shortDateFormat === this.oldProfile.shortDateFormat &&
this.newProfile.longTimeFormat === this.oldProfile.longTimeFormat &&
this.newProfile.shortTimeFormat === this.oldProfile.shortTimeFormat) {
return 'Nothing has been modified'; return 'Nothing has been modified';
} else if (!this.newProfile.password && this.newProfile.confirmPassword) { } else if (!this.newProfile.password && this.newProfile.confirmPassword) {
return 'Password cannot be empty'; return 'Password cannot be empty';
@@ -258,6 +402,9 @@ export default {
} }
}, },
extendInputInvalidProblemMessage() { extendInputInvalidProblemMessage() {
return null;
},
langAndRegionInputInvalidProblemMessage() {
if (!this.newProfile.defaultCurrency) { if (!this.newProfile.defaultCurrency) {
return 'Default currency cannot be empty'; return 'Default currency cannot be empty';
} else { } else {
@@ -277,21 +424,7 @@ export default {
Promise.all(promises).then(responses => { Promise.all(promises).then(responses => {
const profile = responses[1]; const profile = responses[1];
self.setCurrentUserProfile(profile);
self.oldProfile.email = profile.email;
self.oldProfile.nickname = profile.nickname;
self.oldProfile.defaultCurrency = profile.defaultCurrency;
self.oldProfile.defaultAccountId = profile.defaultAccountId;
self.oldProfile.firstDayOfWeek = profile.firstDayOfWeek;
self.oldProfile.transactionEditScope = profile.transactionEditScope;
self.newProfile.email = self.oldProfile.email
self.newProfile.nickname = self.oldProfile.nickname;
self.newProfile.defaultCurrency = self.oldProfile.defaultCurrency;
self.newProfile.defaultAccountId = self.oldProfile.defaultAccountId;
self.newProfile.firstDayOfWeek = self.oldProfile.firstDayOfWeek;
self.newProfile.transactionEditScope = self.oldProfile.transactionEditScope;
self.loading = false; self.loading = false;
}).catch(error => { }).catch(error => {
if (error.processed) { if (error.processed) {
@@ -312,7 +445,7 @@ export default {
self.showInputPasswordSheet = false; self.showInputPasswordSheet = false;
let problemMessage = self.inputIsNotChangedProblemMessage || self.inputInvalidProblemMessage || self.extendInputInvalidProblemMessage; let problemMessage = self.inputIsNotChangedProblemMessage || self.inputInvalidProblemMessage || self.extendInputInvalidProblemMessage || self.langAndRegionInputInvalidProblemMessage;
if (problemMessage) { if (problemMessage) {
self.$alert(problemMessage); self.$alert(problemMessage);
@@ -330,11 +463,16 @@ export default {
self.$store.dispatch('updateUserProfile', { self.$store.dispatch('updateUserProfile', {
profile: self.newProfile, profile: self.newProfile,
currentPassword: self.currentPassword currentPassword: self.currentPassword
}).then(() => { }).then(response => {
self.saving = false; self.saving = false;
self.$hideLoading(); self.$hideLoading();
self.currentPassword = ''; self.currentPassword = '';
if (response.user) {
self.setCurrentUserProfile(response.user);
self.$locale.setLanguage(response.user.language);
}
self.$toast('Your profile has been successfully updated'); self.$toast('Your profile has been successfully updated');
router.back(); router.back();
}).catch(error => { }).catch(error => {
@@ -347,10 +485,30 @@ export default {
} }
}); });
}, },
getDayOfWeekName(dayOfWeek) { setCurrentUserProfile(profile) {
const weekName = this.$utilities.getNameByKeyValue(this.$constants.datetime.allWeekDays, dayOfWeek, 'type', 'name'); this.oldProfile.email = profile.email;
const i18nWeekNameKey = `datetime.${weekName}.long`; this.oldProfile.nickname = profile.nickname;
return this.$t(i18nWeekNameKey); this.oldProfile.defaultAccountId = profile.defaultAccountId;
this.oldProfile.transactionEditScope = profile.transactionEditScope;
this.oldProfile.language = profile.language;
this.oldProfile.defaultCurrency = profile.defaultCurrency;
this.oldProfile.firstDayOfWeek = profile.firstDayOfWeek;
this.oldProfile.longDateFormat = profile.longDateFormat;
this.oldProfile.shortDateFormat = profile.shortDateFormat;
this.oldProfile.longTimeFormat = profile.longTimeFormat;
this.oldProfile.shortTimeFormat = profile.shortTimeFormat;
this.newProfile.email = this.oldProfile.email
this.newProfile.nickname = this.oldProfile.nickname;
this.newProfile.defaultAccountId = this.oldProfile.defaultAccountId;
this.newProfile.transactionEditScope = this.oldProfile.transactionEditScope;
this.newProfile.language = this.oldProfile.language;
this.newProfile.defaultCurrency = this.oldProfile.defaultCurrency;
this.newProfile.firstDayOfWeek = this.oldProfile.firstDayOfWeek;
this.newProfile.longDateFormat = this.oldProfile.longDateFormat;
this.newProfile.shortDateFormat = this.oldProfile.shortDateFormat;
this.newProfile.longTimeFormat = this.oldProfile.longTimeFormat;
this.newProfile.shortTimeFormat = this.oldProfile.shortTimeFormat;
} }
} }
}; };