mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-15 15:37:33 +08:00
support transaction tag group
This commit is contained in:
@@ -49,53 +49,46 @@
|
||||
<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="includeTagsCount > 1">
|
||||
<f7-list-item radio
|
||||
:title="tt(filterType.name)"
|
||||
:key="filterType.type"
|
||||
:value="filterType.type"
|
||||
:checked="includeTagFilterType === filterType.type"
|
||||
v-for="filterType in [TransactionTagFilterType.HasAny, TransactionTagFilterType.HasAll]"
|
||||
@change="includeTagFilterType = filterType.type">
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
|
||||
<f7-list class="margin-top-half margin-bottom" strong inset dividers v-if="excludeTagsCount > 1">
|
||||
<f7-list-item radio
|
||||
:title="tt(filterType.name)"
|
||||
:key="filterType.type"
|
||||
:value="filterType.type"
|
||||
:checked="excludeTagFilterType === filterType.type"
|
||||
v-for="filterType in [TransactionTagFilterType.NotHasAny, TransactionTagFilterType.NotHasAll]"
|
||||
@change="excludeTagFilterType = filterType.type">
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
|
||||
<f7-accordion-item :opened="collapseStates['default']!.opened"
|
||||
@accordion:open="collapseStates['default']!.opened = true"
|
||||
@accordion:close="collapseStates['default']!.opened = false">
|
||||
<f7-block class="combination-list-wrapper margin-vertical"
|
||||
:key="tagGroup.id" v-for="tagGroup in allTagGroupsWithDefault"
|
||||
v-show="!loading && hasAnyVisibleTag">
|
||||
<f7-accordion-item :opened="collapseStates[tagGroup.id]?.opened ?? true"
|
||||
@accordion:open="collapseStates[tagGroup.id]!.opened = true"
|
||||
@accordion:close="collapseStates[tagGroup.id]!.opened = false"
|
||||
v-if="allVisibleTags[tagGroup.id] && allVisibleTags[tagGroup.id]!.length > 0">
|
||||
<f7-block-title>
|
||||
<f7-accordion-toggle>
|
||||
<f7-list strong inset dividers
|
||||
class="combination-list-header"
|
||||
:class="collapseStates['default']!.opened ? 'combination-list-opened' : 'combination-list-closed'">
|
||||
:class="collapseStates[tagGroup.id]?.opened ? 'combination-list-opened' : 'combination-list-closed'">
|
||||
<f7-list-item group-title>
|
||||
<small>{{ tt('Tags') }}</small>
|
||||
<f7-icon class="combination-list-chevron-icon" :f7="collapseStates['default']!.opened ? 'chevron_up' : 'chevron_down'"></f7-icon>
|
||||
<small class="tag-group-title">{{ tagGroup.name }}</small>
|
||||
<f7-icon class="combination-list-chevron-icon" :f7="collapseStates[tagGroup.id]?.opened ? 'chevron_up' : 'chevron_down'"></f7-icon>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
</f7-accordion-toggle>
|
||||
</f7-block-title>
|
||||
<f7-accordion-content :style="{ height: collapseStates['default']!.opened ? 'auto' : '' }">
|
||||
<f7-accordion-content :style="{ height: collapseStates[tagGroup.id]?.opened ? 'auto' : '' }">
|
||||
<f7-list strong inset dividers accordion-list class="combination-list-content">
|
||||
<f7-list-item link="#"
|
||||
popover-open=".tag-filter-include-type-popover-menu"
|
||||
:title="tt(TransactionTagFilterType.parse(groupTagFilterTypesMap[tagGroup.id]?.includeType as number)?.name as string)"
|
||||
@click="currentTransactionTagGroupId = tagGroup.id"
|
||||
v-if="groupTagFilterTypesMap[tagGroup.id] && groupTagFilterStateCountMap[tagGroup.id] && groupTagFilterStateCountMap[tagGroup.id]![TransactionTagFilterState.Include] && groupTagFilterStateCountMap[tagGroup.id]![TransactionTagFilterState.Include] > 1 && TransactionTagFilterType.parse(groupTagFilterTypesMap[tagGroup.id]?.includeType as number)">
|
||||
</f7-list-item>
|
||||
<f7-list-item link="#"
|
||||
popover-open=".tag-filter-exclude-type-popover-menu"
|
||||
:title="tt(TransactionTagFilterType.parse(groupTagFilterTypesMap[tagGroup.id]?.excludeType as number)?.name as string)"
|
||||
@click="currentTransactionTagGroupId = tagGroup.id"
|
||||
v-if="groupTagFilterTypesMap[tagGroup.id] && groupTagFilterStateCountMap[tagGroup.id] && groupTagFilterStateCountMap[tagGroup.id]![TransactionTagFilterState.Exclude] && groupTagFilterStateCountMap[tagGroup.id]![TransactionTagFilterState.Exclude] > 1 && TransactionTagFilterType.parse(groupTagFilterTypesMap[tagGroup.id]?.excludeType as number)">
|
||||
</f7-list-item>
|
||||
<f7-list-item link="#"
|
||||
popover-open=".tag-filter-state-popover-menu"
|
||||
:title="transactionTag.name"
|
||||
:value="transactionTag.id"
|
||||
:key="transactionTag.id"
|
||||
:after="tt(filterTagIds[transactionTag.id] === TransactionTagFilterState.Include ? 'Included' : filterTagIds[transactionTag.id] === TransactionTagFilterState.Exclude ? 'Excluded' : 'Default')"
|
||||
v-for="transactionTag in allVisibleTags"
|
||||
:after="tt(tagFilterStateMap[transactionTag.id] === TransactionTagFilterState.Include ? 'Included' : tagFilterStateMap[transactionTag.id] === TransactionTagFilterState.Exclude ? 'Excluded' : 'Default')"
|
||||
v-for="transactionTag in allVisibleTags[tagGroup.id]"
|
||||
v-show="showHidden || !transactionTag.hidden"
|
||||
@click="currentTransactionTagId = transactionTag.id">
|
||||
<template #media>
|
||||
@@ -111,11 +104,41 @@
|
||||
</f7-accordion-item>
|
||||
</f7-block>
|
||||
|
||||
<f7-popover class="tag-filter-include-type-popover-menu">
|
||||
<f7-list dividers>
|
||||
<f7-list-item link="#" no-chevron popover-close
|
||||
:title="tt(filterType.name)"
|
||||
:class="{ 'list-item-selected': groupTagFilterTypesMap[currentTransactionTagGroupId]?.includeType === filterType.type }"
|
||||
:key="filterType.type"
|
||||
v-for="filterType in [TransactionTagFilterType.HasAny, TransactionTagFilterType.HasAll]"
|
||||
@click="updateTransactionTagGroupIncludeType(filterType)">
|
||||
<template #after>
|
||||
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="groupTagFilterTypesMap[currentTransactionTagGroupId]?.includeType === filterType.type"></f7-icon>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
</f7-popover>
|
||||
|
||||
<f7-popover class="tag-filter-exclude-type-popover-menu">
|
||||
<f7-list dividers>
|
||||
<f7-list-item link="#" no-chevron popover-close
|
||||
:title="tt(filterType.name)"
|
||||
:class="{ 'list-item-selected': groupTagFilterTypesMap[currentTransactionTagGroupId]?.excludeType === filterType.type }"
|
||||
:key="filterType.type"
|
||||
v-for="filterType in [TransactionTagFilterType.NotHasAny, TransactionTagFilterType.NotHasAll]"
|
||||
@click="updateTransactionTagGroupExcludeType(filterType)">
|
||||
<template #after>
|
||||
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="groupTagFilterTypesMap[currentTransactionTagGroupId]?.excludeType === filterType.type"></f7-icon>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
</f7-popover>
|
||||
|
||||
<f7-popover class="tag-filter-state-popover-menu">
|
||||
<f7-list dividers>
|
||||
<f7-list-item link="#" no-chevron popover-close
|
||||
:title="state.displayName"
|
||||
:class="{ 'list-item-selected': filterTagIds[currentTransactionTagId] === state.type }"
|
||||
:class="{ 'list-item-selected': tagFilterStateMap[currentTransactionTagId] === state.type }"
|
||||
:key="state.type"
|
||||
v-for="state in [
|
||||
{ type: TransactionTagFilterState.Include, displayName: tt('Included') },
|
||||
@@ -124,7 +147,7 @@
|
||||
]"
|
||||
@click="updateCurrentTransactionTagState(state.type)">
|
||||
<template #after>
|
||||
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="filterTagIds[currentTransactionTagId] === state.type"></f7-icon>
|
||||
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="tagFilterStateMap[currentTransactionTagId] === state.type"></f7-icon>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
@@ -160,6 +183,7 @@ import {
|
||||
|
||||
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
||||
|
||||
import { values } from '@/core/base.ts';
|
||||
import { TransactionTagFilterType } from '@/core/transaction.ts';
|
||||
|
||||
interface CollapseState {
|
||||
@@ -180,13 +204,13 @@ const {
|
||||
loading,
|
||||
showHidden,
|
||||
filterContent,
|
||||
filterTagIds,
|
||||
includeTagFilterType,
|
||||
excludeTagFilterType,
|
||||
includeTagsCount,
|
||||
excludeTagsCount,
|
||||
tagFilterStateMap,
|
||||
groupTagFilterTypesMap,
|
||||
title,
|
||||
groupTagFilterStateCountMap,
|
||||
allTagGroupsWithDefault,
|
||||
allVisibleTags,
|
||||
allVisibleTagGroupIds,
|
||||
hasAnyAvailableTag,
|
||||
hasAnyVisibleTag,
|
||||
loadFilterTagIds,
|
||||
@@ -196,20 +220,30 @@ const {
|
||||
const transactionTagsStore = useTransactionTagsStore();
|
||||
|
||||
const loadingError = ref<unknown | null>(null);
|
||||
const currentTransactionTagGroupId = ref<string>('');
|
||||
const currentTransactionTagId = ref<string>('');
|
||||
const showMoreActionSheet = ref<boolean>(false);
|
||||
|
||||
const collapseStates = ref<Record<string, CollapseState>>({
|
||||
default: {
|
||||
opened: true
|
||||
const collapseStates = ref<Record<string, CollapseState>>(getInitCollapseState(allVisibleTagGroupIds.value));
|
||||
|
||||
function getInitCollapseState(tagGroupIds: string[]): Record<string, CollapseState> {
|
||||
const states: Record<string, CollapseState> = {};
|
||||
|
||||
for (const tagGroupId of tagGroupIds) {
|
||||
states[tagGroupId] = {
|
||||
opened: true
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
return states;
|
||||
}
|
||||
|
||||
function init(): void {
|
||||
transactionTagsStore.loadAllTags({
|
||||
force: false
|
||||
}).then(() => {
|
||||
loading.value = false;
|
||||
collapseStates.value = getInitCollapseState(allVisibleTagGroupIds.value);
|
||||
|
||||
if (!loadFilterTagIds()) {
|
||||
showToast('Parameter Invalid');
|
||||
@@ -225,14 +259,36 @@ function init(): void {
|
||||
});
|
||||
}
|
||||
|
||||
function updateTransactionTagGroupIncludeType(filterType: TransactionTagFilterType): void {
|
||||
const tagFilterTypes = groupTagFilterTypesMap.value[currentTransactionTagGroupId.value];
|
||||
|
||||
if (!tagFilterTypes) {
|
||||
return;
|
||||
}
|
||||
|
||||
tagFilterTypes.includeType = filterType.type;
|
||||
}
|
||||
|
||||
function updateTransactionTagGroupExcludeType(filterType: TransactionTagFilterType): void {
|
||||
const tagFilterTypes = groupTagFilterTypesMap.value[currentTransactionTagGroupId.value];
|
||||
|
||||
if (!tagFilterTypes) {
|
||||
return;
|
||||
}
|
||||
|
||||
tagFilterTypes.excludeType = filterType.type;
|
||||
}
|
||||
|
||||
function updateCurrentTransactionTagState(state: number): void {
|
||||
filterTagIds.value[currentTransactionTagId.value] = state;
|
||||
tagFilterStateMap.value[currentTransactionTagId.value] = state;
|
||||
currentTransactionTagId.value = '';
|
||||
}
|
||||
|
||||
function setAllTagsState(value: TransactionTagFilterState): void {
|
||||
for (const tag of allVisibleTags.value) {
|
||||
filterTagIds.value[tag.id] = value;
|
||||
for (const tags of values(allVisibleTags.value)) {
|
||||
for (const tag of tags) {
|
||||
tagFilterStateMap.value[tag.id] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,3 +307,10 @@ function onPageAfterIn(): void {
|
||||
|
||||
init();
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.tag-group-title {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -5,7 +5,12 @@
|
||||
<f7-nav-left v-else-if="sortable">
|
||||
<f7-link icon-f7="xmark" :class="{ 'disabled': displayOrderSaving }" @click="cancelSort"></f7-link>
|
||||
</f7-nav-left>
|
||||
<f7-nav-title :title="tt('Transaction Tags')"></f7-nav-title>
|
||||
<f7-nav-title>
|
||||
<f7-link popover-open=".tag-group-popover-menu" :class="{ 'disabled': sortable || hasEditingTag }">
|
||||
<span style="color: var(--f7-text-color)">{{ displayTagGroupName }}</span>
|
||||
<f7-icon class="page-title-bar-icon" color="gray" style="opacity: 0.5" f7="chevron_down_circle_fill"></f7-icon>
|
||||
</f7-link>
|
||||
</f7-nav-title>
|
||||
<f7-nav-right class="navbar-compact-icons">
|
||||
<f7-link icon-f7="ellipsis" :class="{ 'disabled': hasEditingTag || !tags.length || sortable }" @click="showMoreActionSheet = true"></f7-link>
|
||||
<f7-link icon-f7="plus" :class="{ 'disabled': hasEditingTag }" v-if="!sortable" @click="add"></f7-link>
|
||||
@@ -13,6 +18,22 @@
|
||||
</f7-nav-right>
|
||||
</f7-navbar>
|
||||
|
||||
<f7-popover class="tag-group-popover-menu"
|
||||
@popover:open="scrollPopoverToSelectedItem">
|
||||
<f7-list dividers>
|
||||
<f7-list-item link="#" no-chevron popover-close
|
||||
:title="tagGroup.name"
|
||||
:class="{ 'list-item-selected': activeTagGroupId === tagGroup.id }"
|
||||
:key="tagGroup.id"
|
||||
v-for="tagGroup in allTagGroupsWithDefault"
|
||||
@click="switchTagGroup(tagGroup.id)">
|
||||
<template #after>
|
||||
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="activeTagGroupId === tagGroup.id"></f7-icon>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
</f7-popover>
|
||||
|
||||
<f7-list strong inset dividers class="tag-item-list margin-top skeleton-text" v-if="loading">
|
||||
<f7-list-item :key="itemIdx" v-for="itemIdx in [ 1, 2, 3 ]">
|
||||
<template #media>
|
||||
@@ -155,18 +176,17 @@ import { ref, computed } from 'vue';
|
||||
import type { Router } from 'framework7/types';
|
||||
|
||||
import { useI18n } from '@/locales/helpers.ts';
|
||||
import { useI18nUIComponents, showLoading, hideLoading, onSwipeoutDeleted } from '@/lib/ui/mobile.ts';
|
||||
import { type Framework7Dom, useI18nUIComponents, showLoading, hideLoading, onSwipeoutDeleted } from '@/lib/ui/mobile.ts';
|
||||
import { useTagListPageBase } from '@/views/base/tags/TagListPageBase.ts';
|
||||
|
||||
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
||||
|
||||
import { TextDirection } from '@/core/text.ts';
|
||||
|
||||
import { TransactionTag } from '@/models/transaction_tag.ts';
|
||||
|
||||
import {
|
||||
isNoAvailableTag,
|
||||
getFirstShowingId,
|
||||
getLastShowingId
|
||||
} from '@/lib/tag.ts';
|
||||
import { scrollToSelectedItem } from '@/lib/ui/common.ts';
|
||||
import { getFirstShowingId, getLastShowingId } from '@/lib/tag.ts';
|
||||
|
||||
const props = defineProps<{
|
||||
f7router: Router.Router;
|
||||
@@ -175,34 +195,40 @@ const props = defineProps<{
|
||||
const { tt, getCurrentLanguageTextDirection } = useI18n();
|
||||
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
|
||||
|
||||
const {
|
||||
activeTagGroupId,
|
||||
newTag,
|
||||
editingTag,
|
||||
loading,
|
||||
showHidden,
|
||||
displayOrderModified,
|
||||
allTagGroupsWithDefault,
|
||||
tags,
|
||||
noAvailableTag,
|
||||
hasEditingTag,
|
||||
isTagModified,
|
||||
switchTagGroup,
|
||||
add,
|
||||
edit
|
||||
} = useTagListPageBase();
|
||||
|
||||
const transactionTagsStore = useTransactionTagsStore();
|
||||
|
||||
const newTag = ref<TransactionTag | null>(null);
|
||||
const editingTag = ref<TransactionTag>(TransactionTag.createNewTag());
|
||||
const loading = ref<boolean>(true);
|
||||
const loadingError = ref<unknown | null>(null);
|
||||
const showHidden = ref<boolean>(false);
|
||||
const sortable = ref<boolean>(false);
|
||||
const tagToDelete = ref<TransactionTag | null>(null);
|
||||
const showMoreActionSheet = ref<boolean>(false);
|
||||
const showDeleteActionSheet = ref<boolean>(false);
|
||||
const displayOrderModified = ref<boolean>(false);
|
||||
const displayOrderSaving = ref<boolean>(false);
|
||||
|
||||
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
|
||||
const tags = computed<TransactionTag[]>(() => transactionTagsStore.allTransactionTags);
|
||||
const firstShowingId = computed<string | null>(() => getFirstShowingId(tags.value, showHidden.value));
|
||||
const lastShowingId = computed<string | null>(() => getLastShowingId(tags.value, showHidden.value));
|
||||
const noAvailableTag = computed<boolean>(() => isNoAvailableTag(tags.value, showHidden.value));
|
||||
const hasEditingTag = computed<boolean>(() => !!(newTag.value || (editingTag.value.id && editingTag.value.id !== '')));
|
||||
|
||||
function isTagModified(tag: TransactionTag): boolean {
|
||||
if (tag.id) {
|
||||
return editingTag.value.name !== '' && editingTag.value.name !== tag.name;
|
||||
} else {
|
||||
return tag.name !== '';
|
||||
}
|
||||
}
|
||||
const displayTagGroupName = computed<string>(() => {
|
||||
const tagGroup = transactionTagsStore.allTransactionTagGroupsMap[activeTagGroupId.value];
|
||||
return tagGroup ? tagGroup.name : tt('Default Group');
|
||||
});
|
||||
|
||||
function getTagDomId(tag: TransactionTag): string {
|
||||
return 'tag_' + tag.id;
|
||||
@@ -258,15 +284,6 @@ function reload(done?: () => void): void {
|
||||
});
|
||||
}
|
||||
|
||||
function add(): void {
|
||||
newTag.value = TransactionTag.createNewTag();
|
||||
}
|
||||
|
||||
function edit(tag: TransactionTag): void {
|
||||
editingTag.value.id = tag.id;
|
||||
editingTag.value.name = tag.name;
|
||||
}
|
||||
|
||||
function save(tag: TransactionTag): void {
|
||||
showLoading();
|
||||
|
||||
@@ -368,7 +385,7 @@ function saveSortResult(): void {
|
||||
displayOrderSaving.value = true;
|
||||
showLoading();
|
||||
|
||||
transactionTagsStore.updateTagDisplayOrders().then(() => {
|
||||
transactionTagsStore.updateTagDisplayOrders(activeTagGroupId.value).then(() => {
|
||||
displayOrderSaving.value = false;
|
||||
hideLoading();
|
||||
|
||||
@@ -438,6 +455,10 @@ function onSort(event: { el: { id: string }, from: number, to: number }): void {
|
||||
});
|
||||
}
|
||||
|
||||
function scrollPopoverToSelectedItem(event: { $el: Framework7Dom }): void {
|
||||
scrollToSelectedItem(event.$el[0], '.popover-inner', '.popover-inner', 'li.list-item-selected');
|
||||
}
|
||||
|
||||
function onPageAfterIn(): void {
|
||||
if (transactionTagsStore.transactionTagListStateInvalid && !loading.value) {
|
||||
reload();
|
||||
@@ -458,4 +479,9 @@ init();
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.tag-group-popover-menu .popover-inner {
|
||||
max-height: 440px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -367,7 +367,7 @@
|
||||
<template #footer>
|
||||
<f7-block class="margin-top-half no-padding no-margin" v-if="transaction.tagIds && transaction.tagIds.length">
|
||||
<f7-chip media-text-color="var(--f7-chip-text-color)" class="transaction-edit-tag"
|
||||
:text="getTagName(tagId)"
|
||||
:text="allTagsMap[tagId]?.name ?? ''"
|
||||
:key="tagId"
|
||||
v-for="tagId in transaction.tagIds">
|
||||
<template #media>
|
||||
@@ -570,7 +570,6 @@ const {
|
||||
allVisibleCategorizedAccounts,
|
||||
allCategories,
|
||||
allCategoriesMap,
|
||||
allTags,
|
||||
allTagsMap,
|
||||
firstVisibleAccountId,
|
||||
hasVisibleExpenseCategories,
|
||||
@@ -828,16 +827,6 @@ function getFontClassByAmount(amount: number): string {
|
||||
}
|
||||
}
|
||||
|
||||
function getTagName(tagId: string): string {
|
||||
for (const tag of allTags.value) {
|
||||
if (tag.id === tagId) {
|
||||
return tag.name;
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
function init(): void {
|
||||
if (!pageTypeAndMode) {
|
||||
showToast('Parameter Invalid');
|
||||
|
||||
@@ -558,24 +558,31 @@
|
||||
</template>
|
||||
</f7-list-item>
|
||||
|
||||
<f7-list-item link="#" no-chevron popover-close
|
||||
:title="transactionTag.name"
|
||||
:class="{ 'list-item-selected': queryAllFilterTagIdsCount === 1 && isDefined(queryAllFilterTagIds[transactionTag.id]), 'item-in-multiple-selection': queryAllFilterTagIdsCount > 1 && isDefined(queryAllFilterTagIds[transactionTag.id]) }"
|
||||
:key="transactionTag.id"
|
||||
v-for="transactionTag in allTransactionTags"
|
||||
v-show="!transactionTag.hidden || isDefined(queryAllFilterTagIds[transactionTag.id])"
|
||||
@click="changeTagFilter(TransactionTagFilter.of(transactionTag.id).toTextualTagFilter())"
|
||||
>
|
||||
<template #before-title>
|
||||
<f7-icon class="transaction-tag-name transaction-tag-icon" f7="number"></f7-icon>
|
||||
</template>
|
||||
<template #after>
|
||||
<f7-icon class="list-item-checked-icon"
|
||||
:f7="queryAllFilterTagIds[transactionTag.id] === true ? 'checkmark_alt' : (queryAllFilterTagIds[transactionTag.id] === false ? 'multiply' : undefined)"
|
||||
v-if="isDefined(queryAllFilterTagIds[transactionTag.id])">
|
||||
</f7-icon>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
<template :key="transactionTagGroup.id"
|
||||
v-for="transactionTagGroup in allTransactionTagGroupsWithDefault">
|
||||
<f7-list-item group-title class="transaction-tag-group" v-if="allTransactionTagsByGroup[transactionTagGroup.id] && allTransactionTagsByGroup[transactionTagGroup.id]?.length && hasVisibleTagsInTagGroup(transactionTagGroup)">
|
||||
<small>{{ transactionTagGroup.name }}</small>
|
||||
</f7-list-item>
|
||||
|
||||
<f7-list-item link="#" no-chevron popover-close
|
||||
:title="transactionTag.name"
|
||||
:class="{ 'list-item-selected': queryAllFilterTagIdsCount === 1 && isDefined(queryAllFilterTagIds[transactionTag.id]), 'item-in-multiple-selection': queryAllFilterTagIdsCount > 1 && isDefined(queryAllFilterTagIds[transactionTag.id]) }"
|
||||
:key="transactionTag.id"
|
||||
v-for="transactionTag in (allTransactionTagsByGroup[transactionTagGroup.id] ?? [])"
|
||||
v-show="!transactionTag.hidden || isDefined(queryAllFilterTagIds[transactionTag.id])"
|
||||
@click="changeTagFilter(TransactionTagFilter.of(transactionTag.id).toTextualTagFilter())"
|
||||
>
|
||||
<template #before-title>
|
||||
<f7-icon class="transaction-tag-name transaction-tag-icon" f7="number"></f7-icon>
|
||||
</template>
|
||||
<template #after>
|
||||
<f7-icon class="list-item-checked-icon"
|
||||
:f7="queryAllFilterTagIds[transactionTag.id] === true ? 'checkmark_alt' : (queryAllFilterTagIds[transactionTag.id] === false ? 'multiply' : undefined)"
|
||||
v-if="isDefined(queryAllFilterTagIds[transactionTag.id])">
|
||||
</f7-icon>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
</template>
|
||||
</f7-list>
|
||||
</f7-popover>
|
||||
|
||||
@@ -686,6 +693,8 @@ const {
|
||||
allCategories,
|
||||
allPrimaryCategories,
|
||||
allAvailableCategoriesCount,
|
||||
allTransactionTagGroupsWithDefault,
|
||||
allTransactionTagsByGroup,
|
||||
allTransactionTags,
|
||||
allAvailableTagsCount,
|
||||
displayPageTypeName,
|
||||
@@ -708,6 +717,7 @@ const {
|
||||
transactionCalendarMaxDate,
|
||||
currentMonthTransactionData,
|
||||
hasSubCategoryInQuery,
|
||||
hasVisibleTagsInTagGroup,
|
||||
isSameAsDefaultTimezoneOffsetMinutes,
|
||||
canAddTransaction,
|
||||
getDisplayTime,
|
||||
@@ -1608,6 +1618,15 @@ html[dir="rtl"] .list.transaction-info-list li.transaction-info .transaction-foo
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.more-popover-menu .transaction-tag-group {
|
||||
background-color: inherit;
|
||||
|
||||
> small {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
||||
.transaction-calendar-container .dp__theme_light,
|
||||
.transaction-calendar-container .dp__theme_dark {
|
||||
--dp-background-color: var(--f7-list-strong-bg-color);
|
||||
|
||||
Reference in New Issue
Block a user