use the same code for page scrolling on both the desktop and mobile versions
This commit is contained in:
@@ -50,7 +50,7 @@ import type { ColorValue, ColorInfo } from '@/core/color.ts';
|
|||||||
|
|
||||||
import { arrayContainsFieldValue } from '@/lib/common.ts';
|
import { arrayContainsFieldValue } from '@/lib/common.ts';
|
||||||
import { getColorsInRows, getDisplayColor } from '@/lib/color.ts';
|
import { getColorsInRows, getDisplayColor } from '@/lib/color.ts';
|
||||||
import { scrollToSelectedItem } from '@/lib/ui/desktop.ts';
|
import { scrollToSelectedItem } from '@/lib/ui/common.ts';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
mdiSquareRounded,
|
mdiSquareRounded,
|
||||||
@@ -90,7 +90,7 @@ function onMenuStateChanged(state: boolean): void {
|
|||||||
if (state) {
|
if (state) {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
if (dropdownMenu.value && dropdownMenu.value.parentElement) {
|
if (dropdownMenu.value && dropdownMenu.value.parentElement) {
|
||||||
scrollToSelectedItem(dropdownMenu.value.parentElement, null, '.row-has-selected-item');
|
scrollToSelectedItem(dropdownMenu.value.parentElement, null, null, '.row-has-selected-item');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ import type { ColorValue } from '@/core/color.ts';
|
|||||||
import type { IconInfo, IconInfoWithId } from '@/core/icon.ts';
|
import type { IconInfo, IconInfoWithId } from '@/core/icon.ts';
|
||||||
import { arrayContainsFieldValue } from '@/lib/common.ts';
|
import { arrayContainsFieldValue } from '@/lib/common.ts';
|
||||||
import { getIconsInRows } from '@/lib/icon.ts';
|
import { getIconsInRows } from '@/lib/icon.ts';
|
||||||
import { scrollToSelectedItem } from '@/lib/ui/desktop.ts';
|
import { scrollToSelectedItem } from '@/lib/ui/common.ts';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
mdiCheck
|
mdiCheck
|
||||||
@@ -89,7 +89,7 @@ function onMenuStateChanged(state: boolean): void {
|
|||||||
if (state) {
|
if (state) {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
if (dropdownMenu.value && dropdownMenu.value.parentElement) {
|
if (dropdownMenu.value && dropdownMenu.value.parentElement) {
|
||||||
scrollToSelectedItem(dropdownMenu.value.parentElement, null, '.row-has-selected-item');
|
scrollToSelectedItem(dropdownMenu.value.parentElement, null, null, '.row-has-selected-item');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ import { useUserStore } from '@/stores/user.ts';
|
|||||||
import { type WeekDayValue } from '@/core/datetime.ts';
|
import { type WeekDayValue } from '@/core/datetime.ts';
|
||||||
import { ScheduledTemplateFrequencyType } from '@/core/template.ts';
|
import { ScheduledTemplateFrequencyType } from '@/core/template.ts';
|
||||||
import { sortNumbersArray } from '@/lib/common.ts';
|
import { sortNumbersArray } from '@/lib/common.ts';
|
||||||
import { scrollToSelectedItem } from '@/lib/ui/desktop.ts';
|
import { scrollToSelectedItem } from '@/lib/ui/common.ts';
|
||||||
|
|
||||||
const props = defineProps<CommonScheduleFrequencySelectionProps>();
|
const props = defineProps<CommonScheduleFrequencySelectionProps>();
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@@ -159,7 +159,7 @@ function onMenuStateChanged(state: boolean): void {
|
|||||||
if (state) {
|
if (state) {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
if (dropdownMenu.value && dropdownMenu.value.parentElement) {
|
if (dropdownMenu.value && dropdownMenu.value.parentElement) {
|
||||||
scrollToSelectedItem(dropdownMenu.value.parentElement, '.schedule-frequency-value-container', '.frequency-value-selected');
|
scrollToSelectedItem(dropdownMenu.value.parentElement, '.schedule-frequency-value-container', '.schedule-frequency-value-container', '.frequency-value-selected');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,7 +102,8 @@ import {
|
|||||||
getItemByKeyValue,
|
getItemByKeyValue,
|
||||||
getNameByKeyValue
|
getNameByKeyValue
|
||||||
} from '@/lib/common.ts';
|
} from '@/lib/common.ts';
|
||||||
import { type ComponentDensity, type InputVariant, setChildInputFocus, scrollToSelectedItem } from '@/lib/ui/desktop.ts';
|
import { scrollToSelectedItem } from '@/lib/ui/common.ts';
|
||||||
|
import { type ComponentDensity, type InputVariant, setChildInputFocus } from '@/lib/ui/desktop.ts';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
mdiChevronRight,
|
mdiChevronRight,
|
||||||
@@ -246,8 +247,8 @@ function onMenuStateChanged(state: boolean): void {
|
|||||||
if (state) {
|
if (state) {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
if (dropdownMenu.value && dropdownMenu.value.parentElement) {
|
if (dropdownMenu.value && dropdownMenu.value.parentElement) {
|
||||||
scrollToSelectedItem(dropdownMenu.value.parentElement, '.primary-list-container', '.primary-list-item-selected');
|
scrollToSelectedItem(dropdownMenu.value.parentElement, '.primary-list-container', '.primary-list-container', '.primary-list-item-selected');
|
||||||
scrollToSelectedItem(dropdownMenu.value.parentElement, '.secondary-list-container', '.secondary-list-item-selected');
|
scrollToSelectedItem(dropdownMenu.value.parentElement, '.secondary-list-container', '.secondary-list-container', '.secondary-list-item-selected');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ import { ref, computed } from 'vue';
|
|||||||
import type { ColorValue, ColorInfo } from '@/core/color.ts';
|
import type { ColorValue, ColorInfo } from '@/core/color.ts';
|
||||||
import { arrayContainsFieldValue } from '@/lib/common.ts';
|
import { arrayContainsFieldValue } from '@/lib/common.ts';
|
||||||
import { getColorsInRows } from '@/lib/color.ts';
|
import { getColorsInRows } from '@/lib/color.ts';
|
||||||
import { type Framework7Dom, scrollToSelectedItem } from '@/lib/ui/mobile.ts';
|
import { scrollToSelectedItem } from '@/lib/ui/common.ts';
|
||||||
|
import { type Framework7Dom } from '@/lib/ui/mobile.ts';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue: ColorValue;
|
modelValue: ColorValue;
|
||||||
@@ -63,7 +64,7 @@ function hasSelectedIcon(row: ColorInfo[]): boolean {
|
|||||||
|
|
||||||
function onSheetOpen(event: { $el: Framework7Dom }): void {
|
function onSheetOpen(event: { $el: Framework7Dom }): void {
|
||||||
currentValue.value = props.modelValue;
|
currentValue.value = props.modelValue;
|
||||||
scrollToSelectedItem(event.$el, '.page-content', '.row-has-selected-item');
|
scrollToSelectedItem(event.$el[0], '.sheet-modal-inner', '.page-content', '.row-has-selected-item');
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSheetClosed(): void {
|
function onSheetClosed(): void {
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ import { ref, computed } from 'vue';
|
|||||||
import type { IconInfo, IconInfoWithId } from '@/core/icon.ts';
|
import type { IconInfo, IconInfoWithId } from '@/core/icon.ts';
|
||||||
import { arrayContainsFieldValue } from '@/lib/common.ts';
|
import { arrayContainsFieldValue } from '@/lib/common.ts';
|
||||||
import { getIconsInRows } from '@/lib/icon.ts';
|
import { getIconsInRows } from '@/lib/icon.ts';
|
||||||
import { type Framework7Dom, scrollToSelectedItem } from '@/lib/ui/mobile.ts';
|
import { scrollToSelectedItem } from '@/lib/ui/common.ts';
|
||||||
|
import { type Framework7Dom } from '@/lib/ui/mobile.ts';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue: string;
|
modelValue: string;
|
||||||
@@ -73,7 +74,7 @@ function hasSelectedIcon(row: IconInfoWithId[]): boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onSheetOpen(event: { $el: Framework7Dom }): void {
|
function onSheetOpen(event: { $el: Framework7Dom }): void {
|
||||||
scrollToSelectedItem(event.$el, '.page-content', '.row-has-selected-item');
|
scrollToSelectedItem(event.$el[0], '.sheet-modal-inner', '.page-content', '.row-has-selected-item');
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSheetClosed(): void {
|
function onSheetClosed(): void {
|
||||||
|
|||||||
@@ -56,7 +56,8 @@ import type { Searchbar } from 'framework7/types';
|
|||||||
|
|
||||||
import { useI18n } from '@/locales/helpers.ts';
|
import { useI18n } from '@/locales/helpers.ts';
|
||||||
|
|
||||||
import { type Framework7Dom, scrollToSelectedItem } from '@/lib/ui/mobile.ts';
|
import { scrollToSelectedItem } from '@/lib/ui/common.ts';
|
||||||
|
import { type Framework7Dom } from '@/lib/ui/mobile.ts';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue: unknown;
|
modelValue: unknown;
|
||||||
@@ -186,7 +187,7 @@ function onItemClicked(item: unknown, index: number): void {
|
|||||||
|
|
||||||
function onPopupOpen(event: { $el: Framework7Dom }): void {
|
function onPopupOpen(event: { $el: Framework7Dom }): void {
|
||||||
currentValue.value = props.modelValue;
|
currentValue.value = props.modelValue;
|
||||||
scrollToSelectedItem(event.$el, '.page-content', 'li.list-item-selected', false);
|
scrollToSelectedItem(event.$el[0], '.popup > .page', '.page-content', 'li.list-item-selected');
|
||||||
}
|
}
|
||||||
|
|
||||||
function onPopupClosed(): void {
|
function onPopupClosed(): void {
|
||||||
|
|||||||
@@ -36,7 +36,8 @@ import { ref, computed } from 'vue';
|
|||||||
|
|
||||||
import { useI18n } from '@/locales/helpers.ts';
|
import { useI18n } from '@/locales/helpers.ts';
|
||||||
|
|
||||||
import { type Framework7Dom, scrollToSelectedItem } from '@/lib/ui/mobile.ts';
|
import { scrollToSelectedItem } from '@/lib/ui/common.ts';
|
||||||
|
import { type Framework7Dom } from '@/lib/ui/mobile.ts';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue: unknown;
|
modelValue: unknown;
|
||||||
@@ -117,7 +118,7 @@ function onItemClicked(item: unknown, index: number): void {
|
|||||||
|
|
||||||
function onSheetOpen(event: { $el: Framework7Dom }): void {
|
function onSheetOpen(event: { $el: Framework7Dom }): void {
|
||||||
currentValue.value = props.modelValue;
|
currentValue.value = props.modelValue;
|
||||||
scrollToSelectedItem(event.$el, '.page-content', 'li.list-item-selected');
|
scrollToSelectedItem(event.$el[0], '.sheet-modal-inner', '.page-content', 'li.list-item-selected');
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSheetClosed(): void {
|
function onSheetClosed(): void {
|
||||||
|
|||||||
@@ -76,7 +76,8 @@ import { itemAndIndex } from '@/core/base.ts';
|
|||||||
import { type WeekDayValue } from '@/core/datetime.ts';
|
import { type WeekDayValue } from '@/core/datetime.ts';
|
||||||
import { ScheduledTemplateFrequencyType } from '@/core/template.ts';
|
import { ScheduledTemplateFrequencyType } from '@/core/template.ts';
|
||||||
import { sortNumbersArray } from '@/lib/common.ts';
|
import { sortNumbersArray } from '@/lib/common.ts';
|
||||||
import { type Framework7Dom, scrollToSelectedItem } from '@/lib/ui/mobile.ts';
|
import { scrollToSelectedItem } from '@/lib/ui/common.ts';
|
||||||
|
import { type Framework7Dom } from '@/lib/ui/mobile.ts';
|
||||||
|
|
||||||
interface MobileScheduleFrequencySelectionProps extends CommonScheduleFrequencySelectionProps {
|
interface MobileScheduleFrequencySelectionProps extends CommonScheduleFrequencySelectionProps {
|
||||||
show: boolean;
|
show: boolean;
|
||||||
@@ -151,7 +152,7 @@ function close(): void {
|
|||||||
function onSheetOpen(event: { $el: Framework7Dom }): void {
|
function onSheetOpen(event: { $el: Framework7Dom }): void {
|
||||||
currentFrequencyType.value = props.type;
|
currentFrequencyType.value = props.type;
|
||||||
currentFrequencyValue.value = getFrequencyValues(props.modelValue);
|
currentFrequencyValue.value = getFrequencyValues(props.modelValue);
|
||||||
scrollToSelectedItem(event.$el, '.schedule-frequency-value-container', 'li.list-item-selected');
|
scrollToSelectedItem(event.$el[0], '.schedule-frequency-value-container', '.schedule-frequency-value-container', 'li.list-item-selected');
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSheetClosed(): void {
|
function onSheetClosed(): void {
|
||||||
|
|||||||
@@ -94,7 +94,8 @@ import { useI18nUIComponents, showLoading, hideLoading } from '@/lib/ui/mobile.t
|
|||||||
import { TransactionTag } from '@/models/transaction_tag.ts';
|
import { TransactionTag } from '@/models/transaction_tag.ts';
|
||||||
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
||||||
|
|
||||||
import { type Framework7Dom, scrollToSelectedItem, scrollSheetToTop } from '@/lib/ui/mobile.ts';
|
import { scrollToSelectedItem } from '@/lib/ui/common.ts';
|
||||||
|
import { type Framework7Dom, scrollSheetToTop } from '@/lib/ui/mobile.ts';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue: string[];
|
modelValue: string[];
|
||||||
@@ -229,7 +230,7 @@ function onSearchBarFocus(): void {
|
|||||||
function onSheetOpen(event: { $el: Framework7Dom }): void {
|
function onSheetOpen(event: { $el: Framework7Dom }): void {
|
||||||
selectedItemIds.value = Array.from(props.modelValue);
|
selectedItemIds.value = Array.from(props.modelValue);
|
||||||
newTag.value = null;
|
newTag.value = null;
|
||||||
scrollToSelectedItem(event.$el, '.page-content', 'li.list-item-selected');
|
scrollToSelectedItem(event.$el[0], '.sheet-modal-inner', '.page-content', 'li.list-item-selected');
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSheetClosed(): void {
|
function onSheetClosed(): void {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
<f7-list class="no-margin-top no-margin-bottom" v-if="!filteredItems || !filteredItems.length">
|
<f7-list class="no-margin-top no-margin-bottom" v-if="!filteredItems || !filteredItems.length">
|
||||||
<f7-list-item :title="filterNoItemsText"></f7-list-item>
|
<f7-list-item :title="filterNoItemsText"></f7-list-item>
|
||||||
</f7-list>
|
</f7-list>
|
||||||
<f7-treeview>
|
<f7-treeview class="tree-view-selection-treeview">
|
||||||
<f7-treeview-item item-toggle
|
<f7-treeview-item item-toggle
|
||||||
:opened="isPrimaryItemHasSecondaryValue(item)"
|
:opened="isPrimaryItemHasSecondaryValue(item)"
|
||||||
:label="ti((primaryTitleField ? item[primaryTitleField] : item) as string, !!primaryTitleI18n)"
|
:label="ti((primaryTitleField ? item[primaryTitleField] : item) as string, !!primaryTitleI18n)"
|
||||||
@@ -54,7 +54,8 @@ import type { Sheet, Searchbar } from 'framework7/types';
|
|||||||
import { useI18n } from '@/locales/helpers.ts';
|
import { useI18n } from '@/locales/helpers.ts';
|
||||||
import { type TwoLevelItemSelectionBaseProps, useTwoLevelItemSelectionBase } from '@/components/base/TwoLevelItemSelectionBase.ts';
|
import { type TwoLevelItemSelectionBaseProps, useTwoLevelItemSelectionBase } from '@/components/base/TwoLevelItemSelectionBase.ts';
|
||||||
|
|
||||||
import { type Framework7Dom, scrollToSelectedItem, scrollSheetToTop } from '@/lib/ui/mobile.ts';
|
import { scrollToSelectedItem } from '@/lib/ui/common.ts';
|
||||||
|
import { type Framework7Dom, scrollSheetToTop } from '@/lib/ui/mobile.ts';
|
||||||
|
|
||||||
interface MobileTwoLevelItemSelectionBaseProps extends TwoLevelItemSelectionBaseProps {
|
interface MobileTwoLevelItemSelectionBaseProps extends TwoLevelItemSelectionBaseProps {
|
||||||
show: boolean;
|
show: boolean;
|
||||||
@@ -137,7 +138,7 @@ function onSearchBarFocus(): void {
|
|||||||
|
|
||||||
function onSheetOpen(event: { $el: Framework7Dom }): void {
|
function onSheetOpen(event: { $el: Framework7Dom }): void {
|
||||||
currentValue.value = props.modelValue;
|
currentValue.value = props.modelValue;
|
||||||
scrollToSelectedItem(event.$el, '.page-content', '.treeview-item .treeview-item-selected');
|
scrollToSelectedItem(event.$el[0], '.sheet-modal-inner', '.page-content', '.treeview-item > .treeview-item-selected');
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSheetClosed(): void {
|
function onSheetClosed(): void {
|
||||||
@@ -168,4 +169,8 @@ function onSheetClosed(): void {
|
|||||||
height: 320px;
|
height: 320px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tree-view-selection-treeview {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -75,7 +75,8 @@ import type { Sheet, 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';
|
||||||
|
|
||||||
import { type Framework7Dom, scrollToSelectedItem, scrollSheetToTop } from '@/lib/ui/mobile.ts';
|
import { scrollToSelectedItem } from '@/lib/ui/common.ts';
|
||||||
|
import { type Framework7Dom, scrollSheetToTop } from '@/lib/ui/mobile.ts';
|
||||||
|
|
||||||
interface MobileTwoColumnListItemSelectionProps extends CommonTwoColumnListItemSelectionProps {
|
interface MobileTwoColumnListItemSelectionProps extends CommonTwoColumnListItemSelectionProps {
|
||||||
show: boolean;
|
show: boolean;
|
||||||
@@ -135,8 +136,8 @@ function onSearchBarFocus(): void {
|
|||||||
function onSheetOpen(event: { $el: Framework7Dom }): void {
|
function onSheetOpen(event: { $el: Framework7Dom }): void {
|
||||||
currentPrimaryValue.value = getCurrentPrimaryValueBySecondaryValue(props.modelValue);
|
currentPrimaryValue.value = getCurrentPrimaryValueBySecondaryValue(props.modelValue);
|
||||||
currentSecondaryValue.value = props.modelValue;
|
currentSecondaryValue.value = props.modelValue;
|
||||||
scrollToSelectedItem(event.$el, '.primary-list-container', 'li.primary-list-item-selected');
|
scrollToSelectedItem(event.$el[0], '.primary-list-container', '.primary-list-container', 'li.primary-list-item-selected');
|
||||||
scrollToSelectedItem(event.$el, '.secondary-list-container', 'li.secondary-list-item-selected');
|
scrollToSelectedItem(event.$el[0], '.secondary-list-container', '.secondary-list-container', 'li.secondary-list-item-selected');
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSheetClosed(): void {
|
function onSheetClosed(): void {
|
||||||
|
|||||||
@@ -7,6 +7,59 @@ import { KnownFileType } from '@/core/file.ts';
|
|||||||
|
|
||||||
import logger from '../logger.ts';
|
import logger from '../logger.ts';
|
||||||
|
|
||||||
|
export function scrollToSelectedItem(parentEl: Element | null | undefined, containerSelector: string | null, scrollableListSelector: string | null, selectedItemSelector: string): void {
|
||||||
|
if (!parentEl) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const container = containerSelector ? parentEl.querySelector<HTMLElement>(containerSelector) : parentEl;
|
||||||
|
|
||||||
|
if (!container) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const scrollableList = scrollableListSelector ? parentEl.querySelector<HTMLElement>(scrollableListSelector) : parentEl;
|
||||||
|
|
||||||
|
if (!scrollableList) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectedItems = scrollableList.querySelectorAll<HTMLElement>(selectedItemSelector);
|
||||||
|
|
||||||
|
if (!selectedItems.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const containerHeight: number = container.clientHeight;
|
||||||
|
|
||||||
|
const firstSelectedItem: HTMLElement = selectedItems[0] as HTMLElement;
|
||||||
|
const lastSelectedItem: HTMLElement = selectedItems[selectedItems.length - 1] as HTMLElement;
|
||||||
|
|
||||||
|
const firstSelectedItemHeight: number = firstSelectedItem.offsetHeight;
|
||||||
|
const firstSelectedItemTop: number = firstSelectedItem.offsetTop;
|
||||||
|
const lastSelectedItemTop: number = lastSelectedItem.offsetTop;
|
||||||
|
const lastSelectedItemBottom: number = lastSelectedItem.offsetTop + lastSelectedItem.offsetHeight;
|
||||||
|
|
||||||
|
const middle: number = (firstSelectedItemTop + lastSelectedItemBottom) / 2;
|
||||||
|
let targetScrollTop: number = middle - containerHeight / 2;
|
||||||
|
|
||||||
|
if (containerSelector !== scrollableListSelector) {
|
||||||
|
const scrollableListStyle = window.getComputedStyle(scrollableList);
|
||||||
|
const paddingTop: number = parseFloat(scrollableListStyle.paddingTop) || 0;
|
||||||
|
targetScrollTop += paddingTop / 3 * 2;
|
||||||
|
|
||||||
|
if (selectedItems.length > 1 && lastSelectedItemTop - firstSelectedItemTop > containerHeight - firstSelectedItemHeight - paddingTop) {
|
||||||
|
targetScrollTop = firstSelectedItemTop;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (selectedItems.length > 1 && lastSelectedItemTop - firstSelectedItemTop > containerHeight - firstSelectedItemHeight) {
|
||||||
|
targetScrollTop = firstSelectedItemTop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollableList.scrollTop = Math.max(0, targetScrollTop);
|
||||||
|
}
|
||||||
|
|
||||||
export function getSystemTheme(): ThemeType {
|
export function getSystemTheme(): ThemeType {
|
||||||
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||||
return ThemeType.Dark;
|
return ThemeType.Dark;
|
||||||
|
|||||||
@@ -39,15 +39,6 @@ export function getNavSideBarOuterHeight(element: HTMLElement | null): number {
|
|||||||
return totalHeight;
|
return totalHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getCssValue(element: HTMLElement | null, name: string): string {
|
|
||||||
if (!element) {
|
|
||||||
return '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
const computedStyle = window.getComputedStyle(element);
|
|
||||||
return computedStyle.getPropertyValue(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setChildInputFocus(parentEl: HTMLElement | undefined, childSelector: string): void {
|
export function setChildInputFocus(parentEl: HTMLElement | undefined, childSelector: string): void {
|
||||||
if (!parentEl) {
|
if (!parentEl) {
|
||||||
return;
|
return;
|
||||||
@@ -63,57 +54,3 @@ export function setChildInputFocus(parentEl: HTMLElement | undefined, childSelec
|
|||||||
childInput.focus();
|
childInput.focus();
|
||||||
childInput.select();
|
childInput.select();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function scrollToSelectedItem(parentEl: HTMLElement | null | undefined, containerSelector: string | null, selectedItemSelector: string): void {
|
|
||||||
if (!parentEl) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let container = parentEl;
|
|
||||||
|
|
||||||
if (containerSelector) {
|
|
||||||
const lists = parentEl.querySelectorAll(containerSelector);
|
|
||||||
|
|
||||||
if (!lists.length || !lists[0]) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
container = lists[0] as HTMLElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
const selectedItems = container.querySelectorAll(selectedItemSelector);
|
|
||||||
|
|
||||||
if (!selectedItems.length || !selectedItems[0]) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const selectedItem = selectedItems[0] as HTMLElement;
|
|
||||||
const containerOuterHeight = getOuterHeight(container);
|
|
||||||
const selectedItemOuterHeight = getOuterHeight(selectedItem);
|
|
||||||
|
|
||||||
let targetPos = selectedItem.offsetTop - container.offsetTop - parseInt(getCssValue(container, 'padding-top'), 10)
|
|
||||||
- (containerOuterHeight - selectedItemOuterHeight) / 2;
|
|
||||||
|
|
||||||
if (selectedItems.length > 1) {
|
|
||||||
|
|
||||||
const firstSelectedItem = selectedItems[0] as HTMLElement;
|
|
||||||
const lastSelectedItem = selectedItems[selectedItems.length - 1] as HTMLElement;
|
|
||||||
|
|
||||||
const firstSelectedItemInTop = firstSelectedItem.offsetTop - container.offsetTop - parseInt(getCssValue(container, 'padding-top'), 10);
|
|
||||||
const lastSelectedItemInTop = lastSelectedItem.offsetTop - container.offsetTop - parseInt(getCssValue(container, 'padding-top'), 10);
|
|
||||||
const lastSelectedItemInBottom = lastSelectedItem.offsetTop - container.offsetTop - parseInt(getCssValue(container, 'padding-top'), 10)
|
|
||||||
- (containerOuterHeight - selectedItemOuterHeight);
|
|
||||||
|
|
||||||
targetPos = (firstSelectedItemInTop + lastSelectedItemInBottom) / 2;
|
|
||||||
|
|
||||||
if (lastSelectedItemInTop - firstSelectedItemInTop > containerOuterHeight) {
|
|
||||||
targetPos = firstSelectedItemInTop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (targetPos <= 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
container.scrollTop = targetPos;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { useI18n } from '@/locales/helpers.ts';
|
|||||||
|
|
||||||
import { TextDirection } from '@/core/text.ts';
|
import { TextDirection } from '@/core/text.ts';
|
||||||
import { FontSize, FONT_SIZE_PREVIEW_CLASSNAME_PREFIX } from '@/core/font.ts';
|
import { FontSize, FONT_SIZE_PREVIEW_CLASSNAME_PREFIX } from '@/core/font.ts';
|
||||||
import { getNumberValue } from '../common.ts';
|
|
||||||
import { isEnableAnimate } from '../settings.ts';
|
import { isEnableAnimate } from '../settings.ts';
|
||||||
|
|
||||||
export interface Framework7Dom {
|
export interface Framework7Dom {
|
||||||
@@ -148,51 +147,6 @@ export function getElementBoundingRect(selector: string): DOMRect | null {
|
|||||||
return el.getBoundingClientRect();
|
return el.getBoundingClientRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function scrollToSelectedItem(parentEl: Framework7Dom, containerSelector: string, selectedItemSelector: string, hasBottomToolbar?: boolean): void {
|
|
||||||
if (!parentEl || !parentEl.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const container = parentEl.find(containerSelector);
|
|
||||||
const selectedItem = parentEl.find(selectedItemSelector);
|
|
||||||
|
|
||||||
if (!container.length || !selectedItem.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const containerPaddingTop = getNumberValue(container.css('padding-top'), 0) / 2;
|
|
||||||
|
|
||||||
let targetPos = selectedItem.offset().top - container.offset().top - containerPaddingTop
|
|
||||||
- (container.outerHeight() - selectedItem.outerHeight()) / 2;
|
|
||||||
|
|
||||||
if (selectedItem.length > 1) {
|
|
||||||
const firstSelectedItem = f7.$(selectedItem[0]);
|
|
||||||
const lastSelectedItem = f7.$(selectedItem[selectedItem.length - 1]);
|
|
||||||
|
|
||||||
const firstSelectedItemInTop = firstSelectedItem.offset().top - container.offset().top - containerPaddingTop;
|
|
||||||
const lastSelectedItemInTop = lastSelectedItem.offset().top - container.offset().top - containerPaddingTop;
|
|
||||||
const lastSelectedItemInBottom = lastSelectedItem.offset().top - container.offset().top - containerPaddingTop
|
|
||||||
- (container.outerHeight() - firstSelectedItem.outerHeight());
|
|
||||||
|
|
||||||
targetPos = (firstSelectedItemInTop + lastSelectedItemInBottom) / 2;
|
|
||||||
|
|
||||||
if (lastSelectedItemInTop - firstSelectedItemInTop > container.outerHeight()) {
|
|
||||||
targetPos = firstSelectedItemInTop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (targetPos <= 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasBottomToolbar) {
|
|
||||||
const toolbarHeight = parentEl.find('.toolbar.toolbar-bottom').outerHeight() || 0;
|
|
||||||
targetPos += toolbarHeight / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
container.scrollTop(targetPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function scrollSheetToTop(sheetElement: HTMLElement | undefined, windowNormalInnerHeight: number): void {
|
export function scrollSheetToTop(sheetElement: HTMLElement | undefined, windowNormalInnerHeight: number): void {
|
||||||
if (!sheetElement) {
|
if (!sheetElement) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -135,6 +135,8 @@ i.icon.la, i.icon.las, i.icon.lab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.ios .popover-inner {
|
.ios .popover-inner {
|
||||||
|
touch-action: inherit;
|
||||||
|
|
||||||
> :not(.list) {
|
> :not(.list) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@@ -222,10 +224,6 @@ i.icon.la, i.icon.las, i.icon.lab {
|
|||||||
|
|
||||||
.lang-popover-menu .popover-inner {
|
.lang-popover-menu .popover-inner {
|
||||||
max-height: 350px;
|
max-height: 350px;
|
||||||
|
|
||||||
> .list {
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.lang-popover-menu .popover-inner .item-title {
|
.lang-popover-menu .popover-inner .item-title {
|
||||||
|
|||||||
@@ -711,8 +711,7 @@ import {
|
|||||||
transactionTypeToCategoryType
|
transactionTypeToCategoryType
|
||||||
} from '@/lib/category.ts';
|
} from '@/lib/category.ts';
|
||||||
import { isDataExportingEnabled, isDataImportingEnabled, isTransactionFromAIImageRecognitionEnabled } from '@/lib/server_settings.ts';
|
import { isDataExportingEnabled, isDataImportingEnabled, isTransactionFromAIImageRecognitionEnabled } from '@/lib/server_settings.ts';
|
||||||
import { startDownloadFile } from '@/lib/ui/common.ts';
|
import { scrollToSelectedItem, startDownloadFile } from '@/lib/ui/common.ts';
|
||||||
import { scrollToSelectedItem } from '@/lib/ui/desktop.ts';
|
|
||||||
import logger from '@/lib/logger.ts';
|
import logger from '@/lib/logger.ts';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -1696,7 +1695,7 @@ function scrollTagMenuToSelectedItem(opened: boolean): void {
|
|||||||
|
|
||||||
function scrollMenuToSelectedItem(menu: VMenu | null): void {
|
function scrollMenuToSelectedItem(menu: VMenu | null): void {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
scrollToSelectedItem(menu?.contentEl, 'div.v-list', 'div.v-list-item.list-item-selected');
|
scrollToSelectedItem(menu?.contentEl, 'div.v-list', 'div.v-list', 'div.v-list-item.list-item-selected');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -440,9 +440,6 @@ init();
|
|||||||
|
|
||||||
.template-popover-menu .popover-inner {
|
.template-popover-menu .popover-inner {
|
||||||
max-height: 400px;
|
max-height: 400px;
|
||||||
|
overflow-y: auto;
|
||||||
> .list {
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -16,51 +16,45 @@
|
|||||||
<f7-popover class="chart-data-type-popover-menu"
|
<f7-popover class="chart-data-type-popover-menu"
|
||||||
@popover:open="scrollPopoverToSelectedItem">
|
@popover:open="scrollPopoverToSelectedItem">
|
||||||
<f7-list dividers>
|
<f7-list dividers>
|
||||||
<f7-list-group>
|
<f7-list-item group-title>
|
||||||
<f7-list-item group-title>
|
<small>{{ tt('Categorical Analysis') }}</small>
|
||||||
<small>{{ tt('Categorical Analysis') }}</small>
|
</f7-list-item>
|
||||||
</f7-list-item>
|
<f7-list-item link="#" no-chevron popover-close
|
||||||
<f7-list-item link="#" no-chevron popover-close
|
:title="tt(dataType.name)"
|
||||||
:title="tt(dataType.name)"
|
:class="{ 'list-item-selected': analysisType === StatisticsAnalysisType.CategoricalAnalysis && query.chartDataType === dataType.type }"
|
||||||
:class="{ 'list-item-selected': analysisType === StatisticsAnalysisType.CategoricalAnalysis && query.chartDataType === dataType.type }"
|
:key="dataType.type"
|
||||||
:key="dataType.type"
|
v-for="dataType in ChartDataType.values(StatisticsAnalysisType.CategoricalAnalysis)"
|
||||||
v-for="dataType in ChartDataType.values(StatisticsAnalysisType.CategoricalAnalysis)"
|
@click="setChartDataType(StatisticsAnalysisType.CategoricalAnalysis, dataType.type)">
|
||||||
@click="setChartDataType(StatisticsAnalysisType.CategoricalAnalysis, dataType.type)">
|
<template #after>
|
||||||
<template #after>
|
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="analysisType === StatisticsAnalysisType.CategoricalAnalysis && query.chartDataType === dataType.type"></f7-icon>
|
||||||
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="analysisType === StatisticsAnalysisType.CategoricalAnalysis && query.chartDataType === dataType.type"></f7-icon>
|
</template>
|
||||||
</template>
|
</f7-list-item>
|
||||||
</f7-list-item>
|
<f7-list-item group-title>
|
||||||
</f7-list-group>
|
<small>{{ tt('Trend Analysis') }}</small>
|
||||||
<f7-list-group>
|
</f7-list-item>
|
||||||
<f7-list-item group-title>
|
<f7-list-item link="#" no-chevron popover-close
|
||||||
<small>{{ tt('Trend Analysis') }}</small>
|
:title="tt(dataType.name)"
|
||||||
</f7-list-item>
|
:class="{ 'list-item-selected': analysisType === StatisticsAnalysisType.TrendAnalysis && query.chartDataType === dataType.type }"
|
||||||
<f7-list-item link="#" no-chevron popover-close
|
:key="dataType.type"
|
||||||
:title="tt(dataType.name)"
|
v-for="dataType in ChartDataType.values(StatisticsAnalysisType.TrendAnalysis)"
|
||||||
:class="{ 'list-item-selected': analysisType === StatisticsAnalysisType.TrendAnalysis && query.chartDataType === dataType.type }"
|
@click="setChartDataType(StatisticsAnalysisType.TrendAnalysis, dataType.type)">
|
||||||
:key="dataType.type"
|
<template #after>
|
||||||
v-for="dataType in ChartDataType.values(StatisticsAnalysisType.TrendAnalysis)"
|
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="analysisType === StatisticsAnalysisType.TrendAnalysis && query.chartDataType === dataType.type"></f7-icon>
|
||||||
@click="setChartDataType(StatisticsAnalysisType.TrendAnalysis, dataType.type)">
|
</template>
|
||||||
<template #after>
|
</f7-list-item>
|
||||||
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="analysisType === StatisticsAnalysisType.TrendAnalysis && query.chartDataType === dataType.type"></f7-icon>
|
<f7-list-item group-title>
|
||||||
</template>
|
<small>{{ tt('Asset Trends') }}</small>
|
||||||
</f7-list-item>
|
</f7-list-item>
|
||||||
</f7-list-group>
|
<f7-list-item link="#" no-chevron popover-close
|
||||||
<f7-list-group>
|
:title="tt(dataType.name)"
|
||||||
<f7-list-item group-title>
|
:class="{ 'list-item-selected': analysisType === StatisticsAnalysisType.AssetTrends && query.chartDataType === dataType.type }"
|
||||||
<small>{{ tt('Asset Trends') }}</small>
|
:key="dataType.type"
|
||||||
</f7-list-item>
|
v-for="dataType in ChartDataType.values(StatisticsAnalysisType.AssetTrends)"
|
||||||
<f7-list-item link="#" no-chevron popover-close
|
@click="setChartDataType(StatisticsAnalysisType.AssetTrends, dataType.type)">
|
||||||
:title="tt(dataType.name)"
|
<template #after>
|
||||||
:class="{ 'list-item-selected': analysisType === StatisticsAnalysisType.AssetTrends && query.chartDataType === dataType.type }"
|
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="analysisType === StatisticsAnalysisType.AssetTrends && query.chartDataType === dataType.type"></f7-icon>
|
||||||
:key="dataType.type"
|
</template>
|
||||||
v-for="dataType in ChartDataType.values(StatisticsAnalysisType.AssetTrends)"
|
</f7-list-item>
|
||||||
@click="setChartDataType(StatisticsAnalysisType.AssetTrends, dataType.type)">
|
|
||||||
<template #after>
|
|
||||||
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="analysisType === StatisticsAnalysisType.AssetTrends && query.chartDataType === dataType.type"></f7-icon>
|
|
||||||
</template>
|
|
||||||
</f7-list-item>
|
|
||||||
</f7-list-group>
|
|
||||||
</f7-list>
|
</f7-list>
|
||||||
</f7-popover>
|
</f7-popover>
|
||||||
|
|
||||||
@@ -437,7 +431,8 @@ import {
|
|||||||
getDateTypeByDateRange,
|
getDateTypeByDateRange,
|
||||||
getDateRangeByDateType
|
getDateRangeByDateType
|
||||||
} from '@/lib/datetime.ts';
|
} from '@/lib/datetime.ts';
|
||||||
import { type Framework7Dom, useI18nUIComponents, scrollToSelectedItem } from '@/lib/ui/mobile.ts';
|
import { scrollToSelectedItem } from '@/lib/ui/common.ts';
|
||||||
|
import { type Framework7Dom, useI18nUIComponents } from '@/lib/ui/mobile.ts';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
f7router: Router.Router;
|
f7router: Router.Router;
|
||||||
@@ -884,7 +879,7 @@ function settings(): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function scrollPopoverToSelectedItem(event: { $el: Framework7Dom }): void {
|
function scrollPopoverToSelectedItem(event: { $el: Framework7Dom }): void {
|
||||||
scrollToSelectedItem(event.$el, '.popover-inner', 'li.list-item-selected');
|
scrollToSelectedItem(event.$el[0], '.popover-inner', '.popover-inner', 'li.list-item-selected');
|
||||||
}
|
}
|
||||||
|
|
||||||
function onClickPieChartItem(item: Record<string, unknown>): void {
|
function onClickPieChartItem(item: Record<string, unknown>): void {
|
||||||
@@ -949,9 +944,6 @@ init();
|
|||||||
|
|
||||||
.chart-data-type-popover-menu .popover-inner {
|
.chart-data-type-popover-menu .popover-inner {
|
||||||
max-height: 440px;
|
max-height: 440px;
|
||||||
|
overflow-y: auto;
|
||||||
> .list {
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -339,7 +339,7 @@
|
|||||||
@update:modelValue="changeCustomMonthDateFilter">
|
@update:modelValue="changeCustomMonthDateFilter">
|
||||||
</month-selection-sheet>
|
</month-selection-sheet>
|
||||||
|
|
||||||
<f7-popover class="category-popover-menu" @popover:open="onPopoverOpen">
|
<f7-popover class="category-popover-menu" @popover:open="onCategoryPopoverOpen">
|
||||||
<f7-list dividers accordion-list>
|
<f7-list dividers accordion-list>
|
||||||
<f7-list-item link="#" no-chevron popover-close
|
<f7-list-item link="#" no-chevron popover-close
|
||||||
:class="{ 'list-item-selected': !query.categoryIds }"
|
:class="{ 'list-item-selected': !query.categoryIds }"
|
||||||
@@ -364,57 +364,55 @@
|
|||||||
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="query.categoryIds && queryAllFilterCategoryIdsCount > 1"></f7-icon>
|
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="query.categoryIds && queryAllFilterCategoryIdsCount > 1"></f7-icon>
|
||||||
</template>
|
</template>
|
||||||
</f7-list-item>
|
</f7-list-item>
|
||||||
</f7-list>
|
<template :key="categoryType"
|
||||||
<f7-list dividers accordion-list
|
v-for="(categories, categoryType) in allPrimaryCategories">
|
||||||
class="no-margin-vertical"
|
<template v-if="categories && categories.length">
|
||||||
:key="categoryType"
|
<f7-list-item divider :title="getTransactionTypeName(categoryTypeToTransactionType(parseInt(categoryType)), 'Type')"></f7-list-item>
|
||||||
v-for="(categories, categoryType) in allPrimaryCategories"
|
<f7-list-item accordion-item
|
||||||
v-show="categories && categories.length"
|
:title="category.name"
|
||||||
>
|
:class="getCategoryListItemCheckedClass(category, queryAllFilterCategoryIds)"
|
||||||
<f7-list-item divider :title="getTransactionTypeName(categoryTypeToTransactionType(parseInt(categoryType)), 'Type')"></f7-list-item>
|
:key="category.id"
|
||||||
<f7-list-item accordion-item
|
v-for="category in categories"
|
||||||
:title="category.name"
|
v-show="!category.hidden || queryAllFilterCategoryIds[category.id] || allCategories[query.categoryIds]?.parentId === category.id || hasSubCategoryInQuery(category)"
|
||||||
:class="getCategoryListItemCheckedClass(category, queryAllFilterCategoryIds)"
|
>
|
||||||
:key="category.id"
|
<template #media>
|
||||||
v-for="category in categories"
|
<ItemIcon icon-type="category" :icon-id="category.icon" :color="category.color"></ItemIcon>
|
||||||
v-show="!category.hidden || queryAllFilterCategoryIds[category.id] || allCategories[query.categoryIds]?.parentId === category.id || hasSubCategoryInQuery(category)"
|
</template>
|
||||||
>
|
<f7-accordion-content>
|
||||||
<template #media>
|
<f7-list dividers class="padding-inline-start">
|
||||||
<ItemIcon icon-type="category" :icon-id="category.icon" :color="category.color"></ItemIcon>
|
<f7-list-item link="#" no-chevron popover-close
|
||||||
|
:class="{ 'list-item-selected': query.categoryIds === category.id, 'item-in-multiple-selection': queryAllFilterCategoryIdsCount > 1 && queryAllFilterCategoryIds[category.id] }"
|
||||||
|
:title="tt('All')" @click="changeCategoryFilter(category.id)">
|
||||||
|
<template #media>
|
||||||
|
<f7-icon f7="rectangle_grid_2x2"></f7-icon>
|
||||||
|
</template>
|
||||||
|
<template #after>
|
||||||
|
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="query.categoryIds === category.id"></f7-icon>
|
||||||
|
</template>
|
||||||
|
</f7-list-item>
|
||||||
|
<f7-list-item link="#" no-chevron popover-close
|
||||||
|
:class="{ 'list-item-selected': query.categoryIds === subCategory.id, 'item-in-multiple-selection': queryAllFilterCategoryIdsCount > 1 && queryAllFilterCategoryIds[subCategory.id] }"
|
||||||
|
:title="subCategory.name"
|
||||||
|
:key="subCategory.id"
|
||||||
|
v-for="subCategory in category.subCategories"
|
||||||
|
v-show="!subCategory.hidden || queryAllFilterCategoryIds[subCategory.id]"
|
||||||
|
@click="changeCategoryFilter(subCategory.id)"
|
||||||
|
>
|
||||||
|
<template #media>
|
||||||
|
<ItemIcon icon-type="category" :icon-id="subCategory.icon" :color="subCategory.color"></ItemIcon>
|
||||||
|
</template>
|
||||||
|
<template #after>
|
||||||
|
<f7-icon class="list-item-checked-icon"
|
||||||
|
f7="checkmark_alt"
|
||||||
|
v-if="query.categoryIds === subCategory.id">
|
||||||
|
</f7-icon>
|
||||||
|
</template>
|
||||||
|
</f7-list-item>
|
||||||
|
</f7-list>
|
||||||
|
</f7-accordion-content>
|
||||||
|
</f7-list-item>
|
||||||
</template>
|
</template>
|
||||||
<f7-accordion-content>
|
</template>
|
||||||
<f7-list dividers class="padding-inline-start">
|
|
||||||
<f7-list-item link="#" no-chevron popover-close
|
|
||||||
:class="{ 'list-item-selected': query.categoryIds === category.id, 'item-in-multiple-selection': queryAllFilterCategoryIdsCount > 1 && queryAllFilterCategoryIds[category.id] }"
|
|
||||||
:title="tt('All')" @click="changeCategoryFilter(category.id)">
|
|
||||||
<template #media>
|
|
||||||
<f7-icon f7="rectangle_grid_2x2"></f7-icon>
|
|
||||||
</template>
|
|
||||||
<template #after>
|
|
||||||
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="query.categoryIds === category.id"></f7-icon>
|
|
||||||
</template>
|
|
||||||
</f7-list-item>
|
|
||||||
<f7-list-item link="#" no-chevron popover-close
|
|
||||||
:class="{ 'list-item-selected': query.categoryIds === subCategory.id, 'item-in-multiple-selection': queryAllFilterCategoryIdsCount > 1 && queryAllFilterCategoryIds[subCategory.id] }"
|
|
||||||
:title="subCategory.name"
|
|
||||||
:key="subCategory.id"
|
|
||||||
v-for="subCategory in category.subCategories"
|
|
||||||
v-show="!subCategory.hidden || queryAllFilterCategoryIds[subCategory.id]"
|
|
||||||
@click="changeCategoryFilter(subCategory.id)"
|
|
||||||
>
|
|
||||||
<template #media>
|
|
||||||
<ItemIcon icon-type="category" :icon-id="subCategory.icon" :color="subCategory.color"></ItemIcon>
|
|
||||||
</template>
|
|
||||||
<template #after>
|
|
||||||
<f7-icon class="list-item-checked-icon"
|
|
||||||
f7="checkmark_alt"
|
|
||||||
v-if="query.categoryIds === subCategory.id">
|
|
||||||
</f7-icon>
|
|
||||||
</template>
|
|
||||||
</f7-list-item>
|
|
||||||
</f7-list>
|
|
||||||
</f7-accordion-content>
|
|
||||||
</f7-list-item>
|
|
||||||
</f7-list>
|
</f7-list>
|
||||||
</f7-popover>
|
</f7-popover>
|
||||||
|
|
||||||
@@ -598,6 +596,7 @@ import { ref, computed, nextTick, onMounted, onUnmounted } from 'vue';
|
|||||||
import type { Router } from 'framework7/types';
|
import type { Router } from 'framework7/types';
|
||||||
|
|
||||||
import { useI18n } from '@/locales/helpers.ts';
|
import { useI18n } from '@/locales/helpers.ts';
|
||||||
|
import { scrollToSelectedItem } from '@/lib/ui/common.ts';
|
||||||
import {
|
import {
|
||||||
type Framework7Dom,
|
type Framework7Dom,
|
||||||
useI18nUIComponents,
|
useI18nUIComponents,
|
||||||
@@ -606,7 +605,6 @@ import {
|
|||||||
onSwipeoutDeleted,
|
onSwipeoutDeleted,
|
||||||
getElementActualHeights,
|
getElementActualHeights,
|
||||||
getElementBoundingRect,
|
getElementBoundingRect,
|
||||||
scrollToSelectedItem,
|
|
||||||
onInfiniteScrolling
|
onInfiniteScrolling
|
||||||
} from '@/lib/ui/mobile.ts';
|
} from '@/lib/ui/mobile.ts';
|
||||||
import { TransactionListPageType, useTransactionListPageBase } from '@/views/base/transactions/TransactionListPageBase.ts';
|
import { TransactionListPageType, useTransactionListPageBase } from '@/views/base/transactions/TransactionListPageBase.ts';
|
||||||
@@ -1440,7 +1438,11 @@ function collapseTransactionMonthList(monthList: TransactionMonthList, collapse:
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onPopoverOpen(event: { $el: Framework7Dom }): void {
|
function onPopoverOpen(event: { $el: Framework7Dom }): void {
|
||||||
scrollToSelectedItem(event.$el, '.popover-inner', 'li.list-item-selected');
|
scrollToSelectedItem(event.$el[0], '.popover-inner', '.popover-inner', 'li.list-item-selected');
|
||||||
|
}
|
||||||
|
|
||||||
|
function onCategoryPopoverOpen(event: { $el: Framework7Dom }): void {
|
||||||
|
scrollToSelectedItem(event.$el[0], '.popover-inner', '.popover-inner', 'li.list-item-checked');
|
||||||
}
|
}
|
||||||
|
|
||||||
function onPageAfterIn(): void {
|
function onPageAfterIn(): void {
|
||||||
@@ -1604,10 +1606,7 @@ html[dir="rtl"] .list.transaction-info-list li.transaction-info .transaction-foo
|
|||||||
.account-popover-menu .popover-inner,
|
.account-popover-menu .popover-inner,
|
||||||
.more-popover-menu .popover-inner {
|
.more-popover-menu .popover-inner {
|
||||||
max-height: 400px;
|
max-height: 400px;
|
||||||
|
overflow-y: auto;
|
||||||
> .list {
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.transaction-calendar-container .dp__theme_light,
|
.transaction-calendar-container .dp__theme_light,
|
||||||
|
|||||||
Reference in New Issue
Block a user