diff --git a/pkg/api/accounts.go b/pkg/api/accounts.go index fb0242e8..b14b7cf4 100644 --- a/pkg/api/accounts.go +++ b/pkg/api/accounts.go @@ -174,6 +174,11 @@ func (a *AccountsApi) AccountCreateHandler(c *core.WebContext) (any, *errs.Error log.Warnf(c, "[accounts.AccountCreateHandler] account balance time is not set") return nil, errs.ErrAccountBalanceTimeNotSet } + + if accountCreateReq.Category != models.ACCOUNT_CATEGORY_CREDIT_CARD && accountCreateReq.CreditCardStatementDate != 0 { + log.Warnf(c, "[accounts.AccountCreateHandler] cannot set statement date with category \"%d\"", accountCreateReq.Category) + return nil, errs.ErrCannotSetStatementDateForNonCreditCard + } } else if accountCreateReq.Type == models.ACCOUNT_TYPE_MULTI_SUB_ACCOUNTS { if len(accountCreateReq.SubAccounts) < 1 { log.Warnf(c, "[accounts.AccountCreateHandler] account does not have any sub-accounts") @@ -212,6 +217,11 @@ func (a *AccountsApi) AccountCreateHandler(c *core.WebContext) (any, *errs.Error log.Warnf(c, "[accounts.AccountCreateHandler] sub-account#%d balance time is not set", i) return nil, errs.ErrAccountBalanceTimeNotSet } + + if subAccount.Category != models.ACCOUNT_CATEGORY_CREDIT_CARD && subAccount.CreditCardStatementDate != 0 { + log.Warnf(c, "[accounts.AccountCreateHandler] sub-account#%d cannot set statement date with category \"%d\"", i, subAccount.Category) + return nil, errs.ErrCannotSetStatementDateForNonCreditCard + } } } else { log.Warnf(c, "[accounts.AccountCreateHandler] account type invalid, type is %d", accountCreateReq.Type) @@ -312,8 +322,9 @@ func (a *AccountsApi) AccountModifyHandler(c *core.WebContext) (any, *errs.Error } accountMap := a.accounts.GetAccountMapByList(accountAndSubAccounts) + mainAccount, exists := accountMap[accountModifyReq.Id] - if _, exists := accountMap[accountModifyReq.Id]; !exists { + if !exists { return nil, errs.ErrAccountNotFound } @@ -321,10 +332,26 @@ func (a *AccountsApi) AccountModifyHandler(c *core.WebContext) (any, *errs.Error return nil, errs.ErrCannotAddOrDeleteSubAccountsWhenModify } + if mainAccount.Type == models.ACCOUNT_TYPE_SINGLE_ACCOUNT { + if accountModifyReq.Category != models.ACCOUNT_CATEGORY_CREDIT_CARD && accountModifyReq.CreditCardStatementDate != 0 { + log.Warnf(c, "[accounts.AccountModifyHandler] cannot set statement date with category \"%d\"", accountModifyReq.Category) + return nil, errs.ErrCannotSetStatementDateForNonCreditCard + } + } else if mainAccount.Type == models.ACCOUNT_TYPE_MULTI_SUB_ACCOUNTS { + for i := 0; i < len(accountModifyReq.SubAccounts); i++ { + subAccount := accountModifyReq.SubAccounts[i] + + if subAccount.Category != models.ACCOUNT_CATEGORY_CREDIT_CARD && subAccount.CreditCardStatementDate != 0 { + log.Warnf(c, "[accounts.AccountModifyHandler] sub-account#%d cannot set statement date with category \"%d\"", i, subAccount.Category) + return nil, errs.ErrCannotSetStatementDateForNonCreditCard + } + } + } + anythingUpdate := false var toUpdateAccounts []*models.Account - toUpdateAccount := a.getToUpdateAccount(uid, &accountModifyReq, accountMap[accountModifyReq.Id]) + toUpdateAccount := a.getToUpdateAccount(uid, &accountModifyReq, mainAccount) if toUpdateAccount != nil { anythingUpdate = true @@ -479,6 +506,12 @@ func (a *AccountsApi) AccountDeleteHandler(c *core.WebContext) (any, *errs.Error } func (a *AccountsApi) createNewAccountModel(uid int64, accountCreateReq *models.AccountCreateRequest, order int32) *models.Account { + accountExtend := &models.AccountExtend{} + + if accountCreateReq.Category == models.ACCOUNT_CATEGORY_CREDIT_CARD { + accountExtend.CreditCardStatementDate = &accountCreateReq.CreditCardStatementDate + } + return &models.Account{ Uid: uid, Name: accountCreateReq.Name, @@ -490,6 +523,7 @@ func (a *AccountsApi) createNewAccountModel(uid int64, accountCreateReq *models. Currency: accountCreateReq.Currency, Balance: accountCreateReq.Balance, Comment: accountCreateReq.Comment, + Extend: accountExtend, } } @@ -510,6 +544,12 @@ func (a *AccountsApi) createSubAccountModels(uid int64, accountCreateReq *models } func (a *AccountsApi) getToUpdateAccount(uid int64, accountModifyReq *models.AccountModifyRequest, oldAccount *models.Account) *models.Account { + newAccountExtend := &models.AccountExtend{} + + if accountModifyReq.Category == models.ACCOUNT_CATEGORY_CREDIT_CARD { + newAccountExtend.CreditCardStatementDate = &accountModifyReq.CreditCardStatementDate + } + newAccount := &models.Account{ AccountId: oldAccount.AccountId, Uid: uid, @@ -518,6 +558,7 @@ func (a *AccountsApi) getToUpdateAccount(uid int64, accountModifyReq *models.Acc Icon: accountModifyReq.Icon, Color: accountModifyReq.Color, Comment: accountModifyReq.Comment, + Extend: newAccountExtend, Hidden: accountModifyReq.Hidden, } @@ -530,5 +571,16 @@ func (a *AccountsApi) getToUpdateAccount(uid int64, accountModifyReq *models.Acc return newAccount } + if (newAccount.Extend != nil && oldAccount.Extend == nil) || + (newAccount.Extend == nil && oldAccount.Extend != nil) { + return newAccount + } + + oldAccountExtend := oldAccount.Extend + + if newAccountExtend.CreditCardStatementDate != oldAccountExtend.CreditCardStatementDate { + return newAccount + } + return nil } diff --git a/pkg/errs/account.go b/pkg/errs/account.go index 816ebfee..c685504f 100644 --- a/pkg/errs/account.go +++ b/pkg/errs/account.go @@ -20,4 +20,5 @@ var ( ErrAccountInUseCannotBeDeleted = NewNormalError(NormalSubcategoryAccount, 13, http.StatusBadRequest, "account is in use and cannot be deleted") ErrAccountCategoryInvalid = NewNormalError(NormalSubcategoryAccount, 14, http.StatusBadRequest, "account category is invalid") ErrAccountBalanceTimeNotSet = NewNormalError(NormalSubcategoryAccount, 15, http.StatusBadRequest, "account balance time is not set") + ErrCannotSetStatementDateForNonCreditCard = NewNormalError(NormalSubcategoryAccount, 16, http.StatusBadRequest, "cannot set statement date for non credit card account") ) diff --git a/pkg/models/account.go b/pkg/models/account.go index a596bfb9..291a437e 100644 --- a/pkg/models/account.go +++ b/pkg/models/account.go @@ -1,5 +1,7 @@ package models +import "encoding/json" + // LevelOneAccountParentId represents the parent id of level-one account const LevelOneAccountParentId = 0 @@ -52,6 +54,8 @@ const ( ACCOUNT_TYPE_MULTI_SUB_ACCOUNTS AccountType = 2 ) +var defaultCreditCardAccountStatementDate = 0 + // Account represents account data stored in database type Account struct { AccountId int64 `xorm:"PK"` @@ -67,37 +71,45 @@ type Account struct { Currency string `xorm:"VARCHAR(3) NOT NULL"` Balance int64 `xorm:"NOT NULL"` Comment string `xorm:"VARCHAR(255) NOT NULL"` + Extend *AccountExtend `xorm:"BLOB"` Hidden bool `xorm:"NOT NULL"` CreatedUnixTime int64 UpdatedUnixTime int64 DeletedUnixTime int64 } +// AccountExtend represents account extend data stored in database +type AccountExtend struct { + CreditCardStatementDate *int `json:"creditCardStatementDate"` +} + // AccountCreateRequest represents all parameters of account creation request type AccountCreateRequest struct { - Name string `json:"name" binding:"required,notBlank,max=32"` - Category AccountCategory `json:"category" binding:"required"` - Type AccountType `json:"type" binding:"required"` - Icon int64 `json:"icon,string" binding:"required,min=1"` - Color string `json:"color" binding:"required,len=6,validHexRGBColor"` - Currency string `json:"currency" binding:"required,len=3,validCurrency"` - Balance int64 `json:"balance"` - BalanceTime int64 `json:"balanceTime"` - Comment string `json:"comment" binding:"max=255"` - SubAccounts []*AccountCreateRequest `json:"subAccounts" binding:"omitempty"` - ClientSessionId string `json:"clientSessionId"` + Name string `json:"name" binding:"required,notBlank,max=32"` + Category AccountCategory `json:"category" binding:"required"` + Type AccountType `json:"type" binding:"required"` + Icon int64 `json:"icon,string" binding:"required,min=1"` + Color string `json:"color" binding:"required,len=6,validHexRGBColor"` + Currency string `json:"currency" binding:"required,len=3,validCurrency"` + Balance int64 `json:"balance"` + BalanceTime int64 `json:"balanceTime"` + Comment string `json:"comment" binding:"max=255"` + CreditCardStatementDate int `json:"creditCardStatementDate" binding:"min=0,max=28"` + SubAccounts []*AccountCreateRequest `json:"subAccounts" binding:"omitempty"` + ClientSessionId string `json:"clientSessionId"` } // AccountModifyRequest represents all parameters of account modification request type AccountModifyRequest struct { - Id int64 `json:"id,string" binding:"required,min=1"` - Name string `json:"name" binding:"required,notBlank,max=32"` - Category AccountCategory `json:"category" binding:"required"` - Icon int64 `json:"icon,string" binding:"min=1"` - Color string `json:"color" binding:"required,len=6,validHexRGBColor"` - Comment string `json:"comment" binding:"max=255"` - Hidden bool `json:"hidden"` - SubAccounts []*AccountModifyRequest `json:"subAccounts" binding:"omitempty"` + Id int64 `json:"id,string" binding:"required,min=1"` + Name string `json:"name" binding:"required,notBlank,max=32"` + Category AccountCategory `json:"category" binding:"required"` + Icon int64 `json:"icon,string" binding:"min=1"` + Color string `json:"color" binding:"required,len=6,validHexRGBColor"` + Comment string `json:"comment" binding:"max=255"` + CreditCardStatementDate int `json:"creditCardStatementDate" binding:"min=0,max=28"` + Hidden bool `json:"hidden"` + SubAccounts []*AccountModifyRequest `json:"subAccounts" binding:"omitempty"` } // AccountListRequest represents all parameters of account listing request @@ -134,43 +146,65 @@ type AccountDeleteRequest struct { // AccountInfoResponse represents a view-object of account type AccountInfoResponse struct { - Id int64 `json:"id,string"` - Name string `json:"name"` - ParentId int64 `json:"parentId,string"` - Category AccountCategory `json:"category"` - Type AccountType `json:"type"` - Icon int64 `json:"icon,string"` - Color string `json:"color"` - Currency string `json:"currency"` - Balance int64 `json:"balance"` - Comment string `json:"comment"` - DisplayOrder int32 `json:"displayOrder"` - IsAsset bool `json:"isAsset,omitempty"` - IsLiability bool `json:"isLiability,omitempty"` - Hidden bool `json:"hidden"` - SubAccounts AccountInfoResponseSlice `json:"subAccounts,omitempty"` + Id int64 `json:"id,string"` + Name string `json:"name"` + ParentId int64 `json:"parentId,string"` + Category AccountCategory `json:"category"` + Type AccountType `json:"type"` + Icon int64 `json:"icon,string"` + Color string `json:"color"` + Currency string `json:"currency"` + Balance int64 `json:"balance"` + Comment string `json:"comment"` + CreditCardStatementDate *int `json:"creditCardStatementDate,omitempty"` + DisplayOrder int32 `json:"displayOrder"` + IsAsset bool `json:"isAsset,omitempty"` + IsLiability bool `json:"isLiability,omitempty"` + Hidden bool `json:"hidden"` + SubAccounts AccountInfoResponseSlice `json:"subAccounts,omitempty"` } // ToAccountInfoResponse returns a view-object according to database model func (a *Account) ToAccountInfoResponse() *AccountInfoResponse { + var creditCardStatementDate *int + + if a.Category == ACCOUNT_CATEGORY_CREDIT_CARD { + if a.Extend != nil { + creditCardStatementDate = a.Extend.CreditCardStatementDate + } else { + creditCardStatementDate = &defaultCreditCardAccountStatementDate + } + } + return &AccountInfoResponse{ - Id: a.AccountId, - Name: a.Name, - ParentId: a.ParentAccountId, - Category: a.Category, - Type: a.Type, - Icon: a.Icon, - Color: a.Color, - Currency: a.Currency, - Balance: a.Balance, - Comment: a.Comment, - DisplayOrder: a.DisplayOrder, - IsAsset: assetAccountCategory[a.Category], - IsLiability: liabilityAccountCategory[a.Category], - Hidden: a.Hidden, + Id: a.AccountId, + Name: a.Name, + ParentId: a.ParentAccountId, + Category: a.Category, + Type: a.Type, + Icon: a.Icon, + Color: a.Color, + Currency: a.Currency, + Balance: a.Balance, + Comment: a.Comment, + CreditCardStatementDate: creditCardStatementDate, + DisplayOrder: a.DisplayOrder, + IsAsset: assetAccountCategory[a.Category], + IsLiability: liabilityAccountCategory[a.Category], + Hidden: a.Hidden, } } +// FromDB fills the fields from the data stored in database +func (a *AccountExtend) FromDB(data []byte) error { + return json.Unmarshal(data, a) +} + +// ToDB returns the actual stored data in database +func (a *AccountExtend) ToDB() ([]byte, error) { + return json.Marshal(a) +} + // AccountInfoResponseSlice represents the slice data structure of AccountInfoResponse type AccountInfoResponseSlice []*AccountInfoResponse diff --git a/pkg/services/accounts.go b/pkg/services/accounts.go index 2fdb9890..589f24a4 100644 --- a/pkg/services/accounts.go +++ b/pkg/services/accounts.go @@ -329,7 +329,7 @@ func (s *AccountService) ModifyAccounts(c core.Context, uid int64, accounts []*m return s.UserDataDB(uid).DoTransaction(c, func(sess *xorm.Session) error { for i := 0; i < len(accounts); i++ { account := accounts[i] - updatedRows, err := sess.ID(account.AccountId).Cols("name", "category", "icon", "color", "comment", "hidden", "updated_unix_time").Where("uid=? AND deleted=?", uid, false).Update(account) + updatedRows, err := sess.ID(account.AccountId).Cols("name", "category", "icon", "color", "comment", "extend", "hidden", "updated_unix_time").Where("uid=? AND deleted=?", uid, false).Update(account) if err != nil { return err diff --git a/src/consts/account.js b/src/consts/account.js index 77dc2969..b32ba6da 100644 --- a/src/consts/account.js +++ b/src/consts/account.js @@ -1,49 +1,61 @@ -const allAccountCategories = [ - { +const allAccountCategories = { + Cash: { id: 1, name: 'Cash', defaultAccountIconId: '1' }, - { + CheckingAccount: { id: 2, name: 'Checking Account', defaultAccountIconId: '100' }, - { + SavingsAccount: { id: 8, name: 'Savings Account', defaultAccountIconId: '100' }, - { + CreditCard: { id: 3, name: 'Credit Card', defaultAccountIconId: '100' }, - { + VirtualAccount: { id: 4, name: 'Virtual Account', defaultAccountIconId: '500' }, - { + DebtAccount: { id: 5, name: 'Debt Account', defaultAccountIconId: '600' }, - { + Receivables: { id: 6, name: 'Receivables', defaultAccountIconId: '700' }, - { + CertificatePfDeposit: { id: 9, name: 'Certificate of Deposit', defaultAccountIconId: '110' }, - { + InvestmentAccount: { id: 7, name: 'Investment Account', defaultAccountIconId: '800' } +}; + +const allAccountCategoriesArray = [ + allAccountCategories.Cash, + allAccountCategories.CheckingAccount, + allAccountCategories.SavingsAccount, + allAccountCategories.CreditCard, + allAccountCategories.VirtualAccount, + allAccountCategories.DebtAccount, + allAccountCategories.Receivables, + allAccountCategories.CertificatePfDeposit, + allAccountCategories.InvestmentAccount ]; const allAccountTypes = { SingleAccount: 1, @@ -60,7 +72,9 @@ const allAccountTypesArray = [ ]; export default { - allCategories: allAccountCategories, + cashCategoryType: allAccountCategories.Cash.id, + creditCardCategoryType: allAccountCategories.CreditCard.id, + allCategories: allAccountCategoriesArray, allAccountTypes: allAccountTypes, allAccountTypesArray: allAccountTypesArray, }; diff --git a/src/lib/account.js b/src/lib/account.js index e9676c54..09488cd8 100644 --- a/src/lib/account.js +++ b/src/lib/account.js @@ -12,6 +12,7 @@ export function setAccountModelByAnotherAccount(account, account2) { account.balance = account2.balance; account.balanceTime = account2.balanceTime; account.comment = account2.comment; + account.creditCardStatementDate = account2.creditCardStatementDate; account.visible = !account2.hidden; } diff --git a/src/lib/services.js b/src/lib/services.js index ef513309..5dad70bb 100644 --- a/src/lib/services.js +++ b/src/lib/services.js @@ -256,7 +256,7 @@ export default { getAccount: ({ id }) => { return axios.get('v1/accounts/get.json?id=' + id); }, - addAccount: ({ category, type, name, icon, color, currency, balance, balanceTime, comment, subAccounts, clientSessionId }) => { + addAccount: ({ category, type, name, icon, color, currency, balance, balanceTime, comment, creditCardStatementDate, subAccounts, clientSessionId }) => { return axios.post('v1/accounts/add.json', { category, type, @@ -267,11 +267,12 @@ export default { balance, balanceTime, comment, + creditCardStatementDate, subAccounts, clientSessionId }); }, - modifyAccount: ({ id, category, name, icon, color, comment, hidden, subAccounts }) => { + modifyAccount: ({ id, category, name, icon, color, comment, creditCardStatementDate, hidden, subAccounts }) => { return axios.post('v1/accounts/modify.json', { id, category, @@ -279,6 +280,7 @@ export default { icon, color, comment, + creditCardStatementDate, hidden, subAccounts }); diff --git a/src/locales/en.json b/src/locales/en.json index 92fd028c..b41b1682 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -1061,6 +1061,7 @@ "account is in use and cannot be deleted": "Account is in use and it cannot be deleted", "account category is invalid": "Account category is invalid", "account balance time is not set": "Account balance time is not set", + "cannot set statement date for non credit card account": "Cannot set statement date for non credit card account", "transaction id is invalid": "Transaction ID is invalid", "transaction not found": "Transaction is not found", "transaction type is invalid": "Transaction type is invalid", @@ -1172,6 +1173,7 @@ "type": "Type", "color": "Color", "currency": "Currency", + "creditCardStatementDate": "Credit Card Statement Date", "parentId": "Parent Node ID", "categoryId": "Category ID", "time": "Time", @@ -1232,6 +1234,7 @@ "Clear": "Clear", "None": "None", "Unspecified": "Unspecified", + "Not set": "Not set", "No results": "No results", "Unknown": "Unknown", "Miscellaneous": "Miscellaneous", @@ -1468,6 +1471,7 @@ "Sub-account Balance": "Sub-account Balance", "Balance Time": "Balance Time", "Sub-account Balance Time": "Sub-account Balance Time", + "Statement Date": "Statement Date", "Description": "Description", "Your account description (optional)": "Your account description (optional)", "Your sub-account description (optional)": "Your sub-account description (optional)", diff --git a/src/locales/vi.json b/src/locales/vi.json index d69c3928..8dbf2de9 100644 --- a/src/locales/vi.json +++ b/src/locales/vi.json @@ -1061,6 +1061,7 @@ "account is in use and cannot be deleted": "Tài khoản đang được sử dụng và không thể xóa", "account category is invalid": "Danh mục tài khoản không hợp lệ", "account balance time is not set": "Thời gian số dư tài khoản chưa được đặt", + "cannot set statement date for non credit card account": "Cannot set statement date for non credit card account", "transaction id is invalid": "ID giao dịch không hợp lệ", "transaction not found": "Không tìm thấy giao dịch", "transaction type is invalid": "Loại giao dịch không hợp lệ", @@ -1172,6 +1173,7 @@ "type": "Loại", "color": "Màu sắc", "currency": "Tiền tệ", + "creditCardStatementDate": "Credit Card Statement Date", "parentId": "ID nút cha", "categoryId": "ID danh mục", "time": "Thời gian", @@ -1232,6 +1234,7 @@ "Clear": "Xóa", "None": "Không có", "Unspecified": "Không xác định", + "Not set": "Not set", "No results": "Không có kết quả", "Unknown": "Không rõ", "Miscellaneous": "Linh tinh", @@ -1468,6 +1471,7 @@ "Sub-account Balance": "Số dư tài khoản phụ", "Balance Time": "Thời gian số dư", "Sub-account Balance Time": "Thời gian số dư tài khoản phụ", + "Statement Date": "Statement Date", "Description": "Mô tả", "Your account description (optional)": "Mô tả tài khoản của bạn (tùy chọn)", "Your sub-account description (optional)": "Mô tả tài khoản phụ của bạn (tùy chọn)", diff --git a/src/locales/zh_Hans.json b/src/locales/zh_Hans.json index a14b14cc..fcf5c2fa 100644 --- a/src/locales/zh_Hans.json +++ b/src/locales/zh_Hans.json @@ -1061,6 +1061,7 @@ "account is in use and cannot be deleted": "账户正在被使用,无法删除", "account category is invalid": "账户分类无效", "account balance time is not set": "账户余额时间没有设置", + "cannot set statement date for non credit card account": "非信用卡账户不能设置账单日期", "transaction id is invalid": "交易ID无效", "transaction not found": "交易不存在", "transaction type is invalid": "交易类型无效", @@ -1172,6 +1173,7 @@ "type": "类型", "color": "颜色", "currency": "货币", + "creditCardStatementDate": "信用卡账单日期", "parentId": "父节点ID", "categoryId": "分类ID", "time": "时间", @@ -1232,6 +1234,7 @@ "Clear": "清除", "None": "无", "Unspecified": "未指定", + "Not set": "未设置", "No results": "无结果", "Unknown": "未知", "Miscellaneous": "杂项", @@ -1468,6 +1471,7 @@ "Sub-account Balance": "子账户余额", "Balance Time": "余额时间", "Sub-account Balance Time": "子账户余额时间", + "Statement Date": "账单日期", "Description": "描述", "Your account description (optional)": "你的账户描述 (可选)", "Your sub-account description (optional)": "你的子账户描述 (可选)", diff --git a/src/stores/account.js b/src/stores/account.js index d153bc20..306fec51 100644 --- a/src/stores/account.js +++ b/src/stores/account.js @@ -258,7 +258,7 @@ export const useAccountsStore = defineStore('accounts', { const now = getCurrentUnixTime(); return { - category: 1, + category: accountConstants.cashCategoryType, type: accountConstants.allAccountTypes.SingleAccount, name: '', icon: iconConstants.defaultAccountIconId, @@ -267,6 +267,7 @@ export const useAccountsStore = defineStore('accounts', { balance: 0, balanceTime: now, comment: '', + creditCardStatementDate: 0, visible: true }; }, @@ -284,6 +285,7 @@ export const useAccountsStore = defineStore('accounts', { balance: 0, balanceTime: now, comment: '', + creditCardStatementDate: parentAccount.creditCardStatementDate, visible: true }; }, @@ -760,6 +762,10 @@ export const useAccountsStore = defineStore('accounts', { comment: subAccount.comment }; + if (account.category === accountConstants.creditCardCategoryType) { + submitAccount.creditCardStatementDate = subAccount.creditCardStatementDate; + } + if (isEdit) { submitAccount.id = subAccount.id; submitAccount.hidden = !subAccount.visible; @@ -783,6 +789,10 @@ export const useAccountsStore = defineStore('accounts', { subAccounts: account.type === accountConstants.allAccountTypes.SingleAccount ? null : submitSubAccounts, }; + if (account.category === accountConstants.creditCardCategoryType) { + submitAccount.creditCardStatementDate = account.creditCardStatementDate; + } + if (clientSessionId) { submitAccount.clientSessionId = clientSessionId; } diff --git a/src/views/desktop/accounts/list/dialogs/EditDialog.vue b/src/views/desktop/accounts/list/dialogs/EditDialog.vue index 82e0d227..44057475 100644 --- a/src/views/desktop/accounts/list/dialogs/EditDialog.vue +++ b/src/views/desktop/accounts/list/dialogs/EditDialog.vue @@ -108,7 +108,7 @@ :disabled="loading || submitting" v-model="selectedAccount.color" /> - + + + + + + + + + + + + @@ -387,6 +415,20 @@ + + + +