mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-18 16:54:25 +08:00
two column list item selection supports filtering content (#38)
This commit is contained in:
@@ -1,4 +1,6 @@
|
|||||||
import { type Ref } from 'vue';
|
import { type Ref, ref, computed } from 'vue';
|
||||||
|
|
||||||
|
import { useI18n } from '@/locales/helpers.ts';
|
||||||
|
|
||||||
import { getItemByKeyValue, getPrimaryValueBySecondaryValue } from '@/lib/common.ts';
|
import { getItemByKeyValue, getPrimaryValueBySecondaryValue } from '@/lib/common.ts';
|
||||||
|
|
||||||
@@ -29,12 +31,94 @@ export interface CommonTwoColumnListItemSelectionProps {
|
|||||||
secondaryIconType?: string;
|
secondaryIconType?: string;
|
||||||
secondaryColorField?: string;
|
secondaryColorField?: string;
|
||||||
secondaryHiddenField?: string;
|
secondaryHiddenField?: string;
|
||||||
items: unknown[];
|
enableFilter?: boolean;
|
||||||
|
filterPlaceholder?: string;
|
||||||
|
filterNoItemsText?: string;
|
||||||
|
items: Record<string, unknown>[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useTwoColumnListItemSelectionBase(props: CommonTwoColumnListItemSelectionProps) {
|
export function useTwoColumnListItemSelectionBase(props: CommonTwoColumnListItemSelectionProps) {
|
||||||
|
const { ti } = useI18n();
|
||||||
|
|
||||||
|
const filterContent = ref<string>('');
|
||||||
|
|
||||||
|
const filteredItems = computed<Record<string, unknown>[]>(() => {
|
||||||
|
const finalItems: Record<string, unknown>[] = [];
|
||||||
|
const items = props.items;
|
||||||
|
|
||||||
|
for (const item of items) {
|
||||||
|
if (props.primaryHiddenField && item[props.primaryHiddenField]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!props.enableFilter || !filterContent.value) {
|
||||||
|
finalItems.push(item);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.primaryTitleField) {
|
||||||
|
const title = ti(item[props.primaryTitleField] as string, !!props.primaryTitleI18n);
|
||||||
|
|
||||||
|
if (title.toLowerCase().indexOf(filterContent.value.toLowerCase()) >= 0) {
|
||||||
|
finalItems.push(item);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.primarySubItemsField) {
|
||||||
|
if (getFilteredSubItems(item).length > 0) {
|
||||||
|
finalItems.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return finalItems;
|
||||||
|
});
|
||||||
|
|
||||||
|
function getFilteredSubItems(selectedPrimaryItem: unknown): Record<string, unknown>[] {
|
||||||
|
const finalItems: Record<string, unknown>[] = [];
|
||||||
|
|
||||||
|
if (!selectedPrimaryItem || !props.primarySubItemsField) {
|
||||||
|
return finalItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
const subItems = (selectedPrimaryItem as Record<string, unknown>)[props.primarySubItemsField] as Record<string, unknown>[];
|
||||||
|
let primaryTitleHasFilterContent = false;
|
||||||
|
|
||||||
|
if (props.primaryTitleField) {
|
||||||
|
const title = ti((selectedPrimaryItem as Record<string, unknown>)[props.primaryTitleField] as string, !!props.primaryTitleI18n);
|
||||||
|
primaryTitleHasFilterContent = title.toLowerCase().indexOf(filterContent.value.toLowerCase()) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const subItem of subItems) {
|
||||||
|
if (props.secondaryHiddenField && subItem[props.secondaryHiddenField]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!props.enableFilter || !filterContent.value) {
|
||||||
|
finalItems.push(subItem);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (primaryTitleHasFilterContent) {
|
||||||
|
finalItems.push(subItem);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.secondaryTitleField && filterContent.value) {
|
||||||
|
const title = ti(subItem[props.secondaryTitleField] as string, !!props.secondaryTitleI18n);
|
||||||
|
|
||||||
|
if (title.toLowerCase().indexOf(filterContent.value.toLowerCase()) >= 0) {
|
||||||
|
finalItems.push(subItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return finalItems;
|
||||||
|
}
|
||||||
|
|
||||||
function getCurrentPrimaryValueBySecondaryValue(secondaryValue: unknown): unknown {
|
function getCurrentPrimaryValueBySecondaryValue(secondaryValue: unknown): unknown {
|
||||||
return getPrimaryValueBySecondaryValue(props.items as Record<string, Record<string, unknown>[]>[] | Record<string, Record<string, Record<string, unknown>[]>>, props.primarySubItemsField, props.primaryValueField, props.primaryHiddenField, props.secondaryValueField, props.secondaryHiddenField, secondaryValue);
|
return getPrimaryValueBySecondaryValue(props.items as Record<string, Record<string, unknown>[]>[], props.primarySubItemsField, props.primaryValueField, props.primaryHiddenField, props.secondaryValueField, props.secondaryHiddenField, secondaryValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isSecondaryValueSelected(currentSecondaryValue: unknown, subItem: unknown): boolean {
|
function isSecondaryValueSelected(currentSecondaryValue: unknown, subItem: unknown): boolean {
|
||||||
@@ -45,17 +129,17 @@ export function useTwoColumnListItemSelectionBase(props: CommonTwoColumnListItem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSelectedPrimaryItem(currentPrimaryValue: unknown) {
|
function getSelectedPrimaryItem(currentPrimaryValue: unknown): unknown {
|
||||||
if (props.primaryValueField) {
|
if (props.primaryValueField) {
|
||||||
return getItemByKeyValue(props.items as Record<string, unknown>[] | Record<string, Record<string, unknown>>, currentPrimaryValue, props.primaryValueField);
|
return getItemByKeyValue(props.items, currentPrimaryValue, props.primaryValueField);
|
||||||
} else {
|
} else {
|
||||||
return currentPrimaryValue;
|
return currentPrimaryValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSelectedSecondaryItem(currentSecondaryValue: unknown, selectedPrimaryItem: unknown) {
|
function getSelectedSecondaryItem(currentSecondaryValue: unknown, selectedPrimaryItem: unknown): unknown {
|
||||||
if (currentSecondaryValue && selectedPrimaryItem && (selectedPrimaryItem as Record<string, unknown>)[props.primarySubItemsField]) {
|
if (currentSecondaryValue && selectedPrimaryItem && (selectedPrimaryItem as Record<string, unknown>)[props.primarySubItemsField]) {
|
||||||
return getItemByKeyValue((selectedPrimaryItem as Record<string, unknown>)[props.primarySubItemsField] as Record<string, unknown>[] | Record<string, Record<string, unknown>>, currentSecondaryValue, props.secondaryValueField as string);
|
return getItemByKeyValue((selectedPrimaryItem as Record<string, unknown>)[props.primarySubItemsField] as Record<string, unknown>[], currentSecondaryValue, props.secondaryValueField as string);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -78,7 +162,12 @@ export function useTwoColumnListItemSelectionBase(props: CommonTwoColumnListItem
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
// states
|
||||||
|
filterContent,
|
||||||
|
// computed states
|
||||||
|
filteredItems,
|
||||||
// functions
|
// functions
|
||||||
|
getFilteredSubItems,
|
||||||
getCurrentPrimaryValueBySecondaryValue,
|
getCurrentPrimaryValueBySecondaryValue,
|
||||||
isSecondaryValueSelected,
|
isSecondaryValueSelected,
|
||||||
getSelectedPrimaryItem,
|
getSelectedPrimaryItem,
|
||||||
|
|||||||
@@ -14,11 +14,11 @@
|
|||||||
<template #selection>
|
<template #selection>
|
||||||
<div class="d-flex align-center text-truncate cursor-pointer">
|
<div class="d-flex align-center text-truncate cursor-pointer">
|
||||||
<span class="text-truncate" v-if="customSelectionPrimaryText">{{ customSelectionPrimaryText }}</span>
|
<span class="text-truncate" v-if="customSelectionPrimaryText">{{ customSelectionPrimaryText }}</span>
|
||||||
<v-icon class="disabled" :icon="icons.chevronRight" size="23" v-if="customSelectionPrimaryText && customSelectionSecondaryText" />
|
<v-icon class="disabled" :icon="mdiChevronRight" size="23" v-if="customSelectionPrimaryText && customSelectionSecondaryText" />
|
||||||
<span class="text-truncate" v-if="customSelectionPrimaryText && customSelectionSecondaryText">{{ customSelectionSecondaryText }}</span>
|
<span class="text-truncate" v-if="customSelectionPrimaryText && customSelectionSecondaryText">{{ customSelectionSecondaryText }}</span>
|
||||||
<span class="text-truncate" v-if="!customSelectionPrimaryText && !selectedPrimaryItem && !selectedSecondaryItem">{{ noSelectionText }}</span>
|
<span class="text-truncate" v-if="!customSelectionPrimaryText && !selectedPrimaryItem && !selectedSecondaryItem">{{ noSelectionText }}</span>
|
||||||
<span class="text-truncate" v-if="!customSelectionPrimaryText && showSelectionPrimaryText && selectedPrimaryItem">{{ selectionPrimaryItemText }}</span>
|
<span class="text-truncate" v-if="!customSelectionPrimaryText && showSelectionPrimaryText && selectedPrimaryItem">{{ selectionPrimaryItemText }}</span>
|
||||||
<v-icon class="disabled" :icon="icons.chevronRight" size="23" v-if="!customSelectionPrimaryText && showSelectionPrimaryText && selectedPrimaryItem && selectedSecondaryItem" />
|
<v-icon class="disabled" :icon="mdiChevronRight" size="23" v-if="!customSelectionPrimaryText && showSelectionPrimaryText && selectedPrimaryItem && selectedSecondaryItem" />
|
||||||
<ItemIcon class="mr-2" icon-type="account" size="21.5px"
|
<ItemIcon class="mr-2" icon-type="account" size="21.5px"
|
||||||
:icon-id="selectedSecondaryItem && secondaryIconField ? (selectedSecondaryItem as Record<string, unknown>)[secondaryIconField] : null"
|
:icon-id="selectedSecondaryItem && secondaryIconField ? (selectedSecondaryItem as Record<string, unknown>)[secondaryIconField] : null"
|
||||||
:color="selectedSecondaryItem && secondaryColorField ? (selectedSecondaryItem as Record<string, unknown>)[secondaryColorField] : null"
|
:color="selectedSecondaryItem && secondaryColorField ? (selectedSecondaryItem as Record<string, unknown>)[secondaryColorField] : null"
|
||||||
@@ -28,13 +28,21 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #no-data>
|
<template #no-data>
|
||||||
<div ref="dropdownMenu" class="two-column-list-container">
|
<div class="mx-2 mt-2" v-if="enableFilter">
|
||||||
|
<v-text-field density="compact"
|
||||||
|
:prepend-inner-icon="mdiMagnify"
|
||||||
|
:placeholder="filterPlaceholder"
|
||||||
|
v-model="filterContent"></v-text-field>
|
||||||
|
</div>
|
||||||
|
<div class="mx-4 my-3" v-show="!filteredItems || !filteredItems.length">
|
||||||
|
{{ filterNoItemsText }}
|
||||||
|
</div>
|
||||||
|
<div ref="dropdownMenu" class="two-column-list-container" v-show="filteredItems && filteredItems.length">
|
||||||
<div class="primary-list-container">
|
<div class="primary-list-container">
|
||||||
<v-list :class="{ 'list-item-with-header': !!primaryHeaderField, 'list-item-with-footer': !!primaryFooterField }">
|
<v-list :class="{ 'list-item-with-header': !!primaryHeaderField, 'list-item-with-footer': !!primaryFooterField }">
|
||||||
<v-list-item :class="{ 'primary-list-item-selected v-list-item--active text-primary': item === selectedPrimaryItem }"
|
<v-list-item :class="{ 'primary-list-item-selected v-list-item--active text-primary': item === selectedPrimaryItem }"
|
||||||
:key="primaryKeyField ? (item as Record<string, unknown>)[primaryKeyField] : item"
|
:key="primaryKeyField ? (item as Record<string, unknown>)[primaryKeyField] : item"
|
||||||
v-for="item in items"
|
v-for="item in filteredItems"
|
||||||
v-show="item && (!primaryHiddenField || !(item as Record<string, unknown>)[primaryHiddenField])"
|
|
||||||
@click="onPrimaryItemClicked(item)">
|
@click="onPrimaryItemClicked(item)">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<ItemIcon class="mr-2" :icon-type="primaryIconType"
|
<ItemIcon class="mr-2" :icon-type="primaryIconType"
|
||||||
@@ -53,8 +61,7 @@
|
|||||||
v-if="selectedPrimaryItem && primarySubItemsField && (selectedPrimaryItem as Record<string, unknown>)[primarySubItemsField]">
|
v-if="selectedPrimaryItem && primarySubItemsField && (selectedPrimaryItem as Record<string, unknown>)[primarySubItemsField]">
|
||||||
<v-list-item :class="{ 'secondary-list-item-selected v-list-item--active text-primary': isSecondarySelected(subItem) }"
|
<v-list-item :class="{ 'secondary-list-item-selected v-list-item--active text-primary': isSecondarySelected(subItem) }"
|
||||||
:key="secondaryKeyField ? subItem[secondaryKeyField] : subItem"
|
:key="secondaryKeyField ? subItem[secondaryKeyField] : subItem"
|
||||||
v-for="subItem in (selectedPrimaryItem as Record<string, unknown>)[primarySubItemsField]"
|
v-for="subItem in filteredSubItems"
|
||||||
v-show="subItem && (!secondaryHiddenField || !subItem[secondaryHiddenField])"
|
|
||||||
@click="onSecondaryItemClicked(subItem)">
|
@click="onSecondaryItemClicked(subItem)">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<ItemIcon class="mr-2" :icon-type="secondaryIconType"
|
<ItemIcon class="mr-2" :icon-type="secondaryIconType"
|
||||||
@@ -87,7 +94,8 @@ import {
|
|||||||
import { scrollToSelectedItem } from '@/lib/ui/desktop.ts';
|
import { scrollToSelectedItem } from '@/lib/ui/desktop.ts';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
mdiChevronRight
|
mdiChevronRight,
|
||||||
|
mdiMagnify
|
||||||
} from '@mdi/js';
|
} from '@mdi/js';
|
||||||
|
|
||||||
interface DesktopTwoColumnListItemSelectionProps extends CommonTwoColumnListItemSelectionProps {
|
interface DesktopTwoColumnListItemSelectionProps extends CommonTwoColumnListItemSelectionProps {
|
||||||
@@ -112,6 +120,9 @@ const emit = defineEmits<{
|
|||||||
const { tt, ti } = useI18n();
|
const { tt, ti } = useI18n();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
filterContent,
|
||||||
|
filteredItems,
|
||||||
|
getFilteredSubItems,
|
||||||
getCurrentPrimaryValueBySecondaryValue,
|
getCurrentPrimaryValueBySecondaryValue,
|
||||||
isSecondaryValueSelected,
|
isSecondaryValueSelected,
|
||||||
getSelectedPrimaryItem,
|
getSelectedPrimaryItem,
|
||||||
@@ -120,26 +131,24 @@ const {
|
|||||||
updateCurrentSecondaryValue
|
updateCurrentSecondaryValue
|
||||||
} = useTwoColumnListItemSelectionBase(props);
|
} = useTwoColumnListItemSelectionBase(props);
|
||||||
|
|
||||||
const icons = {
|
|
||||||
chevronRight: mdiChevronRight
|
|
||||||
};
|
|
||||||
|
|
||||||
const dropdownMenu = useTemplateRef<HTMLElement>('dropdownMenu');
|
const dropdownMenu = useTemplateRef<HTMLElement>('dropdownMenu');
|
||||||
|
|
||||||
const menuState = ref<boolean>(false);
|
const menuState = ref<boolean>(false);
|
||||||
|
|
||||||
|
const filteredSubItems = computed<Record<string, unknown>[]>(() => getFilteredSubItems(selectedPrimaryItem.value));
|
||||||
|
|
||||||
const currentPrimaryValue = computed<unknown>({
|
const currentPrimaryValue = computed<unknown>({
|
||||||
get: () => {
|
get: () => {
|
||||||
return getCurrentPrimaryValueBySecondaryValue(props.modelValue);
|
return getCurrentPrimaryValueBySecondaryValue(props.modelValue);
|
||||||
},
|
},
|
||||||
set: (value) => {
|
set: (value) => {
|
||||||
const primaryItem = getItemByKeyValue(props.items as Record<string, unknown>[] | Record<string, Record<string, unknown>>, value, props.primaryValueField as string);
|
const primaryItem = getItemByKeyValue(filteredItems.value, value, props.primaryValueField as string);
|
||||||
|
|
||||||
if (!primaryItem) {
|
if (!primaryItem) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const secondaryItem = getFirstVisibleItem(primaryItem[props.primarySubItemsField] as Record<string, unknown>[] | Record<string, Record<string, unknown>>, props.primaryHiddenField as string);
|
const secondaryItem = getFirstVisibleItem(getFilteredSubItems(primaryItem), props.primaryHiddenField as string);
|
||||||
|
|
||||||
if (secondaryItem) {
|
if (secondaryItem) {
|
||||||
if (props.secondaryValueField) {
|
if (props.secondaryValueField) {
|
||||||
@@ -167,7 +176,7 @@ const noSelectionText = computed<string>(() => props.noItemText ? props.noItemTe
|
|||||||
const selectionPrimaryItemText = computed<string>(() => {
|
const selectionPrimaryItemText = computed<string>(() => {
|
||||||
if (props.primaryValueField && props.primaryTitleField) {
|
if (props.primaryValueField && props.primaryTitleField) {
|
||||||
if (currentPrimaryValue.value) {
|
if (currentPrimaryValue.value) {
|
||||||
return getNameByKeyValue(props.items as Record<string, string>[] | Record<string, Record<string, string>>, currentPrimaryValue.value, props.primaryValueField, props.primaryTitleField, noSelectionText.value) as string;
|
return getNameByKeyValue(props.items as Record<string, string>[], currentPrimaryValue.value, props.primaryValueField, props.primaryTitleField, noSelectionText.value) as string;
|
||||||
} else {
|
} else {
|
||||||
return noSelectionText.value;
|
return noSelectionText.value;
|
||||||
}
|
}
|
||||||
@@ -179,7 +188,7 @@ const selectionPrimaryItemText = computed<string>(() => {
|
|||||||
const selectionSecondaryItemText = computed<string>(() => {
|
const selectionSecondaryItemText = computed<string>(() => {
|
||||||
if (props.secondaryValueField && props.secondaryTitleField) {
|
if (props.secondaryValueField && props.secondaryTitleField) {
|
||||||
if (currentSecondaryValue.value && selectedPrimaryItem.value && (selectedPrimaryItem.value as Record<string, unknown>)[props.primarySubItemsField]) {
|
if (currentSecondaryValue.value && selectedPrimaryItem.value && (selectedPrimaryItem.value as Record<string, unknown>)[props.primarySubItemsField]) {
|
||||||
return getNameByKeyValue((selectedPrimaryItem.value as Record<string, unknown>)[props.primarySubItemsField] as Record<string, string>[] | Record<string, Record<string, string>>, currentSecondaryValue.value, props.secondaryValueField, props.secondaryTitleField, noSelectionText.value) as string;
|
return getNameByKeyValue((selectedPrimaryItem.value as Record<string, unknown>)[props.primarySubItemsField] as Record<string, string>[], currentSecondaryValue.value, props.secondaryValueField, props.secondaryTitleField, noSelectionText.value) as string;
|
||||||
} else {
|
} else {
|
||||||
return noSelectionText.value;
|
return noSelectionText.value;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,31 +9,39 @@
|
|||||||
</div>
|
</div>
|
||||||
</f7-toolbar>
|
</f7-toolbar>
|
||||||
<f7-page-content>
|
<f7-page-content>
|
||||||
<div class="grid grid-cols-2 grid-gap">
|
<div v-if="enableFilter">
|
||||||
|
<f7-searchbar ref="searchbar" custom-searchs
|
||||||
|
:value="filterContent"
|
||||||
|
:placeholder="filterPlaceholder"
|
||||||
|
:disable-button="false"
|
||||||
|
@input="filterContent = $event.target.value"></f7-searchbar>
|
||||||
|
</div>
|
||||||
|
<div class="grid grid-gap" :class="{ 'grid-cols-2': filteredItems && filteredItems.length }">
|
||||||
<div>
|
<div>
|
||||||
<div class="primary-list-container">
|
<div class="primary-list-container">
|
||||||
<f7-list dividers class="primary-list no-margin-vertical">
|
<f7-list dividers class="primary-list no-margin-vertical">
|
||||||
<f7-list-item link="#" no-chevron
|
<f7-list-item link="#" no-chevron
|
||||||
:class="{ 'primary-list-item-selected': item === selectedPrimaryItem }"
|
:class="{ 'primary-list-item-selected': item === selectedPrimaryItem }"
|
||||||
:value="primaryValueField ? (item as Record<string, unknown>)[primaryValueField] : item"
|
:value="primaryValueField ? item[primaryValueField] : item"
|
||||||
:title="primaryTitleField ? ti((item as Record<string, unknown>)[primaryTitleField] as string, !!primaryTitleI18n) : ''"
|
:title="primaryTitleField ? ti(item[primaryTitleField] as string, !!primaryTitleI18n) : ''"
|
||||||
:header="primaryHeaderField ? ti((item as Record<string, unknown>)[primaryHeaderField] as string, !!primaryHeaderI18n) : ''"
|
:header="primaryHeaderField ? ti(item[primaryHeaderField] as string, !!primaryHeaderI18n) : ''"
|
||||||
:footer="primaryFooterField ? ti((item as Record<string, unknown>)[primaryFooterField] as string, !!primaryFooterI18n) : ''"
|
:footer="primaryFooterField ? ti(item[primaryFooterField] as string, !!primaryFooterI18n) : ''"
|
||||||
:key="primaryKeyField ? (item as Record<string, unknown>)[primaryKeyField] : item"
|
:key="primaryKeyField ? item[primaryKeyField] : item"
|
||||||
v-for="item in items"
|
v-for="item in filteredItems"
|
||||||
v-show="item && (!primaryHiddenField || !(item as Record<string, unknown>)[primaryHiddenField])"
|
|
||||||
@click="onPrimaryItemClicked(item)">
|
@click="onPrimaryItemClicked(item)">
|
||||||
<template #media>
|
<template #media>
|
||||||
<ItemIcon :icon-type="primaryIconType" :icon-id="primaryIconField ? (item as Record<string, unknown>)[primaryIconField] : undefined" :color="primaryColorField ? (item as Record<string, unknown>)[primaryColorField] : undefined"></ItemIcon>
|
<ItemIcon :icon-type="primaryIconType" :icon-id="primaryIconField ? item[primaryIconField] : undefined" :color="primaryColorField ? item[primaryColorField] : undefined"></ItemIcon>
|
||||||
</template>
|
</template>
|
||||||
<template #after>
|
<template #after>
|
||||||
<f7-icon class="list-item-showing" f7="chevron_right" v-if="item === selectedPrimaryItem"></f7-icon>
|
<f7-icon class="list-item-showing" f7="chevron_right" v-if="item === selectedPrimaryItem"></f7-icon>
|
||||||
</template>
|
</template>
|
||||||
</f7-list-item>
|
</f7-list-item>
|
||||||
|
<f7-list-item v-if="!filteredItems || !filteredItems.length"
|
||||||
|
:title="filterNoItemsText"></f7-list-item>
|
||||||
</f7-list>
|
</f7-list>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div v-show="filteredItems && filteredItems.length">
|
||||||
<div class="secondary-list-container">
|
<div class="secondary-list-container">
|
||||||
<f7-list dividers class="secondary-list no-margin-vertical" v-if="selectedPrimaryItem && primarySubItemsField && (selectedPrimaryItem as Record<string, unknown>)[primarySubItemsField]">
|
<f7-list dividers class="secondary-list no-margin-vertical" v-if="selectedPrimaryItem && primarySubItemsField && (selectedPrimaryItem as Record<string, unknown>)[primarySubItemsField]">
|
||||||
<f7-list-item link="#" no-chevron
|
<f7-list-item link="#" no-chevron
|
||||||
@@ -43,8 +51,7 @@
|
|||||||
:header="secondaryHeaderField ? ti(subItem[secondaryHeaderField] as string, !!secondaryHeaderI18n) : ''"
|
:header="secondaryHeaderField ? ti(subItem[secondaryHeaderField] as string, !!secondaryHeaderI18n) : ''"
|
||||||
:footer="secondaryFooterField ? ti(subItem[secondaryFooterField] as string, !!secondaryFooterI18n) : ''"
|
:footer="secondaryFooterField ? ti(subItem[secondaryFooterField] as string, !!secondaryFooterI18n) : ''"
|
||||||
:key="secondaryKeyField ? subItem[secondaryKeyField] : subItem"
|
:key="secondaryKeyField ? subItem[secondaryKeyField] : subItem"
|
||||||
v-for="subItem in (selectedPrimaryItem as Record<string, unknown>)[primarySubItemsField]"
|
v-for="subItem in filteredSubItems"
|
||||||
v-show="subItem && (!secondaryHiddenField || !subItem[secondaryHiddenField])"
|
|
||||||
@click="onSecondaryItemClicked(subItem)">
|
@click="onSecondaryItemClicked(subItem)">
|
||||||
<template #media>
|
<template #media>
|
||||||
<ItemIcon :icon-type="secondaryIconType" :icon-id="secondaryIconField ? subItem[secondaryIconField] : undefined" :color="secondaryColorField ? subItem[secondaryColorField] : undefined"></ItemIcon>
|
<ItemIcon :icon-type="secondaryIconType" :icon-id="secondaryIconField ? subItem[secondaryIconField] : undefined" :color="secondaryColorField ? subItem[secondaryColorField] : undefined"></ItemIcon>
|
||||||
@@ -62,7 +69,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed, useTemplateRef } from 'vue';
|
||||||
|
import type { Searchbar } from 'framework7/types';
|
||||||
|
|
||||||
import { useI18n } from '@/locales/helpers.ts';
|
import { useI18n } from '@/locales/helpers.ts';
|
||||||
import { type CommonTwoColumnListItemSelectionProps, useTwoColumnListItemSelectionBase } from '@/components/base/TwoColumnListItemSelectionBase.ts';
|
import { type CommonTwoColumnListItemSelectionProps, useTwoColumnListItemSelectionBase } from '@/components/base/TwoColumnListItemSelectionBase.ts';
|
||||||
@@ -83,6 +91,9 @@ const emit = defineEmits<{
|
|||||||
const { tt, ti } = useI18n();
|
const { tt, ti } = useI18n();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
filterContent,
|
||||||
|
filteredItems,
|
||||||
|
getFilteredSubItems,
|
||||||
getCurrentPrimaryValueBySecondaryValue,
|
getCurrentPrimaryValueBySecondaryValue,
|
||||||
isSecondaryValueSelected,
|
isSecondaryValueSelected,
|
||||||
getSelectedPrimaryItem,
|
getSelectedPrimaryItem,
|
||||||
@@ -90,10 +101,12 @@ const {
|
|||||||
updateCurrentSecondaryValue
|
updateCurrentSecondaryValue
|
||||||
} = useTwoColumnListItemSelectionBase(props);
|
} = useTwoColumnListItemSelectionBase(props);
|
||||||
|
|
||||||
|
const searchbar = useTemplateRef<Searchbar.Searchbar>('searchbar');
|
||||||
|
|
||||||
const currentPrimaryValue = ref<unknown>(getCurrentPrimaryValueBySecondaryValue(props.modelValue));
|
const currentPrimaryValue = ref<unknown>(getCurrentPrimaryValueBySecondaryValue(props.modelValue));
|
||||||
const currentSecondaryValue = ref<unknown>(props.modelValue);
|
const currentSecondaryValue = ref<unknown>(props.modelValue);
|
||||||
|
|
||||||
|
const filteredSubItems = computed<Record<string, unknown>[]>(() => getFilteredSubItems(selectedPrimaryItem.value));
|
||||||
const selectedPrimaryItem = computed<unknown>(() => getSelectedPrimaryItem(currentPrimaryValue.value));
|
const selectedPrimaryItem = computed<unknown>(() => getSelectedPrimaryItem(currentPrimaryValue.value));
|
||||||
|
|
||||||
function isSecondarySelected(subItem: unknown): boolean {
|
function isSecondarySelected(subItem: unknown): boolean {
|
||||||
@@ -123,6 +136,8 @@ function onSheetOpen(event: { $el: Framework7Dom }): void {
|
|||||||
|
|
||||||
function onSheetClosed(): void {
|
function onSheetClosed(): void {
|
||||||
close();
|
close();
|
||||||
|
filterContent.value = '';
|
||||||
|
searchbar.value?.clear();
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1455,6 +1455,7 @@
|
|||||||
"Account list has been updated": "Account list has been updated",
|
"Account list has been updated": "Account list has been updated",
|
||||||
"All Accounts": "All Accounts",
|
"All Accounts": "All Accounts",
|
||||||
"No available account": "No available account",
|
"No available account": "No available account",
|
||||||
|
"Find account": "Find account",
|
||||||
"Add Account": "Add Account",
|
"Add Account": "Add Account",
|
||||||
"Edit Account": "Edit Account",
|
"Edit Account": "Edit Account",
|
||||||
"Account Category": "Account Category",
|
"Account Category": "Account Category",
|
||||||
@@ -1784,6 +1785,7 @@
|
|||||||
"Transaction Secondary Categories": "Transaction Secondary Categories",
|
"Transaction Secondary Categories": "Transaction Secondary Categories",
|
||||||
"All Categories": "All Categories",
|
"All Categories": "All Categories",
|
||||||
"No available category": "No available category",
|
"No available category": "No available category",
|
||||||
|
"Find category": "Find category",
|
||||||
"Add Default Categories": "Add Default Categories",
|
"Add Default Categories": "Add Default Categories",
|
||||||
"Default Categories": "Default Categories",
|
"Default Categories": "Default Categories",
|
||||||
"Unable to retrieve category list": "Unable to retrieve category list",
|
"Unable to retrieve category list": "Unable to retrieve category list",
|
||||||
|
|||||||
@@ -1455,6 +1455,7 @@
|
|||||||
"Account list has been updated": "La lista de cuentas ha sido actualizada.",
|
"Account list has been updated": "La lista de cuentas ha sido actualizada.",
|
||||||
"All Accounts": "Todas las cuentas",
|
"All Accounts": "Todas las cuentas",
|
||||||
"No available account": "No hay cuenta disponible",
|
"No available account": "No hay cuenta disponible",
|
||||||
|
"Find account": "Find account",
|
||||||
"Add Account": "Agregar cuenta",
|
"Add Account": "Agregar cuenta",
|
||||||
"Edit Account": "Editar cuenta",
|
"Edit Account": "Editar cuenta",
|
||||||
"Account Category": "Categoría de cuenta",
|
"Account Category": "Categoría de cuenta",
|
||||||
@@ -1784,6 +1785,7 @@
|
|||||||
"Transaction Secondary Categories": "Categorías secundarias de transacciones",
|
"Transaction Secondary Categories": "Categorías secundarias de transacciones",
|
||||||
"All Categories": "Todas las categorías",
|
"All Categories": "Todas las categorías",
|
||||||
"No available category": "Ninguna categoría disponible",
|
"No available category": "Ninguna categoría disponible",
|
||||||
|
"Find category": "Find category",
|
||||||
"Add Default Categories": "Agregar categorías predeterminadas",
|
"Add Default Categories": "Agregar categorías predeterminadas",
|
||||||
"Default Categories": "Categorías predeterminadas",
|
"Default Categories": "Categorías predeterminadas",
|
||||||
"Unable to retrieve category list": "No se puede recuperar la lista de categorías",
|
"Unable to retrieve category list": "No se puede recuperar la lista de categorías",
|
||||||
|
|||||||
@@ -1455,6 +1455,7 @@
|
|||||||
"Account list has been updated": "Список счетов обновлен",
|
"Account list has been updated": "Список счетов обновлен",
|
||||||
"All Accounts": "Все счета",
|
"All Accounts": "Все счета",
|
||||||
"No available account": "Нет доступных счетов",
|
"No available account": "Нет доступных счетов",
|
||||||
|
"Find account": "Find account",
|
||||||
"Add Account": "Добавить счет",
|
"Add Account": "Добавить счет",
|
||||||
"Edit Account": "Редактировать счет",
|
"Edit Account": "Редактировать счет",
|
||||||
"Account Category": "Категория счета",
|
"Account Category": "Категория счета",
|
||||||
@@ -1784,6 +1785,7 @@
|
|||||||
"Transaction Secondary Categories": "Вторичные категории транзакций",
|
"Transaction Secondary Categories": "Вторичные категории транзакций",
|
||||||
"All Categories": "Все категории",
|
"All Categories": "Все категории",
|
||||||
"No available category": "Нет доступных категорий",
|
"No available category": "Нет доступных категорий",
|
||||||
|
"Find category": "Find category",
|
||||||
"Add Default Categories": "Добавить категории по умолчанию",
|
"Add Default Categories": "Добавить категории по умолчанию",
|
||||||
"Default Categories": "Категории по умолчанию",
|
"Default Categories": "Категории по умолчанию",
|
||||||
"Unable to retrieve category list": "Не удалось получить список категорий",
|
"Unable to retrieve category list": "Не удалось получить список категорий",
|
||||||
|
|||||||
@@ -1455,6 +1455,7 @@
|
|||||||
"Account list has been updated": "Danh sách tài khoản đã được cập nhật",
|
"Account list has been updated": "Danh sách tài khoản đã được cập nhật",
|
||||||
"All Accounts": "Tất cả tài khoản",
|
"All Accounts": "Tất cả tài khoản",
|
||||||
"No available account": "Không có tài khoản khả dụng",
|
"No available account": "Không có tài khoản khả dụng",
|
||||||
|
"Find account": "Find account",
|
||||||
"Add Account": "Thêm tài khoản",
|
"Add Account": "Thêm tài khoản",
|
||||||
"Edit Account": "Sửa tài khoản",
|
"Edit Account": "Sửa tài khoản",
|
||||||
"Account Category": "Danh mục tài khoản",
|
"Account Category": "Danh mục tài khoản",
|
||||||
@@ -1784,6 +1785,7 @@
|
|||||||
"Transaction Secondary Categories": "Danh mục giao dịch phụ",
|
"Transaction Secondary Categories": "Danh mục giao dịch phụ",
|
||||||
"All Categories": "Tất cả danh mục",
|
"All Categories": "Tất cả danh mục",
|
||||||
"No available category": "Không có danh mục nào khả dụng",
|
"No available category": "Không có danh mục nào khả dụng",
|
||||||
|
"Find category": "Find category",
|
||||||
"Add Default Categories": "Thêm danh mục mặc định",
|
"Add Default Categories": "Thêm danh mục mặc định",
|
||||||
"Default Categories": "Danh mục mặc định",
|
"Default Categories": "Danh mục mặc định",
|
||||||
"Unable to retrieve category list": "Không thể truy xuất danh sách danh mục",
|
"Unable to retrieve category list": "Không thể truy xuất danh sách danh mục",
|
||||||
|
|||||||
@@ -1455,6 +1455,7 @@
|
|||||||
"Account list has been updated": "账户列表已更新",
|
"Account list has been updated": "账户列表已更新",
|
||||||
"All Accounts": "全部账户",
|
"All Accounts": "全部账户",
|
||||||
"No available account": "没有可用的账户",
|
"No available account": "没有可用的账户",
|
||||||
|
"Find account": "查找账户",
|
||||||
"Add Account": "添加账户",
|
"Add Account": "添加账户",
|
||||||
"Edit Account": "编辑账户",
|
"Edit Account": "编辑账户",
|
||||||
"Account Category": "账户分类",
|
"Account Category": "账户分类",
|
||||||
@@ -1784,6 +1785,7 @@
|
|||||||
"Transaction Secondary Categories": "交易二级分类",
|
"Transaction Secondary Categories": "交易二级分类",
|
||||||
"All Categories": "全部分类",
|
"All Categories": "全部分类",
|
||||||
"No available category": "没有可用的分类",
|
"No available category": "没有可用的分类",
|
||||||
|
"Find category": "查找分类",
|
||||||
"Add Default Categories": "添加默认分类",
|
"Add Default Categories": "添加默认分类",
|
||||||
"Default Categories": "默认分类",
|
"Default Categories": "默认分类",
|
||||||
"Unable to retrieve category list": "无法获取分类列表",
|
"Unable to retrieve category list": "无法获取分类列表",
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
secondary-icon-field="icon" secondary-icon-type="category" secondary-color-field="color"
|
secondary-icon-field="icon" secondary-icon-type="category" secondary-color-field="color"
|
||||||
secondary-hidden-field="hidden"
|
secondary-hidden-field="hidden"
|
||||||
:disabled="!hasAvailableExpenseCategories"
|
:disabled="!hasAvailableExpenseCategories"
|
||||||
|
:enable-filter="true" :filter-placeholder="tt('Find category')" :filter-no-items-text="tt('No available category')"
|
||||||
:show-selection-primary-text="true"
|
:show-selection-primary-text="true"
|
||||||
:custom-selection-primary-text="getTransactionPrimaryCategoryName(targetItem, allCategories[CategoryType.Expense])"
|
:custom-selection-primary-text="getTransactionPrimaryCategoryName(targetItem, allCategories[CategoryType.Expense])"
|
||||||
:custom-selection-secondary-text="getTransactionSecondaryCategoryName(targetItem, allCategories[CategoryType.Expense])"
|
:custom-selection-secondary-text="getTransactionSecondaryCategoryName(targetItem, allCategories[CategoryType.Expense])"
|
||||||
@@ -53,6 +54,7 @@
|
|||||||
secondary-icon-field="icon" secondary-icon-type="category" secondary-color-field="color"
|
secondary-icon-field="icon" secondary-icon-type="category" secondary-color-field="color"
|
||||||
secondary-hidden-field="hidden"
|
secondary-hidden-field="hidden"
|
||||||
:disabled="!hasAvailableIncomeCategories"
|
:disabled="!hasAvailableIncomeCategories"
|
||||||
|
:enable-filter="true" :filter-placeholder="tt('Find category')" :filter-no-items-text="tt('No available category')"
|
||||||
:show-selection-primary-text="true"
|
:show-selection-primary-text="true"
|
||||||
:custom-selection-primary-text="getTransactionPrimaryCategoryName(targetItem, allCategories[CategoryType.Income])"
|
:custom-selection-primary-text="getTransactionPrimaryCategoryName(targetItem, allCategories[CategoryType.Income])"
|
||||||
:custom-selection-secondary-text="getTransactionSecondaryCategoryName(targetItem, allCategories[CategoryType.Income])"
|
:custom-selection-secondary-text="getTransactionSecondaryCategoryName(targetItem, allCategories[CategoryType.Income])"
|
||||||
@@ -69,6 +71,7 @@
|
|||||||
secondary-icon-field="icon" secondary-icon-type="category" secondary-color-field="color"
|
secondary-icon-field="icon" secondary-icon-type="category" secondary-color-field="color"
|
||||||
secondary-hidden-field="hidden"
|
secondary-hidden-field="hidden"
|
||||||
:disabled="!hasAvailableTransferCategories"
|
:disabled="!hasAvailableTransferCategories"
|
||||||
|
:enable-filter="true" :filter-placeholder="tt('Find category')" :filter-no-items-text="tt('No available category')"
|
||||||
:show-selection-primary-text="true"
|
:show-selection-primary-text="true"
|
||||||
:custom-selection-primary-text="getTransactionPrimaryCategoryName(targetItem, allCategories[CategoryType.Transfer])"
|
:custom-selection-primary-text="getTransactionPrimaryCategoryName(targetItem, allCategories[CategoryType.Transfer])"
|
||||||
:custom-selection-secondary-text="getTransactionSecondaryCategoryName(targetItem, allCategories[CategoryType.Transfer])"
|
:custom-selection-secondary-text="getTransactionSecondaryCategoryName(targetItem, allCategories[CategoryType.Transfer])"
|
||||||
@@ -105,6 +108,7 @@
|
|||||||
secondary-title-field="name" secondary-footer-field="displayBalance"
|
secondary-title-field="name" secondary-footer-field="displayBalance"
|
||||||
secondary-icon-field="icon" secondary-icon-type="account" secondary-color-field="color"
|
secondary-icon-field="icon" secondary-icon-type="account" secondary-color-field="color"
|
||||||
:disabled="!allVisibleAccounts.length"
|
:disabled="!allVisibleAccounts.length"
|
||||||
|
:enable-filter="true" :filter-placeholder="tt('Find account')" :filter-no-items-text="tt('No available account')"
|
||||||
:custom-selection-primary-text="getAccountDisplayName(targetItem)"
|
:custom-selection-primary-text="getAccountDisplayName(targetItem)"
|
||||||
:label="tt('Target Account')"
|
:label="tt('Target Account')"
|
||||||
:placeholder="tt('Target Account')"
|
:placeholder="tt('Target Account')"
|
||||||
|
|||||||
@@ -114,6 +114,7 @@
|
|||||||
secondary-hidden-field="hidden"
|
secondary-hidden-field="hidden"
|
||||||
:readonly="mode === TransactionEditPageMode.View"
|
:readonly="mode === TransactionEditPageMode.View"
|
||||||
:disabled="loading || submitting || !hasAvailableExpenseCategories"
|
:disabled="loading || submitting || !hasAvailableExpenseCategories"
|
||||||
|
:enable-filter="true" :filter-placeholder="tt('Find category')" :filter-no-items-text="tt('No available category')"
|
||||||
:show-selection-primary-text="true"
|
:show-selection-primary-text="true"
|
||||||
:custom-selection-primary-text="getTransactionPrimaryCategoryName(transaction.expenseCategoryId, allCategories[CategoryType.Expense])"
|
:custom-selection-primary-text="getTransactionPrimaryCategoryName(transaction.expenseCategoryId, allCategories[CategoryType.Expense])"
|
||||||
:custom-selection-secondary-text="getTransactionSecondaryCategoryName(transaction.expenseCategoryId, allCategories[CategoryType.Expense])"
|
:custom-selection-secondary-text="getTransactionSecondaryCategoryName(transaction.expenseCategoryId, allCategories[CategoryType.Expense])"
|
||||||
@@ -131,6 +132,7 @@
|
|||||||
secondary-hidden-field="hidden"
|
secondary-hidden-field="hidden"
|
||||||
:readonly="mode === TransactionEditPageMode.View"
|
:readonly="mode === TransactionEditPageMode.View"
|
||||||
:disabled="loading || submitting || !hasAvailableIncomeCategories"
|
:disabled="loading || submitting || !hasAvailableIncomeCategories"
|
||||||
|
:enable-filter="true" :filter-placeholder="tt('Find category')" :filter-no-items-text="tt('No available category')"
|
||||||
:show-selection-primary-text="true"
|
:show-selection-primary-text="true"
|
||||||
:custom-selection-primary-text="getTransactionPrimaryCategoryName(transaction.incomeCategoryId, allCategories[CategoryType.Income])"
|
:custom-selection-primary-text="getTransactionPrimaryCategoryName(transaction.incomeCategoryId, allCategories[CategoryType.Income])"
|
||||||
:custom-selection-secondary-text="getTransactionSecondaryCategoryName(transaction.incomeCategoryId, allCategories[CategoryType.Income])"
|
:custom-selection-secondary-text="getTransactionSecondaryCategoryName(transaction.incomeCategoryId, allCategories[CategoryType.Income])"
|
||||||
@@ -148,6 +150,7 @@
|
|||||||
secondary-hidden-field="hidden"
|
secondary-hidden-field="hidden"
|
||||||
:readonly="mode === TransactionEditPageMode.View"
|
:readonly="mode === TransactionEditPageMode.View"
|
||||||
:disabled="loading || submitting || !hasAvailableTransferCategories"
|
:disabled="loading || submitting || !hasAvailableTransferCategories"
|
||||||
|
:enable-filter="true" :filter-placeholder="tt('Find category')" :filter-no-items-text="tt('No available category')"
|
||||||
:show-selection-primary-text="true"
|
:show-selection-primary-text="true"
|
||||||
:custom-selection-primary-text="getTransactionPrimaryCategoryName(transaction.transferCategoryId, allCategories[CategoryType.Transfer])"
|
:custom-selection-primary-text="getTransactionPrimaryCategoryName(transaction.transferCategoryId, allCategories[CategoryType.Transfer])"
|
||||||
:custom-selection-secondary-text="getTransactionSecondaryCategoryName(transaction.transferCategoryId, allCategories[CategoryType.Transfer])"
|
:custom-selection-secondary-text="getTransactionSecondaryCategoryName(transaction.transferCategoryId, allCategories[CategoryType.Transfer])"
|
||||||
@@ -167,6 +170,7 @@
|
|||||||
secondary-icon-field="icon" secondary-icon-type="account" secondary-color-field="color"
|
secondary-icon-field="icon" secondary-icon-type="account" secondary-color-field="color"
|
||||||
:readonly="mode === TransactionEditPageMode.View"
|
:readonly="mode === TransactionEditPageMode.View"
|
||||||
:disabled="loading || submitting || !allVisibleAccounts.length"
|
:disabled="loading || submitting || !allVisibleAccounts.length"
|
||||||
|
:enable-filter="true" :filter-placeholder="tt('Find account')" :filter-no-items-text="tt('No available account')"
|
||||||
:custom-selection-primary-text="sourceAccountName"
|
:custom-selection-primary-text="sourceAccountName"
|
||||||
:label="tt(sourceAccountTitle)"
|
:label="tt(sourceAccountTitle)"
|
||||||
:placeholder="tt(sourceAccountTitle)"
|
:placeholder="tt(sourceAccountTitle)"
|
||||||
@@ -185,6 +189,7 @@
|
|||||||
secondary-icon-field="icon" secondary-icon-type="account" secondary-color-field="color"
|
secondary-icon-field="icon" secondary-icon-type="account" secondary-color-field="color"
|
||||||
:readonly="mode === TransactionEditPageMode.View"
|
:readonly="mode === TransactionEditPageMode.View"
|
||||||
:disabled="loading || submitting || !allVisibleAccounts.length"
|
:disabled="loading || submitting || !allVisibleAccounts.length"
|
||||||
|
:enable-filter="true" :filter-placeholder="tt('Find account')" :filter-no-items-text="tt('No available account')"
|
||||||
:custom-selection-primary-text="destinationAccountName"
|
:custom-selection-primary-text="destinationAccountName"
|
||||||
:label="tt('Destination Account')"
|
:label="tt('Destination Account')"
|
||||||
:placeholder="tt('Destination Account')"
|
:placeholder="tt('Destination Account')"
|
||||||
|
|||||||
@@ -317,6 +317,7 @@
|
|||||||
secondary-icon-field="icon" secondary-icon-type="category" secondary-color-field="color"
|
secondary-icon-field="icon" secondary-icon-type="category" secondary-color-field="color"
|
||||||
secondary-hidden-field="hidden"
|
secondary-hidden-field="hidden"
|
||||||
:disabled="loading || submitting || !hasAvailableExpenseCategories"
|
:disabled="loading || submitting || !hasAvailableExpenseCategories"
|
||||||
|
:enable-filter="true" :filter-placeholder="tt('Find category')" :filter-no-items-text="tt('No available category')"
|
||||||
:show-selection-primary-text="true"
|
:show-selection-primary-text="true"
|
||||||
:custom-selection-primary-text="getTransactionPrimaryCategoryName(item.categoryId, allCategories[CategoryType.Expense])"
|
:custom-selection-primary-text="getTransactionPrimaryCategoryName(item.categoryId, allCategories[CategoryType.Expense])"
|
||||||
:custom-selection-secondary-text="getTransactionSecondaryCategoryName(item.categoryId, allCategories[CategoryType.Expense])"
|
:custom-selection-secondary-text="getTransactionSecondaryCategoryName(item.categoryId, allCategories[CategoryType.Expense])"
|
||||||
@@ -334,6 +335,7 @@
|
|||||||
secondary-icon-field="icon" secondary-icon-type="category" secondary-color-field="color"
|
secondary-icon-field="icon" secondary-icon-type="category" secondary-color-field="color"
|
||||||
secondary-hidden-field="hidden"
|
secondary-hidden-field="hidden"
|
||||||
:disabled="loading || submitting || !hasAvailableIncomeCategories"
|
:disabled="loading || submitting || !hasAvailableIncomeCategories"
|
||||||
|
:enable-filter="true" :filter-placeholder="tt('Find category')" :filter-no-items-text="tt('No available category')"
|
||||||
:show-selection-primary-text="true"
|
:show-selection-primary-text="true"
|
||||||
:custom-selection-primary-text="getTransactionPrimaryCategoryName(item.categoryId, allCategories[CategoryType.Income])"
|
:custom-selection-primary-text="getTransactionPrimaryCategoryName(item.categoryId, allCategories[CategoryType.Income])"
|
||||||
:custom-selection-secondary-text="getTransactionSecondaryCategoryName(item.categoryId, allCategories[CategoryType.Income])"
|
:custom-selection-secondary-text="getTransactionSecondaryCategoryName(item.categoryId, allCategories[CategoryType.Income])"
|
||||||
@@ -351,6 +353,7 @@
|
|||||||
secondary-icon-field="icon" secondary-icon-type="category" secondary-color-field="color"
|
secondary-icon-field="icon" secondary-icon-type="category" secondary-color-field="color"
|
||||||
secondary-hidden-field="hidden"
|
secondary-hidden-field="hidden"
|
||||||
:disabled="loading || submitting || !hasAvailableTransferCategories"
|
:disabled="loading || submitting || !hasAvailableTransferCategories"
|
||||||
|
:enable-filter="true" :filter-placeholder="tt('Find category')" :filter-no-items-text="tt('No available category')"
|
||||||
:show-selection-primary-text="true"
|
:show-selection-primary-text="true"
|
||||||
:custom-selection-primary-text="getTransactionPrimaryCategoryName(item.categoryId, allCategories[CategoryType.Transfer])"
|
:custom-selection-primary-text="getTransactionPrimaryCategoryName(item.categoryId, allCategories[CategoryType.Transfer])"
|
||||||
:custom-selection-secondary-text="getTransactionSecondaryCategoryName(item.categoryId, allCategories[CategoryType.Transfer])"
|
:custom-selection-secondary-text="getTransactionSecondaryCategoryName(item.categoryId, allCategories[CategoryType.Transfer])"
|
||||||
@@ -390,6 +393,7 @@
|
|||||||
secondary-title-field="name" secondary-footer-field="displayBalance"
|
secondary-title-field="name" secondary-footer-field="displayBalance"
|
||||||
secondary-icon-field="icon" secondary-icon-type="account" secondary-color-field="color"
|
secondary-icon-field="icon" secondary-icon-type="account" secondary-color-field="color"
|
||||||
:disabled="loading || submitting || !allVisibleAccounts.length"
|
:disabled="loading || submitting || !allVisibleAccounts.length"
|
||||||
|
:enable-filter="true" :filter-placeholder="tt('Find account')" :filter-no-items-text="tt('No available account')"
|
||||||
:custom-selection-primary-text="getSourceAccountDisplayName(item)"
|
:custom-selection-primary-text="getSourceAccountDisplayName(item)"
|
||||||
:placeholder="getSourceAccountTitle(item)"
|
:placeholder="getSourceAccountTitle(item)"
|
||||||
:items="allVisibleCategorizedAccounts"
|
:items="allVisibleCategorizedAccounts"
|
||||||
@@ -406,6 +410,7 @@
|
|||||||
secondary-title-field="name" secondary-footer-field="displayBalance"
|
secondary-title-field="name" secondary-footer-field="displayBalance"
|
||||||
secondary-icon-field="icon" secondary-icon-type="account" secondary-color-field="color"
|
secondary-icon-field="icon" secondary-icon-type="account" secondary-color-field="color"
|
||||||
:disabled="loading || submitting || !allVisibleAccounts.length"
|
:disabled="loading || submitting || !allVisibleAccounts.length"
|
||||||
|
:enable-filter="true" :filter-placeholder="tt('Find account')" :filter-no-items-text="tt('No available account')"
|
||||||
:custom-selection-primary-text="getDestinationAccountDisplayName(item)"
|
:custom-selection-primary-text="getDestinationAccountDisplayName(item)"
|
||||||
:placeholder="tt('Destination Account')"
|
:placeholder="tt('Destination Account')"
|
||||||
:items="allVisibleCategorizedAccounts"
|
:items="allVisibleCategorizedAccounts"
|
||||||
|
|||||||
@@ -87,6 +87,7 @@
|
|||||||
secondary-title-field="name"
|
secondary-title-field="name"
|
||||||
secondary-icon-field="icon" secondary-icon-type="account" secondary-color-field="color"
|
secondary-icon-field="icon" secondary-icon-type="account" secondary-color-field="color"
|
||||||
:disabled="loading || saving || !allVisibleAccounts.length"
|
:disabled="loading || saving || !allVisibleAccounts.length"
|
||||||
|
:enable-filter="true" :filter-placeholder="tt('Find account')" :filter-no-items-text="tt('No available account')"
|
||||||
:label="tt('Default Account')"
|
:label="tt('Default Account')"
|
||||||
:placeholder="tt('Default Account')"
|
:placeholder="tt('Default Account')"
|
||||||
:items="allVisibleCategorizedAccounts"
|
:items="allVisibleCategorizedAccounts"
|
||||||
|
|||||||
@@ -202,6 +202,7 @@
|
|||||||
secondary-key-field="id" secondary-value-field="id"
|
secondary-key-field="id" secondary-value-field="id"
|
||||||
secondary-title-field="name" secondary-footer-field="displayBalance"
|
secondary-title-field="name" secondary-footer-field="displayBalance"
|
||||||
secondary-icon-field="icon" secondary-icon-type="account" secondary-color-field="color"
|
secondary-icon-field="icon" secondary-icon-type="account" secondary-color-field="color"
|
||||||
|
:enable-filter="true" :filter-placeholder="tt('Find account')" :filter-no-items-text="tt('No available account')"
|
||||||
:items="allVisibleCategorizedAccounts"
|
:items="allVisibleCategorizedAccounts"
|
||||||
v-model:show="showSourceAccountSheet"
|
v-model:show="showSourceAccountSheet"
|
||||||
v-model="transaction.sourceAccountId">
|
v-model="transaction.sourceAccountId">
|
||||||
@@ -225,6 +226,7 @@
|
|||||||
secondary-key-field="id" secondary-value-field="id"
|
secondary-key-field="id" secondary-value-field="id"
|
||||||
secondary-title-field="name" secondary-footer-field="displayBalance"
|
secondary-title-field="name" secondary-footer-field="displayBalance"
|
||||||
secondary-icon-field="icon" secondary-icon-type="account" secondary-color-field="color"
|
secondary-icon-field="icon" secondary-icon-type="account" secondary-color-field="color"
|
||||||
|
:enable-filter="true" :filter-placeholder="tt('Find account')" :filter-no-items-text="tt('No available account')"
|
||||||
:items="allVisibleCategorizedAccounts"
|
:items="allVisibleCategorizedAccounts"
|
||||||
v-model:show="showDestinationAccountSheet"
|
v-model:show="showDestinationAccountSheet"
|
||||||
v-model="transaction.destinationAccountId">
|
v-model="transaction.destinationAccountId">
|
||||||
|
|||||||
@@ -103,6 +103,7 @@
|
|||||||
secondary-key-field="id" secondary-value-field="id"
|
secondary-key-field="id" secondary-value-field="id"
|
||||||
secondary-title-field="name"
|
secondary-title-field="name"
|
||||||
secondary-icon-field="icon" secondary-icon-type="account" secondary-color-field="color"
|
secondary-icon-field="icon" secondary-icon-type="account" secondary-color-field="color"
|
||||||
|
:enable-filter="true" :filter-placeholder="tt('Find account')" :filter-no-items-text="tt('No available account')"
|
||||||
:items="allVisibleCategorizedAccounts"
|
:items="allVisibleCategorizedAccounts"
|
||||||
v-model:show="showAccountSheet"
|
v-model:show="showAccountSheet"
|
||||||
v-model="newProfile.defaultAccountId">
|
v-model="newProfile.defaultAccountId">
|
||||||
|
|||||||
Reference in New Issue
Block a user