mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-18 00:34:28 +08:00
migrate transaction tag filter page to composition API and typescript
This commit is contained in:
@@ -0,0 +1,151 @@
|
|||||||
|
import { ref, computed } from 'vue';
|
||||||
|
|
||||||
|
import { useI18n } from '@/locales/helpers.ts';
|
||||||
|
|
||||||
|
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
||||||
|
import { useTransactionsStore } from '@/stores/transaction.ts';
|
||||||
|
import { useStatisticsStore } from '@/stores/statistics.ts';
|
||||||
|
|
||||||
|
import type { TypeAndDisplayName } from '@/core/base.ts';
|
||||||
|
import { TransactionTagFilterType } from '@/core/transaction.ts';
|
||||||
|
import type { TransactionTag } from '@/models/transaction_tag.ts';
|
||||||
|
|
||||||
|
export function useTransactionTagFilterSettingPageBase(type?: string) {
|
||||||
|
const { getAllTransactionTagFilterTypes } = useI18n();
|
||||||
|
|
||||||
|
const transactionTagsStore = useTransactionTagsStore();
|
||||||
|
const transactionsStore = useTransactionsStore();
|
||||||
|
const statisticsStore = useStatisticsStore();
|
||||||
|
|
||||||
|
const loading = ref<boolean>(true);
|
||||||
|
const showHidden = ref<boolean>(false);
|
||||||
|
const filterTagIds = ref<Record<string, boolean>>({});
|
||||||
|
const tagFilterType = ref<number>(TransactionTagFilterType.Default.type);
|
||||||
|
|
||||||
|
const title = computed<string>(() => {
|
||||||
|
return 'Filter Transaction Tags';
|
||||||
|
});
|
||||||
|
|
||||||
|
const applyText = computed<string>(() => {
|
||||||
|
return 'Apply';
|
||||||
|
});
|
||||||
|
|
||||||
|
const allTags = computed<TransactionTag[]>(() => transactionTagsStore.allTransactionTags);
|
||||||
|
const allTagFilterTypes = computed<TypeAndDisplayName[]>(() => getAllTransactionTagFilterTypes());
|
||||||
|
const hasAnyAvailableTag = computed<boolean>(() => transactionTagsStore.allAvailableTagsCount > 0);
|
||||||
|
const hasAnyVisibleTag = computed<boolean>(() => {
|
||||||
|
if (showHidden.value) {
|
||||||
|
return transactionTagsStore.allAvailableTagsCount > 0;
|
||||||
|
} else {
|
||||||
|
return transactionTagsStore.allVisibleTagsCount > 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function loadFilterTagIds(): boolean {
|
||||||
|
const allTransactionTagIds: Record<string, boolean> = {};
|
||||||
|
|
||||||
|
for (const transactionTagId in transactionTagsStore.allTransactionTagsMap) {
|
||||||
|
if (!Object.prototype.hasOwnProperty.call(transactionTagsStore.allTransactionTagsMap, transactionTagId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const transactionTag = transactionTagsStore.allTransactionTagsMap[transactionTagId];
|
||||||
|
allTransactionTagIds[transactionTag.id] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'statisticsCurrent') {
|
||||||
|
const transactionTagIds = statisticsStore.transactionStatisticsFilter.tagIds ? statisticsStore.transactionStatisticsFilter.tagIds.split(',') : [];
|
||||||
|
|
||||||
|
for (let i = 0; i < transactionTagIds.length; i++) {
|
||||||
|
const transactionTagId = transactionTagIds[i];
|
||||||
|
const transactionTag = transactionTagsStore.allTransactionTagsMap[transactionTagId];
|
||||||
|
|
||||||
|
if (transactionTag) {
|
||||||
|
allTransactionTagIds[transactionTag.id] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filterTagIds.value = allTransactionTagIds;
|
||||||
|
tagFilterType.value = statisticsStore.transactionStatisticsFilter.tagFilterType;
|
||||||
|
return true;
|
||||||
|
} else if (type === 'transactionListCurrent') {
|
||||||
|
for (const transactionTagId in transactionsStore.allFilterTagIds) {
|
||||||
|
if (!Object.prototype.hasOwnProperty.call(transactionsStore.allFilterTagIds, transactionTagId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const transactionTag = transactionTagsStore.allTransactionTagsMap[transactionTagId];
|
||||||
|
|
||||||
|
if (transactionTag) {
|
||||||
|
allTransactionTagIds[transactionTag.id] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filterTagIds.value = allTransactionTagIds;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveFilterTagIds(): boolean {
|
||||||
|
const filteredTagIds: Record<string, boolean> = {};
|
||||||
|
let finalTagIds = '';
|
||||||
|
let changed = true;
|
||||||
|
|
||||||
|
for (const transactionTagId in filterTagIds.value) {
|
||||||
|
if (!Object.prototype.hasOwnProperty.call(filterTagIds.value, transactionTagId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const transactionTag = transactionTagsStore.allTransactionTagsMap[transactionTagId];
|
||||||
|
|
||||||
|
if (filterTagIds.value[transactionTag.id]) {
|
||||||
|
filteredTagIds[transactionTag.id] = true;
|
||||||
|
} else {
|
||||||
|
if (finalTagIds.length > 0) {
|
||||||
|
finalTagIds += ',';
|
||||||
|
}
|
||||||
|
|
||||||
|
finalTagIds += transactionTag.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'statisticsCurrent') {
|
||||||
|
changed = statisticsStore.updateTransactionStatisticsFilter({
|
||||||
|
tagIds: finalTagIds,
|
||||||
|
tagFilterType: tagFilterType.value
|
||||||
|
});
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
statisticsStore.updateTransactionStatisticsInvalidState(true);
|
||||||
|
}
|
||||||
|
} else if (type === 'transactionListCurrent') {
|
||||||
|
changed = transactionsStore.updateTransactionListFilter({
|
||||||
|
tagIds: finalTagIds
|
||||||
|
});
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
transactionsStore.updateTransactionListInvalidState(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
// states
|
||||||
|
loading,
|
||||||
|
showHidden,
|
||||||
|
filterTagIds,
|
||||||
|
tagFilterType,
|
||||||
|
// computed states
|
||||||
|
title,
|
||||||
|
applyText,
|
||||||
|
allTags,
|
||||||
|
allTagFilterTypes,
|
||||||
|
hasAnyAvailableTag,
|
||||||
|
hasAnyVisibleTag,
|
||||||
|
// functions
|
||||||
|
loadFilterTagIds,
|
||||||
|
saveFilterTagIds
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<template #title>
|
<template #title>
|
||||||
<div class="d-flex align-center justify-center" v-if="dialogMode">
|
<div class="d-flex align-center justify-center" v-if="dialogMode">
|
||||||
<div class="w-100 text-center">
|
<div class="w-100 text-center">
|
||||||
<h4 class="text-h4">{{ $t(title) }}</h4>
|
<h4 class="text-h4">{{ tt(title) }}</h4>
|
||||||
</div>
|
</div>
|
||||||
<v-btn density="comfortable" color="default" variant="text" class="ml-2"
|
<v-btn density="comfortable" color="default" variant="text" class="ml-2"
|
||||||
:disabled="loading || !hasAnyAvailableTag" :icon="true">
|
:disabled="loading || !hasAnyAvailableTag" :icon="true">
|
||||||
@@ -11,30 +11,30 @@
|
|||||||
<v-menu activator="parent">
|
<v-menu activator="parent">
|
||||||
<v-list>
|
<v-list>
|
||||||
<v-list-item :prepend-icon="icons.selectAll"
|
<v-list-item :prepend-icon="icons.selectAll"
|
||||||
:title="$t('Select All')"
|
:title="tt('Select All')"
|
||||||
:disabled="!hasAnyVisibleTag"
|
:disabled="!hasAnyVisibleTag"
|
||||||
@click="selectAll"></v-list-item>
|
@click="selectAllTransactionTags"></v-list-item>
|
||||||
<v-list-item :prepend-icon="icons.selectNone"
|
<v-list-item :prepend-icon="icons.selectNone"
|
||||||
:title="$t('Select None')"
|
:title="tt('Select None')"
|
||||||
:disabled="!hasAnyVisibleTag"
|
:disabled="!hasAnyVisibleTag"
|
||||||
@click="selectNone"></v-list-item>
|
@click="selectNoneTransactionTags"></v-list-item>
|
||||||
<v-list-item :prepend-icon="icons.selectInverse"
|
<v-list-item :prepend-icon="icons.selectInverse"
|
||||||
:title="$t('Invert Selection')"
|
:title="tt('Invert Selection')"
|
||||||
:disabled="!hasAnyVisibleTag"
|
:disabled="!hasAnyVisibleTag"
|
||||||
@click="selectInvert"></v-list-item>
|
@click="selectInvertTransactionTags"></v-list-item>
|
||||||
<v-divider class="my-2"/>
|
<v-divider class="my-2"/>
|
||||||
<v-list-item :prepend-icon="icons.show"
|
<v-list-item :prepend-icon="icons.show"
|
||||||
:title="$t('Show Hidden Transaction Tags')"
|
:title="tt('Show Hidden Transaction Tags')"
|
||||||
v-if="!showHidden" @click="showHidden = true"></v-list-item>
|
v-if="!showHidden" @click="showHidden = true"></v-list-item>
|
||||||
<v-list-item :prepend-icon="icons.hide"
|
<v-list-item :prepend-icon="icons.hide"
|
||||||
:title="$t('Hide Hidden Transaction Tags')"
|
:title="tt('Hide Hidden Transaction Tags')"
|
||||||
v-if="showHidden" @click="showHidden = false"></v-list-item>
|
v-if="showHidden" @click="showHidden = false"></v-list-item>
|
||||||
</v-list>
|
</v-list>
|
||||||
</v-menu>
|
</v-menu>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex align-center" v-else-if="!dialogMode">
|
<div class="d-flex align-center" v-else-if="!dialogMode">
|
||||||
<span>{{ $t(title) }}</span>
|
<span>{{ tt(title) }}</span>
|
||||||
<v-spacer/>
|
<v-spacer/>
|
||||||
<v-btn density="comfortable" color="default" variant="text" class="ml-2"
|
<v-btn density="comfortable" color="default" variant="text" class="ml-2"
|
||||||
:disabled="loading" :icon="true">
|
:disabled="loading" :icon="true">
|
||||||
@@ -42,23 +42,23 @@
|
|||||||
<v-menu activator="parent">
|
<v-menu activator="parent">
|
||||||
<v-list>
|
<v-list>
|
||||||
<v-list-item :prepend-icon="icons.selectAll"
|
<v-list-item :prepend-icon="icons.selectAll"
|
||||||
:title="$t('Select All')"
|
:title="tt('Select All')"
|
||||||
:disabled="!hasAnyVisibleTag"
|
:disabled="!hasAnyVisibleTag"
|
||||||
@click="selectAll"></v-list-item>
|
@click="selectAllTransactionTags"></v-list-item>
|
||||||
<v-list-item :prepend-icon="icons.selectNone"
|
<v-list-item :prepend-icon="icons.selectNone"
|
||||||
:title="$t('Select None')"
|
:title="tt('Select None')"
|
||||||
:disabled="!hasAnyVisibleTag"
|
:disabled="!hasAnyVisibleTag"
|
||||||
@click="selectNone"></v-list-item>
|
@click="selectNoneTransactionTags"></v-list-item>
|
||||||
<v-list-item :prepend-icon="icons.selectInverse"
|
<v-list-item :prepend-icon="icons.selectInverse"
|
||||||
:title="$t('Invert Selection')"
|
:title="tt('Invert Selection')"
|
||||||
:disabled="!hasAnyVisibleTag"
|
:disabled="!hasAnyVisibleTag"
|
||||||
@click="selectInvert"></v-list-item>
|
@click="selectInvertTransactionTags"></v-list-item>
|
||||||
<v-divider class="my-2"/>
|
<v-divider class="my-2"/>
|
||||||
<v-list-item :prepend-icon="icons.show"
|
<v-list-item :prepend-icon="icons.show"
|
||||||
:title="$t('Show Hidden Transaction Tags')"
|
:title="tt('Show Hidden Transaction Tags')"
|
||||||
v-if="!showHidden" @click="showHidden = true"></v-list-item>
|
v-if="!showHidden" @click="showHidden = true"></v-list-item>
|
||||||
<v-list-item :prepend-icon="icons.hide"
|
<v-list-item :prepend-icon="icons.hide"
|
||||||
:title="$t('Hide Hidden Transaction Tags')"
|
:title="tt('Hide Hidden Transaction Tags')"
|
||||||
v-if="showHidden" @click="showHidden = false"></v-list-item>
|
v-if="showHidden" @click="showHidden = false"></v-list-item>
|
||||||
</v-list>
|
</v-list>
|
||||||
</v-menu>
|
</v-menu>
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<v-card-text :class="{ 'mt-0 mt-sm-2 mt-md-4': dialogMode }" v-if="!loading && !hasAnyVisibleTag">
|
<v-card-text :class="{ 'mt-0 mt-sm-2 mt-md-4': dialogMode }" v-if="!loading && !hasAnyVisibleTag">
|
||||||
<span class="text-body-1">{{ $t('No available tag') }}</span>
|
<span class="text-body-1">{{ tt('No available tag') }}</span>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
|
|
||||||
<v-card-text :class="{ 'mt-0 mt-sm-2 mt-md-4': dialogMode }" v-else-if="!loading && hasAnyVisibleTag">
|
<v-card-text :class="{ 'mt-0 mt-sm-2 mt-md-4': dialogMode }" v-else-if="!loading && hasAnyVisibleTag">
|
||||||
@@ -80,7 +80,7 @@
|
|||||||
<v-btn border class="justify-start" :key="filterType.type"
|
<v-btn border class="justify-start" :key="filterType.type"
|
||||||
:color="tagFilterType === filterType.type ? 'primary' : 'default'"
|
:color="tagFilterType === filterType.type ? 'primary' : 'default'"
|
||||||
:variant="tagFilterType === filterType.type ? 'tonal' : 'outlined'"
|
:variant="tagFilterType === filterType.type ? 'tonal' : 'outlined'"
|
||||||
:append-icon="(tagFilterType === filterType.type ? icons.check : null)"
|
:append-icon="(tagFilterType === filterType.type ? icons.check : undefined)"
|
||||||
v-for="filterType in allTagFilterTypes"
|
v-for="filterType in allTagFilterTypes"
|
||||||
@click="tagFilterType = filterType.type">
|
@click="tagFilterType = filterType.type">
|
||||||
{{ filterType.displayName }}
|
{{ filterType.displayName }}
|
||||||
@@ -90,7 +90,7 @@
|
|||||||
<v-expansion-panels class="tag-categories" multiple v-model="expandTagCategories">
|
<v-expansion-panels class="tag-categories" multiple v-model="expandTagCategories">
|
||||||
<v-expansion-panel class="border" key="default" value="default">
|
<v-expansion-panel class="border" key="default" value="default">
|
||||||
<v-expansion-panel-title class="expand-panel-title-with-bg py-0">
|
<v-expansion-panel-title class="expand-panel-title-with-bg py-0">
|
||||||
<span class="ml-3">{{ $t('Tags') }}</span>
|
<span class="ml-3">{{ tt('Tags') }}</span>
|
||||||
</v-expansion-panel-title>
|
</v-expansion-panel-title>
|
||||||
<v-expansion-panel-text>
|
<v-expansion-panel-text>
|
||||||
<v-list rounded density="comfortable" class="pa-0">
|
<v-list rounded density="comfortable" class="pa-0">
|
||||||
@@ -99,7 +99,7 @@
|
|||||||
<v-list-item v-if="showHidden || !transactionTag.hidden">
|
<v-list-item v-if="showHidden || !transactionTag.hidden">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<v-checkbox :model-value="!filterTagIds[transactionTag.id]"
|
<v-checkbox :model-value="!filterTagIds[transactionTag.id]"
|
||||||
@update:model-value="selectTransactionTag(transactionTag, $event)">
|
@update:model-value="updateTransactionTagSelected(transactionTag, $event)">
|
||||||
<template #label>
|
<template #label>
|
||||||
<v-badge class="right-bottom-icon" color="secondary"
|
<v-badge class="right-bottom-icon" color="secondary"
|
||||||
location="bottom right" offset-x="2" offset-y="2" :icon="icons.hide"
|
location="bottom right" offset-x="2" offset-y="2" :icon="icons.hide"
|
||||||
@@ -121,8 +121,8 @@
|
|||||||
|
|
||||||
<v-card-text class="overflow-y-visible" v-if="dialogMode">
|
<v-card-text class="overflow-y-visible" v-if="dialogMode">
|
||||||
<div class="w-100 d-flex justify-center mt-2 mt-sm-4 mt-md-6 gap-4">
|
<div class="w-100 d-flex justify-center mt-2 mt-sm-4 mt-md-6 gap-4">
|
||||||
<v-btn :disabled="!hasAnyVisibleTag" @click="save">{{ $t(applyText) }}</v-btn>
|
<v-btn :disabled="!hasAnyVisibleTag" @click="save">{{ tt(applyText) }}</v-btn>
|
||||||
<v-btn color="secondary" variant="tonal" @click="cancel">{{ $t('Cancel') }}</v-btn>
|
<v-btn color="secondary" variant="tonal" @click="cancel">{{ tt('Cancel') }}</v-btn>
|
||||||
</div>
|
</div>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
</v-card>
|
</v-card>
|
||||||
@@ -130,13 +130,17 @@
|
|||||||
<snack-bar ref="snackbar" />
|
<snack-bar ref="snackbar" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import { mapStores } from 'pinia';
|
import SnackBar from '@/components/desktop/SnackBar.vue';
|
||||||
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
|
||||||
import { useTransactionsStore } from '@/stores/transaction.ts';
|
|
||||||
import { useStatisticsStore } from '@/stores/statistics.ts';
|
|
||||||
|
|
||||||
import { TransactionTagFilterType } from '@/core/transaction.ts';
|
import { ref, useTemplateRef } from 'vue';
|
||||||
|
|
||||||
|
import { useI18n } from '@/locales/helpers.ts';
|
||||||
|
import { useTransactionTagFilterSettingPageBase } from '@/views/base/settings/TransactionTagFilterSettingPageBase.ts';
|
||||||
|
|
||||||
|
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
||||||
|
|
||||||
|
import type { TransactionTag } from '@/models/transaction_tag.ts';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
selectAll,
|
selectAll,
|
||||||
@@ -155,195 +159,112 @@ import {
|
|||||||
mdiPound
|
mdiPound
|
||||||
} from '@mdi/js';
|
} from '@mdi/js';
|
||||||
|
|
||||||
export default {
|
type SnackBarType = InstanceType<typeof SnackBar>;
|
||||||
props: [
|
|
||||||
'dialogMode',
|
const props = defineProps<{
|
||||||
'type',
|
type: string;
|
||||||
'autoSave'
|
dialogMode?: boolean;
|
||||||
],
|
autoSave?: boolean;
|
||||||
emits: [
|
}>();
|
||||||
'settings:change'
|
|
||||||
],
|
const emit = defineEmits<{
|
||||||
data: function () {
|
(e: 'settings:change', changed: boolean): void;
|
||||||
return {
|
}>();
|
||||||
loading: true,
|
|
||||||
expandTagCategories: [ 'default' ],
|
const { tt } = useI18n();
|
||||||
filterTagIds: {},
|
|
||||||
tagFilterType: TransactionTagFilterType.Default.type,
|
const {
|
||||||
showHidden: false,
|
loading,
|
||||||
icons: {
|
showHidden,
|
||||||
selectAll: mdiSelectAll,
|
filterTagIds,
|
||||||
selectNone: mdiSelect,
|
tagFilterType,
|
||||||
selectInverse: mdiSelectInverse,
|
title,
|
||||||
show: mdiEyeOutline,
|
applyText,
|
||||||
hide: mdiEyeOffOutline,
|
allTags,
|
||||||
more: mdiDotsVertical,
|
allTagFilterTypes,
|
||||||
check: mdiCheck,
|
hasAnyAvailableTag,
|
||||||
tag: mdiPound
|
hasAnyVisibleTag,
|
||||||
}
|
loadFilterTagIds,
|
||||||
|
saveFilterTagIds
|
||||||
|
} = useTransactionTagFilterSettingPageBase(props.type);
|
||||||
|
|
||||||
|
const transactionTagsStore = useTransactionTagsStore();
|
||||||
|
|
||||||
|
const icons = {
|
||||||
|
selectAll: mdiSelectAll,
|
||||||
|
selectNone: mdiSelect,
|
||||||
|
selectInverse: mdiSelectInverse,
|
||||||
|
show: mdiEyeOutline,
|
||||||
|
hide: mdiEyeOffOutline,
|
||||||
|
more: mdiDotsVertical,
|
||||||
|
check: mdiCheck,
|
||||||
|
tag: mdiPound
|
||||||
|
};
|
||||||
|
|
||||||
|
const snackbar = useTemplateRef<SnackBarType>('snackbar');
|
||||||
|
|
||||||
|
const expandTagCategories = ref<string[]>([ 'default' ]);
|
||||||
|
|
||||||
|
function init(): void {
|
||||||
|
transactionTagsStore.loadAllTags({
|
||||||
|
force: false
|
||||||
|
}).then(() => {
|
||||||
|
loading.value = false;
|
||||||
|
|
||||||
|
if (!loadFilterTagIds()) {
|
||||||
|
snackbar.value?.showError('Parameter Invalid');
|
||||||
}
|
}
|
||||||
},
|
}).catch(error => {
|
||||||
computed: {
|
loading.value = false;
|
||||||
...mapStores(useTransactionTagsStore, useTransactionsStore, useStatisticsStore),
|
|
||||||
title() {
|
if (!error.processed) {
|
||||||
return 'Filter Transaction Tags';
|
snackbar.value?.showError(error);
|
||||||
},
|
|
||||||
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;
|
|
||||||
|
|
||||||
self.transactionTagsStore.loadAllTags({
|
function updateTransactionTagSelected(transactionTag: TransactionTag, value: boolean | null): void {
|
||||||
force: false
|
filterTagIds.value[transactionTag.id] = !value;
|
||||||
}).then(() => {
|
|
||||||
self.loading = false;
|
|
||||||
|
|
||||||
const allTransactionTagIds = {};
|
if (props.autoSave) {
|
||||||
|
save();
|
||||||
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.$refs.snackbar.showError('Parameter Invalid');
|
|
||||||
}
|
|
||||||
}).catch(error => {
|
|
||||||
self.loading = false;
|
|
||||||
|
|
||||||
if (!error.processed) {
|
|
||||||
self.$refs.snackbar.showError(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
save() {
|
|
||||||
const self = this;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.$emit('settings:change', changed);
|
|
||||||
},
|
|
||||||
cancel() {
|
|
||||||
this.$emit('settings:change', false);
|
|
||||||
},
|
|
||||||
selectTransactionTag(transactionTag, value) {
|
|
||||||
this.filterTagIds[transactionTag.id] = !value;
|
|
||||||
|
|
||||||
if (this.autoSave) {
|
|
||||||
this.save();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
selectAll() {
|
|
||||||
selectAll(this.filterTagIds, this.transactionTagsStore.allTransactionTagsMap);
|
|
||||||
|
|
||||||
if (this.autoSave) {
|
|
||||||
this.save();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
selectNone() {
|
|
||||||
selectNone(this.filterTagIds, this.transactionTagsStore.allTransactionTagsMap);
|
|
||||||
|
|
||||||
if (this.autoSave) {
|
|
||||||
this.save();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
selectInvert() {
|
|
||||||
selectInvert(this.filterTagIds, this.transactionTagsStore.allTransactionTagsMap);
|
|
||||||
|
|
||||||
if (this.autoSave) {
|
|
||||||
this.save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function selectAllTransactionTags(): void {
|
||||||
|
selectAll(filterTagIds.value, transactionTagsStore.allTransactionTagsMap);
|
||||||
|
|
||||||
|
if (props.autoSave) {
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectNoneTransactionTags(): void {
|
||||||
|
selectNone(filterTagIds.value, transactionTagsStore.allTransactionTagsMap);
|
||||||
|
|
||||||
|
if (props.autoSave) {
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectInvertTransactionTags(): void {
|
||||||
|
selectInvert(filterTagIds.value, transactionTagsStore.allTransactionTagsMap);
|
||||||
|
|
||||||
|
if (props.autoSave) {
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function save(): void {
|
||||||
|
const changed = saveFilterTagIds();
|
||||||
|
emit('settings:change', changed);
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancel(): void {
|
||||||
|
emit('settings:change', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
init();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<f7-page @page:afterin="onPageAfterIn">
|
<f7-page @page:afterin="onPageAfterIn">
|
||||||
<f7-navbar>
|
<f7-navbar>
|
||||||
<f7-nav-left :back-link="$t('Back')"></f7-nav-left>
|
<f7-nav-left :back-link="tt('Back')"></f7-nav-left>
|
||||||
<f7-nav-title :title="$t(title)"></f7-nav-title>
|
<f7-nav-title :title="tt(title)"></f7-nav-title>
|
||||||
<f7-nav-right>
|
<f7-nav-right>
|
||||||
<f7-link icon-f7="ellipsis" :class="{ 'disabled': !hasAnyAvailableTag }" @click="showMoreActionSheet = true"></f7-link>
|
<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-nav-right>
|
||||||
</f7-navbar>
|
</f7-navbar>
|
||||||
|
|
||||||
@@ -38,11 +38,11 @@
|
|||||||
</f7-block>
|
</f7-block>
|
||||||
|
|
||||||
<f7-list strong inset dividers accordion-list class="margin-top" v-if="!loading && !hasAnyVisibleTag">
|
<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-list>
|
||||||
|
|
||||||
<f7-block class="combination-list-wrapper margin-vertical" key="default" v-show="!loading && hasAnyVisibleTag">
|
<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
|
<f7-list-item radio
|
||||||
:title="filterType.displayName"
|
:title="filterType.displayName"
|
||||||
:value="filterType.type"
|
:value="filterType.type"
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
:class="collapseStates['default'].opened ? 'combination-list-opened' : 'combination-list-closed'">
|
:class="collapseStates['default'].opened ? 'combination-list-opened' : 'combination-list-closed'">
|
||||||
<f7-list-item>
|
<f7-list-item>
|
||||||
<template #title>
|
<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>
|
<f7-icon class="combination-list-chevron-icon" :f7="collapseStates['default'].opened ? 'chevron_up' : 'chevron_down'"></f7-icon>
|
||||||
</template>
|
</template>
|
||||||
</f7-list-item>
|
</f7-list-item>
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
:key="transactionTag.id"
|
:key="transactionTag.id"
|
||||||
v-for="transactionTag in allTags"
|
v-for="transactionTag in allTags"
|
||||||
v-show="showHidden || !transactionTag.hidden"
|
v-show="showHidden || !transactionTag.hidden"
|
||||||
@change="selectTransactionTag">
|
@change="updateTransactionTagSelected">
|
||||||
<template #media>
|
<template #media>
|
||||||
<f7-icon class="transaction-tag-icon" f7="number">
|
<f7-icon class="transaction-tag-icon" f7="number">
|
||||||
<f7-badge color="gray" class="right-bottom-icon" v-if="transactionTag.hidden">
|
<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 close-by-outside-click close-on-escape :opened="showMoreActionSheet" @actions:closed="showMoreActionSheet = false">
|
||||||
<f7-actions-group>
|
<f7-actions-group>
|
||||||
<f7-actions-button :class="{ 'disabled': !hasAnyVisibleTag }" @click="selectAll">{{ $t('Select All') }}</f7-actions-button>
|
<f7-actions-button :class="{ 'disabled': !hasAnyVisibleTag }" @click="selectAllTransactionTags">{{ tt('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="selectNoneTransactionTags">{{ tt('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="selectInvertTransactionTags">{{ tt('Invert Selection') }}</f7-actions-button>
|
||||||
</f7-actions-group>
|
</f7-actions-group>
|
||||||
<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 = true">{{ tt('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 = false">{{ tt('Hide Hidden Transaction Tags') }}</f7-actions-button>
|
||||||
</f7-actions-group>
|
</f7-actions-group>
|
||||||
<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-group>
|
||||||
</f7-actions>
|
</f7-actions>
|
||||||
</f7-page>
|
</f7-page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import { mapStores } from 'pinia';
|
import { ref } from 'vue';
|
||||||
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
import type { Router } from 'framework7/types';
|
||||||
import { useTransactionsStore } from '@/stores/transaction.ts';
|
|
||||||
import { useStatisticsStore } from '@/stores/statistics.ts';
|
|
||||||
|
|
||||||
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 {
|
import {
|
||||||
selectAll,
|
selectAll,
|
||||||
@@ -124,183 +126,98 @@ import {
|
|||||||
selectInvert
|
selectInvert
|
||||||
} from '@/lib/common.ts';
|
} from '@/lib/common.ts';
|
||||||
|
|
||||||
export default {
|
interface CollapseState {
|
||||||
props: [
|
opened: boolean;
|
||||||
'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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user