mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-16 07:57:33 +08:00
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:
@@ -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();
|
||||
|
||||
@@ -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, '_');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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}`) }} </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}`) }} </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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user