Upgrade to vue3 (#16)

* upgrade to vue 3.x and framework7 8.x
* change calendar plugin to vue-datepicker
* disable export button when user does not hava any transaction
* implement new pin code input
* append thousands separator in amount in exchange rates page
This commit is contained in:
mayswind
2023-04-21 01:45:00 +08:00
committed by GitHub
parent 4b0f7d45e8
commit b1c765eb51
89 changed files with 8353 additions and 16671 deletions
+43 -35
View File
@@ -2,39 +2,33 @@
<f7-page @page:afterin="onPageAfterIn">
<f7-navbar :title="$t('Data Management')" :back-link="$t('Back')"></f7-navbar>
<f7-card class="skeleton-text" v-if="loading">
<f7-card-content class="no-safe-areas" :padding="false">
<f7-list>
<f7-list-item title="Accounts" after="Count"></f7-list-item>
<f7-list-item title="Transaction Categories" after="Count"></f7-list-item>
<f7-list-item title="Transaction Tags" after="Count"></f7-list-item>
<f7-list-item title="Transactions" after="Count"></f7-list-item>
</f7-list>
</f7-card-content>
</f7-card>
<f7-list strong inset dividers class="margin-vertical skeleton-text" v-if="loading">
<f7-list-item title="Accounts" after="Count"></f7-list-item>
<f7-list-item title="Transaction Categories" after="Count"></f7-list-item>
<f7-list-item title="Transaction Tags" after="Count"></f7-list-item>
<f7-list-item title="Transactions" after="Count"></f7-list-item>
</f7-list>
<f7-card v-else-if="!loading">
<f7-card-content class="no-safe-areas" :padding="false">
<f7-list>
<f7-list-item :title="$t('Accounts')" :after="dataStatistics.totalAccountCount"></f7-list-item>
<f7-list-item :title="$t('Transaction Categories')" :after="dataStatistics.totalTransactionCategoryCount"></f7-list-item>
<f7-list-item :title="$t('Transaction Tags')" :after="dataStatistics.totalTransactionTagCount"></f7-list-item>
<f7-list-item :title="$t('Transactions')" :after="dataStatistics.totalTransactionCount"></f7-list-item>
</f7-list>
</f7-card-content>
</f7-card>
<f7-list strong inset dividers class="margin-vertical" v-else-if="!loading">
<f7-list-item :title="$t('Accounts')" :after="dataStatistics.totalAccountCount"></f7-list-item>
<f7-list-item :title="$t('Transaction Categories')" :after="dataStatistics.totalTransactionCategoryCount"></f7-list-item>
<f7-list-item :title="$t('Transaction Tags')" :after="dataStatistics.totalTransactionTagCount"></f7-list-item>
<f7-list-item :title="$t('Transactions')" :after="dataStatistics.totalTransactionCount"></f7-list-item>
</f7-list>
<f7-card>
<f7-card-content class="no-safe-areas" :padding="false">
<f7-list>
<f7-list-button @click="exportedData = null; showExportDataSheet = true" v-if="isDataExportingEnabled">{{ $t('Export Data') }}</f7-list-button>
<f7-list-button color="red" @click="clearData(null)">{{ $t('Clear User Data') }}</f7-list-button>
</f7-list>
</f7-card-content>
</f7-card>
<f7-list strong inset dividers class="margin-vertical" :class="{ 'disabled': loading }">
<f7-list-button :class="{ 'disabled': !dataStatistics || !dataStatistics.totalTransactionCount || dataStatistics.totalTransactionCount === '0' }"
v-if="isDataExportingEnabled"
@click="exportedData = null; showExportDataSheet = true">{{ $t('Export Data') }}</f7-list-button>
<f7-list-button color="red" @click="clearData(null)">{{ $t('Clear User Data') }}</f7-list-button>
</f7-list>
<f7-sheet style="height:auto" :opened="showExportDataSheet" @sheet:closed="showExportDataSheet = false; exportedData = null;">
<f7-page-content>
<f7-sheet swipe-handler=".swipe-handler" style="height:auto"
:swipe-to-close="!exportingData" :close-on-escape="!exportingData"
:close-by-backdrop-click="!exportingData" :close-by-outside-click="!exportingData"
:opened="showExportDataSheet" @sheet:closed="showExportDataSheet = false; exportedData = null;">
<div class="swipe-handler"></div>
<f7-page-content class="margin-top no-padding-top">
<div class="display-flex padding justify-content-space-between align-items-center">
<div style="font-size: 18px"><b>{{ $t('Are you sure you want to export all data to csv file?') }}</b></div>
</div>
@@ -51,9 +45,9 @@
<password-input-sheet :title="$t('Are you sure you want to clear all data?')"
:hint="$t('You CANNOT undo this action. This will clear your accounts, categories, tags and transactions data. Please input your current password to confirm.')"
:show.sync="showInputPasswordSheetForClearData"
:confirm-disabled="clearingData"
:cancel-disabled="clearingData"
v-model:show="showInputPasswordSheetForClearData"
v-model="currentPasswordForClearData"
@password:confirm="clearData">
</password-input-sheet>
@@ -62,6 +56,9 @@
<script>
export default {
props: [
'f7router'
],
data() {
return {
loading: true,
@@ -76,9 +73,6 @@ export default {
};
},
computed: {
currentTimezoneOffsetMinutes() {
return this.$utilities.getTimezoneOffsetMinutes();
},
isDataExportingEnabled() {
return this.$settings.isDataExportingEnabled();
},
@@ -113,7 +107,7 @@ export default {
},
methods: {
onPageAfterIn() {
this.$routeBackOnError('loadingError');
this.$routeBackOnError(this.f7router, 'loadingError');
},
exportData() {
const self = this;
@@ -155,6 +149,20 @@ export default {
self.showInputPasswordSheetForClearData = false;
self.$toast('All user data has been cleared');
self.loading = true;
self.$store.dispatch('getUserDataStatistics').then(dataStatistics => {
self.dataStatistics = dataStatistics;
self.loading = false;
}).catch(error => {
if (error.processed) {
self.loading = false;
} else {
self.loadingError = error;
self.$toast(error.message || error);
}
});
}).catch(error => {
self.clearingData = false;
self.$hideLoading();
+83 -47
View File
@@ -4,46 +4,49 @@
<f7-nav-left :back-link="$t('Back')"></f7-nav-left>
<f7-nav-title :title="$t('Device & Sessions')"></f7-nav-title>
<f7-nav-right>
<f7-link :class="{ 'disabled': tokens.length < 2 }" :text="$t('Logout All')" @click="revokeAll"></f7-link>
<f7-link :class="{ 'disabled': sessions.length < 2 }" :text="$t('Logout All')" @click="revokeAll"></f7-link>
</f7-nav-right>
</f7-navbar>
<f7-card class="skeleton-text" v-if="loading">
<f7-card-content class="no-safe-areas" :padding="false">
<f7-list media-list>
<f7-list-item class="list-item-media-valign-middle"
title="Current"
text="Device Name (Browser xx.x.xxxx.xx)">
<f7-icon slot="media" f7="device_phone_portrait"></f7-icon>
<small slot="after">MM/DD/YYYY HH:mm:ss</small>
</f7-list-item>
</f7-list>
</f7-card-content>
</f7-card>
<f7-list media-list strong inset dividers class="margin-top skeleton-text" v-if="loading">
<f7-list-item class="list-item-media-valign-middle"
title="Current"
text="Device Name (Browser xx.x.xxxx.xx)">
<template #media>
<f7-icon f7="device_phone_portrait"></f7-icon>
</template>
<template #after>
<small>MM/DD/YYYY HH:mm:ss</small>
</template>
</f7-list-item>
</f7-list>
<f7-card v-else-if="!loading">
<f7-card-content class="no-safe-areas" :padding="false">
<f7-list media-list>
<f7-list-item class="list-item-media-valign-middle" swipeout
v-for="token in tokens"
:key="token.tokenId"
:id="token | tokenDomId"
:title="token | tokenTitle | localized"
:text="token | tokenDevice | localized">
<f7-icon slot="media" :f7="token | tokenIcon"></f7-icon>
<small slot="after">{{ token.createdAt | moment($t('format.datetime.long')) }}</small>
<f7-swipeout-actions right v-if="!token.isCurrent">
<f7-swipeout-button color="red" :text="$t('Log Out')" @click="revoke(token)"></f7-swipeout-button>
</f7-swipeout-actions>
</f7-list-item>
</f7-list>
</f7-card-content>
</f7-card>
<f7-list media-list strong inset dividers class="margin-top" v-else-if="!loading">
<f7-list-item class="list-item-media-valign-middle" swipeout
:id="session.domId"
:title="session.deviceType"
:text="session.deviceInfo"
:key="session.tokenId"
v-for="session in sessions">
<template #media>
<f7-icon :f7="session.icon"></f7-icon>
</template>
<template #after>
<small>{{ session.createdAt }}</small>
</template>
<f7-swipeout-actions right v-if="!session.isCurrent">
<f7-swipeout-button color="red" :text="$t('Log Out')" @click="revoke(session)"></f7-swipeout-button>
</f7-swipeout-actions>
</f7-list-item>
</f7-list>
</f7-page>
</template>
<script>
export default {
props: [
'f7router'
],
data() {
return {
tokens: [],
@@ -51,6 +54,31 @@ export default {
loadingError: null
};
},
computed: {
sessions() {
if (!this.tokens) {
return this.tokens;
}
const sessions = [];
for (let i = 0; i < this.tokens.length; i++) {
const token = this.tokens[i];
sessions.push({
tokenId: token.tokenId,
domId: this.getTokenDomId(token.tokenId),
isCurrent: token.isCurrent,
deviceType: this.$t(token.isCurrent ? 'Current' : 'Other Device'),
deviceInfo: this.$utilities.parseDeviceInfo(token.userAgent),
icon: this.getTokenIcon(token),
createdAt: this.$utilities.formatUnixTime(token.createdAt, this.$t('format.datetime.long'))
});
}
return sessions;
}
},
created() {
const self = this;
@@ -70,7 +98,7 @@ export default {
},
methods: {
onPageAfterIn() {
this.$routeBackOnError('loadingError');
this.$routeBackOnError(this.f7router, 'loadingError');
},
reload(done) {
const self = this;
@@ -91,22 +119,20 @@ export default {
}
});
},
revoke(token) {
revoke(session) {
const self = this;
const app = self.$f7;
const $$ = app.$;
self.$confirm('Are you sure you want to logout from this session?', () => {
self.$showLoading();
self.$store.dispatch('revokeToken', {
tokenId: token.tokenId
tokenId: session.tokenId
}).then(() => {
self.$hideLoading();
app.swipeout.delete($$(`#${self.$options.filters.tokenDomId(token)}`), () => {
self.$ui.onSwipeoutDeleted(self.getTokenDomId(session.tokenId), () => {
for (let i = 0; i < self.tokens.length; i++) {
if (self.tokens[i].tokenId === token.tokenId) {
if (self.tokens[i].tokenId === session.tokenId) {
self.tokens.splice(i, 1);
}
}
@@ -148,18 +174,28 @@ export default {
}
});
});
}
},
filters: {
tokenTitle(token) {
if (token.isCurrent) {
return 'Current';
},
getTokenIcon(token) {
const ua = this.$utilities.parseUserAgent(token.userAgent);
if (!ua || !ua.device) {
return this.$constants.icons.deviceIcons.desktop.f7Icon;
}
return 'Other Device';
if (ua.device.type === 'mobile') {
return this.$constants.icons.deviceIcons.mobile.f7Icon;
} else if (ua.device.type === 'wearable') {
return this.$constants.icons.deviceIcons.wearable.f7Icon;
} else if (ua.device.type === 'tablet') {
return this.$constants.icons.deviceIcons.tablet.f7Icon;
} else if (ua.device.type === 'smarttv') {
return this.$constants.icons.deviceIcons.tv.f7Icon;
} else {
return this.$constants.icons.deviceIcons.desktop.f7Icon;
}
},
tokenDomId(token) {
return 'token_' + token.tokenId.replace(/:/g, '_');
getTokenDomId(tokenId) {
return 'token_' + tokenId.replace(/:/g, '_');
}
}
};
+28 -38
View File
@@ -2,62 +2,44 @@
<f7-page @page:afterin="onPageAfterIn">
<f7-navbar :title="$t('Two-Factor Authentication')" :back-link="$t('Back')"></f7-navbar>
<f7-card class="skeleton-text" v-if="loading">
<f7-card-content class="no-safe-areas" :padding="false">
<f7-list>
<f7-list-item title="Status" after="Unknown"></f7-list-item>
<f7-list-button class="disabled">Operate</f7-list-button>
</f7-list>
</f7-card-content>
</f7-card>
<f7-list strong inset dividers class="margin-top skeleton-text" v-if="loading">
<f7-list-item title="Status" after="Unknown"></f7-list-item>
<f7-list-button class="disabled">Operate</f7-list-button>
</f7-list>
<f7-card v-else-if="!loading && status === true">
<f7-card-content class="no-safe-areas" :padding="false">
<f7-list>
<f7-list-item :title="$t('Status')" :after="$t('Enabled')"></f7-list-item>
<f7-list-button :class="{ 'disabled': regenerating }" @click="regenerateBackupCode(null)">{{ $t('Regenerate Backup Codes') }}</f7-list-button>
<f7-list-button :class="{ 'disabled': disabling }" @click="disable(null)">{{ $t('Disable') }}</f7-list-button>
</f7-list>
</f7-card-content>
</f7-card>
<f7-list strong inset dividers class="margin-top" v-else-if="!loading">
<f7-list-item :title="$t('Status')" :after="$t(status ? 'Enabled' : 'Disabled')"></f7-list-item>
<f7-list-button :class="{ 'disabled': regenerating }" v-if="status === true" @click="regenerateBackupCode(null)">{{ $t('Regenerate Backup Codes') }}</f7-list-button>
<f7-list-button :class="{ 'disabled': disabling }" v-if="status === true" @click="disable(null)">{{ $t('Disable') }}</f7-list-button>
<f7-list-button :class="{ 'disabled': enabling }" v-if="status === false" @click="enable">{{ $t('Enable') }}</f7-list-button>
</f7-list>
<f7-card v-else-if="!loading && status === false">
<f7-card-content class="no-safe-areas" :padding="false">
<f7-list>
<f7-list-item :title="$t('Status')" :after="$t('Disabled')"></f7-list-item>
<f7-list-button :class="{ 'disabled': enabling }" @click="enable">{{ $t('Enable') }}</f7-list-button>
</f7-list>
</f7-card-content>
</f7-card>
<passcode-input-sheet :title="$t('Passcode')"
<passcode-input-sheet :title="$t('Enable Two-Factor Authentication')"
:hint="$t('Please use two factor authentication app scan the below qrcode and input current passcode')"
:show.sync="showInputPasscodeSheetForEnable"
:confirm-disabled="enableConfirming"
:cancel-disabled="enableConfirming"
v-model:show="showInputPasscodeSheetForEnable"
v-model="currentPasscodeForEnable"
@passcode:confirm="enableConfirm">
<div class="row">
<div class="col-100 text-align-center">
<img alt="qrcode" width="240px" height="240px" :src="new2FAQRCode" />
</div>
<div class="col-100 text-align-center">
<img alt="qrcode" class="img-qrcode" :src="new2FAQRCode" />
</div>
</passcode-input-sheet>
<password-input-sheet :title="$t('Current Password')"
<password-input-sheet :title="$t('Disable Two-Factor Authentication')"
:hint="$t('Please enter your current password when disable two factor authentication')"
:show.sync="showInputPasswordSheetForDisable"
:confirm-disabled="disabling"
:cancel-disabled="disabling"
v-model:show="showInputPasswordSheetForDisable"
v-model="currentPasswordForDisable"
@password:confirm="disable">
</password-input-sheet>
<password-input-sheet :title="$t('Current Password')"
<password-input-sheet :title="$t('Regenerate Backup Codes')"
:hint="$t('Please enter your current password when regenerate two factor authentication backup codes. If you regenerate backup codes, the old codes will be invalidated.')"
:show.sync="showInputPasswordSheetForRegenerate"
:confirm-disabled="regenerating"
:cancel-disabled="regenerating"
v-model:show="showInputPasswordSheetForRegenerate"
v-model="currentPasswordForRegenerate"
@password:confirm="regenerateBackupCode">
</password-input-sheet>
@@ -68,7 +50,7 @@
:information="currentBackupCode"
:row-count="10"
:enable-copy="true"
:show.sync="showBackupCodeSheet"
v-model:show="showBackupCodeSheet"
@info:copied="onBackupCodeCopied">
</information-sheet>
</f7-page>
@@ -76,6 +58,9 @@
<script>
export default {
props: [
'f7router'
],
data() {
return {
status: null,
@@ -116,7 +101,7 @@ export default {
},
methods: {
onPageAfterIn() {
this.$routeBackOnError('loadingError');
this.$routeBackOnError(this.f7router, 'loadingError');
},
enable() {
const self = this;
@@ -245,6 +230,11 @@ export default {
</script>
<style>
.img-qrcode {
width: 240px;
height: 240px
}
.backup-code-sheet .information-content {
font-family: monospace;
}
+123 -132
View File
@@ -8,152 +8,135 @@
</f7-nav-right>
</f7-navbar>
<f7-card class="skeleton-text" v-if="loading">
<f7-card-content class="no-safe-areas" :padding="false">
<f7-list>
<f7-list-input label="Password" placeholder="Your password"></f7-list-input>
<f7-list-input label="Confirmation Password" placeholder="Re-enter the password"></f7-list-input>
<f7-list-input label="E-mail" placeholder="Your email address"></f7-list-input>
<f7-list-input label="Nickname" placeholder="Your nickname"></f7-list-input>
</f7-list>
</f7-card-content>
</f7-card>
<f7-list strong inset dividers class="margin-vertical skeleton-text" v-if="loading">
<f7-list-input label="Password" placeholder="Your password"></f7-list-input>
<f7-list-input label="Confirmation Password" placeholder="Re-enter the password"></f7-list-input>
<f7-list-input label="E-mail" placeholder="Your email address"></f7-list-input>
<f7-list-input label="Nickname" placeholder="Your nickname"></f7-list-input>
</f7-list>
<f7-card class="skeleton-text" v-if="loading">
<f7-card-content class="no-safe-areas" :padding="false">
<f7-list>
<f7-list-item class="list-item-with-header-and-title list-item-no-item-after" header="Default Currency" title="Currency"></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"></f7-list-item>
<f7-list-item class="list-item-with-header-and-title list-item-no-item-after" header="Editable Transaction Scope" title="All"></f7-list-item>
</f7-list>
</f7-card-content>
</f7-card>
<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="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>
<f7-card v-if="!loading">
<f7-card-content class="no-safe-areas" :padding="false">
<f7-list form>
<f7-list-input
type="password"
autocomplete="new-password"
clear-button
:label="$t('Password')"
:placeholder="$t('Your password')"
:value="newProfile.password"
@input="newProfile.password = $event.target.value"
></f7-list-input>
<f7-list form strong inset dividers class="margin-vertical" v-if="!loading">
<f7-list-input
type="password"
autocomplete="new-password"
clear-button
:label="$t('Password')"
:placeholder="$t('Your password')"
v-model:value="newProfile.password"
></f7-list-input>
<f7-list-input
type="password"
autocomplete="new-password"
clear-button
:label="$t('Confirmation Password')"
:placeholder="$t('Re-enter the password')"
:value="newProfile.confirmPassword"
@input="newProfile.confirmPassword = $event.target.value"
></f7-list-input>
<f7-list-input
type="password"
autocomplete="new-password"
clear-button
:label="$t('Confirmation Password')"
:placeholder="$t('Re-enter the password')"
v-model:value="newProfile.confirmPassword"
></f7-list-input>
<f7-list-input
type="email"
autocomplete="email"
clear-button
:label="$t('E-mail')"
:placeholder="$t('Your email address')"
:value="newProfile.email"
@input="newProfile.email = $event.target.value"
></f7-list-input>
<f7-list-input
type="email"
autocomplete="email"
clear-button
:label="$t('E-mail')"
:placeholder="$t('Your email address')"
v-model:value="newProfile.email"
></f7-list-input>
<f7-list-input
type="text"
autocomplete="nickname"
clear-button
:label="$t('Nickname')"
:placeholder="$t('Your nickname')"
:value="newProfile.nickname"
@input="newProfile.nickname = $event.target.value"
></f7-list-input>
<f7-list-input
type="text"
autocomplete="nickname"
clear-button
:label="$t('Nickname')"
:placeholder="$t('Your nickname')"
v-model:value="newProfile.nickname"
></f7-list-input>
<f7-list-item class="ebk-list-item-error-info" v-if="inputIsInvalid" :footer="$t(inputInvalidProblemMessage)"></f7-list-item>
</f7-list>
</f7-card-content>
</f7-card>
<f7-list-item class="ebk-list-item-error-info" v-if="inputIsInvalid" :footer="$t(inputInvalidProblemMessage)"></f7-list-item>
</f7-list>
<f7-card v-if="!loading">
<f7-card-content class="no-safe-areas" :padding="false">
<f7-list form>
<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', pageTitle: $t('Default Currency'), searchbar: true, searchbarPlaceholder: $t('Currency Name'), searchbarDisableText: $t('Cancel'), closeOnSelect: true, popupCloseLinkText: $t('Done'), scrollToSelectedItem: true }"
>
<f7-block slot="title" class="no-padding no-margin">
<span>{{ $t(`currency.${newProfile.defaultCurrency}`) }}&nbsp;</span>
<small class="smaller">{{ newProfile.defaultCurrency }}</small>
</f7-block>
<select autocomplete="transaction-currency" v-model="newProfile.defaultCurrency">
<option v-for="currency in allCurrencies"
:key="currency.code"
:value="currency.code">{{ currency.displayName }}</option>
</select>
</f7-list-item>
<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
class="list-item-with-header-and-title"
link="#"
:class="{ 'disabled': !allVisibleAccounts.length }"
:header="$t('Default Account')"
:title="newProfile.defaultAccountId | optionName(allAccounts, 'id', 'name', $t('Not Specified'))"
@click="showAccountSheet = true"
>
<two-column-list-item-selection-sheet primary-key-field="id" primary-value-field="category"
primary-title-field="name"
primary-icon-field="icon" primary-icon-type="account"
primary-sub-items-field="accounts"
:primary-title-i18n="true"
secondary-key-field="id" secondary-value-field="id"
secondary-title-field="name"
secondary-icon-field="icon" secondary-icon-type="account" secondary-color-field="color"
:items="allCategorizedAccounts"
:show.sync="showAccountSheet"
v-model="newProfile.defaultAccountId">
</two-column-list-item-selection-sheet>
</f7-list-item>
<f7-list-item
class="list-item-with-header-and-title"
link="#" no-chevron
:class="{ 'disabled': !allVisibleAccounts.length }"
:header="$t('Default Account')"
:title="$utilities.getNameByKeyValue(allAccounts, newProfile.defaultAccountId, 'id', 'name', $t('Not Specified'))"
@click="showAccountSheet = true"
>
<two-column-list-item-selection-sheet primary-key-field="id" primary-value-field="category"
primary-title-field="name"
primary-icon-field="icon" primary-icon-type="account"
primary-sub-items-field="accounts"
:primary-title-i18n="true"
secondary-key-field="id" secondary-value-field="id"
secondary-title-field="name"
secondary-icon-field="icon" secondary-icon-type="account" secondary-color-field="color"
:items="allCategorizedAccounts"
v-model:show="showAccountSheet"
v-model="newProfile.defaultAccountId">
</two-column-list-item-selection-sheet>
</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="newProfile.firstDayOfWeek | optionName(allWeekDays, 'type', 'name') | format('datetime.#{value}.long') | localized"
smart-select :smart-select-params="{ openIn: 'popup', pageTitle: $t('First Day of Week'), closeOnSelect: true, popupCloseLinkText: $t('Done'), scrollToSelectedItem: true }"
>
<select v-model="newProfile.firstDayOfWeek">
<option v-for="weekDay in allWeekDays"
:key="weekDay.type"
:value="weekDay.type">{{ $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('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
class="list-item-with-header-and-title list-item-no-item-after"
:header="$t('Editable Transaction Scope')"
:title="newProfile.transactionEditScope | optionName(allTransactionEditScopeTypes, 'value', 'name') | localized"
smart-select :smart-select-params="{ openIn: 'popup', pageTitle: $t('Editable Transaction Scope'), closeOnSelect: true, popupCloseLinkText: $t('Done'), scrollToSelectedItem: true }"
>
<select v-model="newProfile.transactionEditScope">
<option v-for="option in allTransactionEditScopeTypes"
:key="option.value"
:value="option.value">{{ $t(option.name) }}</option>
</select>
</f7-list-item>
<f7-list-item
class="list-item-with-header-and-title list-item-no-item-after"
:header="$t('Editable Transaction Scope')"
:title="$t($utilities.getNameByKeyValue(allTransactionEditScopeTypes, newProfile.transactionEditScope, 'value', 'name'))"
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Date Range'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), pageTitle: $t('Editable Transaction Scope'), popupCloseLinkText: $t('Done') }"
>
<select v-model="newProfile.transactionEditScope">
<option :value="option.value"
:key="option.value"
v-for="option in allTransactionEditScopeTypes">{{ $t(option.name) }}</option>
</select>
</f7-list-item>
<f7-list-item class="ebk-list-item-error-info" v-if="extendInputIsInvalid" :footer="$t(extendInputInvalidProblemMessage)"></f7-list-item>
</f7-list>
</f7-card-content>
</f7-card>
<f7-list-item class="ebk-list-item-error-info" v-if="extendInputIsInvalid" :footer="$t(extendInputInvalidProblemMessage)"></f7-list-item>
</f7-list>
<password-input-sheet :title="$t('Current Password')"
:hint="$t('Please enter your current password when modifying your password')"
:show.sync="showInputPasswordSheet"
:confirm-disabled="saving"
:cancel-disabled="saving"
v-model:show="showInputPasswordSheet"
v-model="currentPassword"
@password:confirm="save()">
</password-input-sheet>
@@ -162,6 +145,9 @@
<script>
export default {
props: [
'f7router'
],
data() {
return {
newProfile: {
@@ -318,11 +304,11 @@ export default {
},
methods: {
onPageAfterIn() {
this.$routeBackOnError('loadingError');
this.$routeBackOnError(this.f7router, 'loadingError');
},
save() {
const self = this;
const router = self.$f7router;
const router = self.f7router;
self.showInputPasswordSheet = false;
@@ -360,6 +346,11 @@ export default {
self.$toast(error.message || error);
}
});
},
getDayOfWeekName(dayOfWeek) {
const weekName = this.$utilities.getNameByKeyValue(this.$constants.datetime.allWeekDays, dayOfWeek, 'type', 'name');
const i18nWeekNameKey = `datetime.${weekName}.long`;
return this.$t(i18nWeekNameKey);
}
}
};