mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-15 23:47:33 +08:00
migrate transaction tag filter page to composition API and typescript
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<f7-page @page:afterin="onPageAfterIn">
|
||||
<f7-navbar>
|
||||
<f7-nav-left :back-link="$t('Back')"></f7-nav-left>
|
||||
<f7-nav-title :title="$t(title)"></f7-nav-title>
|
||||
<f7-nav-left :back-link="tt('Back')"></f7-nav-left>
|
||||
<f7-nav-title :title="tt(title)"></f7-nav-title>
|
||||
<f7-nav-right>
|
||||
<f7-link icon-f7="ellipsis" :class="{ 'disabled': !hasAnyAvailableTag }" @click="showMoreActionSheet = true"></f7-link>
|
||||
<f7-link :text="$t(applyText)" :class="{ 'disabled': !hasAnyVisibleTag }" @click="save"></f7-link>
|
||||
<f7-link :text="tt(applyText)" :class="{ 'disabled': !hasAnyVisibleTag }" @click="save"></f7-link>
|
||||
</f7-nav-right>
|
||||
</f7-navbar>
|
||||
|
||||
@@ -38,11 +38,11 @@
|
||||
</f7-block>
|
||||
|
||||
<f7-list strong inset dividers accordion-list class="margin-top" v-if="!loading && !hasAnyVisibleTag">
|
||||
<f7-list-item :title="$t('No available tag')"></f7-list-item>
|
||||
<f7-list-item :title="tt('No available tag')"></f7-list-item>
|
||||
</f7-list>
|
||||
|
||||
<f7-block class="combination-list-wrapper margin-vertical" key="default" v-show="!loading && hasAnyVisibleTag">
|
||||
<f7-list class="margin-top-half margin-bottom" strong inset dividers v-if="type === 'statisticsCurrent'">
|
||||
<f7-list class="margin-top-half margin-bottom" strong inset dividers v-if="query['type'] === 'statisticsCurrent'">
|
||||
<f7-list-item radio
|
||||
:title="filterType.displayName"
|
||||
:value="filterType.type"
|
||||
@@ -63,7 +63,7 @@
|
||||
:class="collapseStates['default'].opened ? 'combination-list-opened' : 'combination-list-closed'">
|
||||
<f7-list-item>
|
||||
<template #title>
|
||||
<span>{{ $t('Tags') }}</span>
|
||||
<span>{{ tt('Tags') }}</span>
|
||||
<f7-icon class="combination-list-chevron-icon" :f7="collapseStates['default'].opened ? 'chevron_up' : 'chevron_down'"></f7-icon>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
@@ -79,7 +79,7 @@
|
||||
:key="transactionTag.id"
|
||||
v-for="transactionTag in allTags"
|
||||
v-show="showHidden || !transactionTag.hidden"
|
||||
@change="selectTransactionTag">
|
||||
@change="updateTransactionTagSelected">
|
||||
<template #media>
|
||||
<f7-icon class="transaction-tag-icon" f7="number">
|
||||
<f7-badge color="gray" class="right-bottom-icon" v-if="transactionTag.hidden">
|
||||
@@ -95,28 +95,30 @@
|
||||
|
||||
<f7-actions close-by-outside-click close-on-escape :opened="showMoreActionSheet" @actions:closed="showMoreActionSheet = false">
|
||||
<f7-actions-group>
|
||||
<f7-actions-button :class="{ 'disabled': !hasAnyVisibleTag }" @click="selectAll">{{ $t('Select All') }}</f7-actions-button>
|
||||
<f7-actions-button :class="{ 'disabled': !hasAnyVisibleTag }" @click="selectNone">{{ $t('Select None') }}</f7-actions-button>
|
||||
<f7-actions-button :class="{ 'disabled': !hasAnyVisibleTag }" @click="selectInvert">{{ $t('Invert Selection') }}</f7-actions-button>
|
||||
<f7-actions-button :class="{ 'disabled': !hasAnyVisibleTag }" @click="selectAllTransactionTags">{{ tt('Select All') }}</f7-actions-button>
|
||||
<f7-actions-button :class="{ 'disabled': !hasAnyVisibleTag }" @click="selectNoneTransactionTags">{{ tt('Select None') }}</f7-actions-button>
|
||||
<f7-actions-button :class="{ 'disabled': !hasAnyVisibleTag }" @click="selectInvertTransactionTags">{{ tt('Invert Selection') }}</f7-actions-button>
|
||||
</f7-actions-group>
|
||||
<f7-actions-group>
|
||||
<f7-actions-button v-if="!showHidden" @click="showHidden = true">{{ $t('Show Hidden Transaction Tags') }}</f7-actions-button>
|
||||
<f7-actions-button v-if="showHidden" @click="showHidden = false">{{ $t('Hide Hidden Transaction Tags') }}</f7-actions-button>
|
||||
<f7-actions-button v-if="!showHidden" @click="showHidden = true">{{ tt('Show Hidden Transaction Tags') }}</f7-actions-button>
|
||||
<f7-actions-button v-if="showHidden" @click="showHidden = false">{{ tt('Hide Hidden Transaction Tags') }}</f7-actions-button>
|
||||
</f7-actions-group>
|
||||
<f7-actions-group>
|
||||
<f7-actions-button bold close>{{ $t('Cancel') }}</f7-actions-button>
|
||||
<f7-actions-button bold close>{{ tt('Cancel') }}</f7-actions-button>
|
||||
</f7-actions-group>
|
||||
</f7-actions>
|
||||
</f7-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapStores } from 'pinia';
|
||||
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
||||
import { useTransactionsStore } from '@/stores/transaction.ts';
|
||||
import { useStatisticsStore } from '@/stores/statistics.ts';
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import type { Router } from 'framework7/types';
|
||||
|
||||
import { TransactionTagFilterType } from '@/core/transaction.ts';
|
||||
import { useI18n } from '@/locales/helpers.ts';
|
||||
import { useI18nUIComponents } from '@/lib/ui/mobile.ts';
|
||||
import { useTransactionTagFilterSettingPageBase } from '@/views/base/settings/TransactionTagFilterSettingPageBase.ts';
|
||||
|
||||
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
||||
|
||||
import {
|
||||
selectAll,
|
||||
@@ -124,183 +126,98 @@ import {
|
||||
selectInvert
|
||||
} from '@/lib/common.ts';
|
||||
|
||||
export default {
|
||||
props: [
|
||||
'f7route',
|
||||
'f7router'
|
||||
],
|
||||
data: function () {
|
||||
return {
|
||||
loading: true,
|
||||
loadingError: null,
|
||||
type: null,
|
||||
filterTagIds: {},
|
||||
tagFilterType: TransactionTagFilterType.Default.type,
|
||||
showHidden: false,
|
||||
collapseStates: {
|
||||
'default': {
|
||||
opened: true
|
||||
}
|
||||
},
|
||||
showMoreActionSheet: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapStores(useTransactionTagsStore, useTransactionsStore, useStatisticsStore),
|
||||
title() {
|
||||
return 'Filter Transaction Tags';
|
||||
},
|
||||
applyText() {
|
||||
return 'Apply';
|
||||
},
|
||||
allTags() {
|
||||
return this.transactionTagsStore.allTransactionTags;
|
||||
},
|
||||
allTagFilterTypes() {
|
||||
return this.$locale.getAllTransactionTagFilterTypes();
|
||||
},
|
||||
hasAnyAvailableTag() {
|
||||
return this.transactionTagsStore.allAvailableTagsCount > 0;
|
||||
},
|
||||
hasAnyVisibleTag() {
|
||||
if (this.showHidden) {
|
||||
return this.transactionTagsStore.allAvailableTagsCount > 0;
|
||||
} else {
|
||||
return this.transactionTagsStore.allVisibleTagsCount > 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const self = this;
|
||||
const query = self.f7route.query;
|
||||
|
||||
self.type = query.type;
|
||||
|
||||
self.transactionTagsStore.loadAllTags({
|
||||
force: false
|
||||
}).then(() => {
|
||||
self.loading = false;
|
||||
|
||||
const allTransactionTagIds = {};
|
||||
|
||||
for (const transactionTagId in self.transactionTagsStore.allTransactionTagsMap) {
|
||||
if (!Object.prototype.hasOwnProperty.call(self.transactionTagsStore.allTransactionTagsMap, transactionTagId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const transactionTag = self.transactionTagsStore.allTransactionTagsMap[transactionTagId];
|
||||
allTransactionTagIds[transactionTag.id] = true;
|
||||
}
|
||||
|
||||
if (self.type === 'statisticsCurrent') {
|
||||
const transactionTagIds = self.statisticsStore.transactionStatisticsFilter.tagIds ? self.statisticsStore.transactionStatisticsFilter.tagIds.split(',') : [];
|
||||
|
||||
for (let i = 0; i < transactionTagIds.length; i++) {
|
||||
const transactionTagId = transactionTagIds[i];
|
||||
const transactionTag = self.transactionTagsStore.allTransactionTagsMap[transactionTagId];
|
||||
|
||||
if (transactionTag) {
|
||||
allTransactionTagIds[transactionTag.id] = false;
|
||||
}
|
||||
}
|
||||
self.filterTagIds = allTransactionTagIds;
|
||||
self.tagFilterType = self.statisticsStore.transactionStatisticsFilter.tagFilterType;
|
||||
} else if (self.type === 'transactionListCurrent') {
|
||||
for (const transactionTagId in self.transactionsStore.allFilterTagIds) {
|
||||
if (!Object.prototype.hasOwnProperty.call(self.transactionsStore.allFilterTagIds, transactionTagId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const transactionTag = self.transactionTagsStore.allTransactionTagsMap[transactionTagId];
|
||||
|
||||
if (transactionTag) {
|
||||
allTransactionTagIds[transactionTag.id] = false;
|
||||
}
|
||||
}
|
||||
self.filterTagIds = allTransactionTagIds;
|
||||
} else {
|
||||
self.$toast('Parameter Invalid');
|
||||
self.loadingError = 'Parameter Invalid';
|
||||
}
|
||||
}).catch(error => {
|
||||
if (error.processed) {
|
||||
self.loading = false;
|
||||
} else {
|
||||
self.loadingError = error;
|
||||
self.$toast(error.message || error);
|
||||
}
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
onPageAfterIn() {
|
||||
this.$routeBackOnError(this.f7router, 'loadingError');
|
||||
},
|
||||
save() {
|
||||
const self = this;
|
||||
const router = self.f7router;
|
||||
|
||||
const filteredTagIds = {};
|
||||
let finalTagIds = '';
|
||||
let changed = true;
|
||||
|
||||
for (const transactionTagId in self.filterTagIds) {
|
||||
if (!Object.prototype.hasOwnProperty.call(self.filterTagIds, transactionTagId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const transactionTag = self.transactionTagsStore.allTransactionTagsMap[transactionTagId];
|
||||
|
||||
if (self.filterTagIds[transactionTag.id]) {
|
||||
filteredTagIds[transactionTag.id] = true;
|
||||
} else {
|
||||
if (finalTagIds.length > 0) {
|
||||
finalTagIds += ',';
|
||||
}
|
||||
|
||||
finalTagIds += transactionTag.id;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.type === 'statisticsCurrent') {
|
||||
changed = self.statisticsStore.updateTransactionStatisticsFilter({
|
||||
tagIds: finalTagIds,
|
||||
tagFilterType: self.tagFilterType
|
||||
});
|
||||
|
||||
if (changed) {
|
||||
self.statisticsStore.updateTransactionStatisticsInvalidState(true);
|
||||
}
|
||||
} else if (this.type === 'transactionListCurrent') {
|
||||
changed = self.transactionsStore.updateTransactionListFilter({
|
||||
tagIds: finalTagIds
|
||||
});
|
||||
|
||||
if (changed) {
|
||||
self.transactionsStore.updateTransactionListInvalidState(true);
|
||||
}
|
||||
}
|
||||
|
||||
router.back();
|
||||
},
|
||||
selectTransactionTag(e) {
|
||||
const transactionTagId = e.target.value;
|
||||
const transactionTag = this.transactionTagsStore.allTransactionTagsMap[transactionTagId];
|
||||
|
||||
if (!transactionTag) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.filterTagIds[transactionTag.id] = !e.target.checked;
|
||||
},
|
||||
selectAll() {
|
||||
selectAll(this.filterTagIds, this.transactionTagsStore.allTransactionTagsMap);
|
||||
},
|
||||
selectNone() {
|
||||
selectNone(this.filterTagIds, this.transactionTagsStore.allTransactionTagsMap);
|
||||
},
|
||||
selectInvert() {
|
||||
selectInvert(this.filterTagIds, this.transactionTagsStore.allTransactionTagsMap);
|
||||
}
|
||||
}
|
||||
interface CollapseState {
|
||||
opened: boolean;
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
f7route: Router.Route;
|
||||
f7router: Router.Router;
|
||||
}>();
|
||||
|
||||
const query = props.f7route.query;
|
||||
|
||||
const { tt } = useI18n();
|
||||
const { showToast, routeBackOnError } = useI18nUIComponents();
|
||||
|
||||
const {
|
||||
loading,
|
||||
showHidden,
|
||||
filterTagIds,
|
||||
tagFilterType,
|
||||
title,
|
||||
applyText,
|
||||
allTags,
|
||||
allTagFilterTypes,
|
||||
hasAnyAvailableTag,
|
||||
hasAnyVisibleTag,
|
||||
loadFilterTagIds,
|
||||
saveFilterTagIds
|
||||
} = useTransactionTagFilterSettingPageBase(query['type']);
|
||||
|
||||
const transactionTagsStore = useTransactionTagsStore();
|
||||
|
||||
const loadingError = ref<unknown | null>(null);
|
||||
const showMoreActionSheet = ref<boolean>(false);
|
||||
|
||||
const collapseStates = ref<Record<string, CollapseState>>({
|
||||
default: {
|
||||
opened: true
|
||||
}
|
||||
});
|
||||
|
||||
function init(): void {
|
||||
transactionTagsStore.loadAllTags({
|
||||
force: false
|
||||
}).then(() => {
|
||||
loading.value = false;
|
||||
|
||||
if (!loadFilterTagIds()) {
|
||||
showToast('Parameter Invalid');
|
||||
loadingError.value = 'Parameter Invalid';
|
||||
}
|
||||
}).catch(error => {
|
||||
if (error.processed) {
|
||||
loading.value = false;
|
||||
} else {
|
||||
loadingError.value = error;
|
||||
showToast(error.message || error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function updateTransactionTagSelected(e: Event): void {
|
||||
const target = e.target as HTMLInputElement;
|
||||
const transactionTagId = target.value;
|
||||
const transactionTag = transactionTagsStore.allTransactionTagsMap[transactionTagId];
|
||||
|
||||
if (!transactionTag) {
|
||||
return;
|
||||
}
|
||||
|
||||
filterTagIds.value[transactionTag.id] = !target.checked;
|
||||
}
|
||||
|
||||
function selectAllTransactionTags(): void {
|
||||
selectAll(filterTagIds.value, transactionTagsStore.allTransactionTagsMap);
|
||||
}
|
||||
|
||||
function selectNoneTransactionTags(): void {
|
||||
selectNone(filterTagIds.value, transactionTagsStore.allTransactionTagsMap);
|
||||
}
|
||||
|
||||
function selectInvertTransactionTags(): void {
|
||||
selectInvert(filterTagIds.value, transactionTagsStore.allTransactionTagsMap);
|
||||
}
|
||||
|
||||
function save(): void {
|
||||
saveFilterTagIds();
|
||||
props.f7router.back();
|
||||
}
|
||||
|
||||
function onPageAfterIn(): void {
|
||||
routeBackOnError(props.f7router, loadingError);
|
||||
}
|
||||
|
||||
init();
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user