mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-14 06:57:35 +08:00
support clicking on map to set specified geographic location
This commit is contained in:
@@ -13,7 +13,8 @@ import { ref, computed, useTemplateRef } from 'vue';
|
||||
|
||||
import { useI18n } from '@/locales/helpers.ts';
|
||||
|
||||
import type { MapInstance, MapPosition } from '@/lib/map/base.ts';
|
||||
import type { MapPosition } from '@/core/map.ts';
|
||||
import type { MapInstance } from '@/lib/map/base.ts';
|
||||
import { createMapInstance } from '@/lib/map/index.ts';
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -23,6 +24,10 @@ const props = defineProps<{
|
||||
geoLocation?: MapPosition;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'click', geoLocation: MapPosition): void;
|
||||
}>();
|
||||
|
||||
const { tt, getCurrentLanguageInfo } = useI18n();
|
||||
|
||||
const mapContainer = useTemplateRef<HTMLElement>('mapContainer');
|
||||
@@ -86,6 +91,9 @@ function initMapView(): void {
|
||||
text: {
|
||||
zoomIn: tt('Zoom in'),
|
||||
zoomOut: tt('Zoom out'),
|
||||
},
|
||||
onClick: (geoLocation: MapPosition) => {
|
||||
emit('click', geoLocation);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -105,7 +113,18 @@ function initMapView(): void {
|
||||
}
|
||||
}
|
||||
|
||||
function setMarkerPosition(geoLocation?: MapPosition): void {
|
||||
if (!mapInstance.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (geoLocation) {
|
||||
mapInstance.value.setMapCenterMarker(geoLocation);
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
initMapView
|
||||
initMapView,
|
||||
setMarkerPosition
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -3,13 +3,16 @@
|
||||
:opened="show" @sheet:open="onSheetOpen" @sheet:closed="onSheetClosed">
|
||||
<f7-toolbar>
|
||||
<div class="swipe-handler"></div>
|
||||
<div class="left"></div>
|
||||
<div class="left">
|
||||
<f7-link :text="tt('Disable Click to Set Location')" @click="switchSetGeoLocationByClickMap(false)" v-if="isSupportGetGeoLocationByClick() && props.setGeoLocationByClickMap"></f7-link>
|
||||
<f7-link :text="tt('Enable Click to Set Location')" @click="switchSetGeoLocationByClickMap(true)" v-if="isSupportGetGeoLocationByClick() && !props.setGeoLocationByClickMap"></f7-link>
|
||||
</div>
|
||||
<div class="right">
|
||||
<f7-link :text="tt('Done')" @click="save"></f7-link>
|
||||
</div>
|
||||
</f7-toolbar>
|
||||
<f7-page-content class="no-margin-vertical no-padding-vertical">
|
||||
<map-view ref="map" height="400px" :geo-location="geoLocation">
|
||||
<map-view ref="map" height="400px" :geo-location="geoLocation" @click="updateSpecifiedGeoLocation">
|
||||
<template #error-title="{ mapSupported, mapDependencyLoaded }">
|
||||
<div class="display-flex padding justify-content-space-between align-items-center">
|
||||
<div class="ebk-sheet-title" v-if="!mapSupported"><b>{{ tt('Unsupported Map Provider') }}</b></div>
|
||||
@@ -36,17 +39,21 @@ import MapView from '@/components/common/MapView.vue';
|
||||
|
||||
import { useI18n } from '@/locales/helpers.ts';
|
||||
|
||||
import type { MapPosition } from '@/lib/map/base.ts';
|
||||
import type { MapPosition } from '@/core/map.ts';
|
||||
|
||||
import { isSupportGetGeoLocationByClick } from '@/lib/map/index.ts';
|
||||
|
||||
type MapViewType = InstanceType<typeof MapView>;
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue?: MapPosition;
|
||||
setGeoLocationByClickMap?: boolean;
|
||||
show: boolean;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:modelValue', value: MapPosition | undefined): void;
|
||||
(e: 'update:setGeoLocationByClickMap', value: boolean): void;
|
||||
(e: 'update:show', value: boolean): void;
|
||||
}>();
|
||||
|
||||
@@ -63,6 +70,17 @@ const geoLocation = computed<MapPosition | undefined>({
|
||||
}
|
||||
});
|
||||
|
||||
function updateSpecifiedGeoLocation(mapPosition: MapPosition): void {
|
||||
if (isSupportGetGeoLocationByClick() && props.setGeoLocationByClickMap) {
|
||||
geoLocation.value = mapPosition;
|
||||
map.value?.setMarkerPosition(mapPosition);
|
||||
}
|
||||
}
|
||||
|
||||
function switchSetGeoLocationByClickMap(value: boolean): void {
|
||||
emit('update:setGeoLocationByClickMap', value);
|
||||
}
|
||||
|
||||
function save(): void {
|
||||
emit('update:show', false);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface MapPosition {
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
}
|
||||
+15
-1
@@ -1,6 +1,7 @@
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-nocheck
|
||||
import type { MapProvider, MapInstance, MapInstanceInitOptions, MapPosition } from './base.ts';
|
||||
import type { MapPosition } from '@/core/map.ts';
|
||||
import type { MapProvider, MapInstance, MapInstanceInitOptions } from './base.ts';
|
||||
|
||||
import { asyncLoadAssets } from '@/lib/misc.ts';
|
||||
import services from '@/lib/services.ts';
|
||||
@@ -18,6 +19,10 @@ export class AmapMapProvider implements MapProvider {
|
||||
return 'https://www.amap.com';
|
||||
}
|
||||
|
||||
public isSupportGetGeoLocationByClick(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
public asyncLoadAssets(language?: string): Promise<unknown> {
|
||||
if (AmapMapProvider.AMap) {
|
||||
@@ -86,6 +91,15 @@ export class AmapMapInstance implements MapInstance {
|
||||
});
|
||||
amapInstance.addControl(amapToolbar);
|
||||
|
||||
amapInstance.on('click', function(e) {
|
||||
if (options.onClick) {
|
||||
options.onClick({
|
||||
latitude: e.lnglat.lat,
|
||||
longitude: e.lnglat.lng
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.amapInstance = amapInstance;
|
||||
this.amapToolbar = amapToolbar;
|
||||
this.inited = true;
|
||||
|
||||
+15
-1
@@ -1,6 +1,7 @@
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-nocheck
|
||||
import type { MapProvider, MapInstance, MapInstanceInitOptions, MapPosition } from './base.ts';
|
||||
import type { MapPosition } from '@/core/map.ts';
|
||||
import type { MapProvider, MapInstance, MapInstanceInitOptions } from './base.ts';
|
||||
|
||||
import { asyncLoadAssets } from '@/lib/misc.ts';
|
||||
import services from '@/lib/services.ts';
|
||||
@@ -17,6 +18,10 @@ export class BaiduMapProvider implements MapProvider {
|
||||
return 'https://map.baidu.com';
|
||||
}
|
||||
|
||||
public isSupportGetGeoLocationByClick(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
public asyncLoadAssets(language?: string): Promise<unknown> {
|
||||
if (BaiduMapProvider.BMap) {
|
||||
@@ -76,6 +81,15 @@ export class BaiduMapInstance implements MapInstance {
|
||||
baiduMapInstance.addControl(baiduMapNavigationControl);
|
||||
baiduMapInstance.centerAndZoom(new BMap.Point(options.initCenter.longitude, options.initCenter.latitude), options.zoomLevel);
|
||||
|
||||
baiduMapInstance.addEventListener('click', function(e) {
|
||||
if (options.onClick) {
|
||||
options.onClick({
|
||||
latitude: e.point.lat,
|
||||
longitude: e.point.lng
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.baiduMapInstance = baiduMapInstance;
|
||||
this.baiduMapConverter = new BMap.Convertor();
|
||||
this.baiduMapNavigationControl = baiduMapNavigationControl;
|
||||
|
||||
+5
-6
@@ -1,5 +1,8 @@
|
||||
import type { MapPosition } from '@/core/map.ts';
|
||||
|
||||
export interface MapProvider {
|
||||
getWebsite(): string;
|
||||
isSupportGetGeoLocationByClick(): boolean;
|
||||
asyncLoadAssets(language?: string): Promise<unknown>;
|
||||
createMapInstance(): MapInstance | null;
|
||||
}
|
||||
@@ -22,10 +25,6 @@ export interface MapInstanceInitOptions {
|
||||
readonly text: {
|
||||
readonly zoomIn: string;
|
||||
readonly zoomOut: string;
|
||||
}
|
||||
}
|
||||
|
||||
export interface MapPosition {
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
};
|
||||
readonly onClick?: (position: MapPosition) => void;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-nocheck
|
||||
import type { MapProvider, MapInstance, MapInstanceInitOptions, MapPosition } from './base.ts';
|
||||
import type { MapPosition } from '@/core/map.ts';
|
||||
import type { MapProvider, MapInstance, MapInstanceInitOptions } from './base.ts';
|
||||
|
||||
import { asyncLoadAssets } from '@/lib/misc.ts';
|
||||
import services from '@/lib/services.ts';
|
||||
@@ -15,6 +16,10 @@ export class GoogleMapProvider implements MapProvider {
|
||||
return 'https://maps.google.com';
|
||||
}
|
||||
|
||||
public isSupportGetGeoLocationByClick(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
public asyncLoadAssets(language?: string): Promise<unknown> {
|
||||
if (GoogleMapProvider.GoogleMap) {
|
||||
return Promise.resolve();
|
||||
@@ -76,6 +81,16 @@ export class GoogleMapInstance implements MapInstance {
|
||||
position: GoogleMapProvider.ControlPosition.LEFT_TOP
|
||||
}
|
||||
});
|
||||
|
||||
this.googleMapInstance.addListener('click', function(e) {
|
||||
if (options.onClick) {
|
||||
options.onClick({
|
||||
latitude: e.latLng.lat(),
|
||||
longitude: e.latLng.lng()
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.inited = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,10 @@ export function getMapWebsite(): string {
|
||||
return mapProvider?.getWebsite() || '';
|
||||
}
|
||||
|
||||
export function isSupportGetGeoLocationByClick(): boolean {
|
||||
return mapProvider?.isSupportGetGeoLocationByClick() || false;
|
||||
}
|
||||
|
||||
export function createMapInstance(): MapInstance | null {
|
||||
return mapProvider?.createMapInstance() || null;
|
||||
}
|
||||
|
||||
+16
-1
@@ -1,8 +1,10 @@
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-nocheck
|
||||
import type { MapPosition } from '@/core/map.ts';
|
||||
|
||||
import { type LeafletTileSource, type LeafletTileSourceExtraParam, LEAFLET_TILE_SOURCES } from '@/consts/map.ts';
|
||||
|
||||
import type { MapProvider, MapInstance, MapInstanceInitOptions, MapPosition } from './base.ts';
|
||||
import type { MapProvider, MapInstance, MapInstanceInitOptions } from './base.ts';
|
||||
|
||||
import {
|
||||
isMapDataFetchProxyEnabled,
|
||||
@@ -35,6 +37,10 @@ export class LeafletMapProvider implements MapProvider {
|
||||
}
|
||||
}
|
||||
|
||||
public isSupportGetGeoLocationByClick(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
public asyncLoadAssets(language?: string): Promise<unknown> {
|
||||
return Promise.all([
|
||||
@@ -158,6 +164,15 @@ export class LeafletMapInstance implements MapInstance {
|
||||
this.leafletAttribution = attribution;
|
||||
}
|
||||
|
||||
leafletInstance.addEventListener('click', function(e) {
|
||||
if (options.onClick) {
|
||||
options.onClick({
|
||||
latitude: e.latlng.lat,
|
||||
longitude: e.latlng.lng
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.leafletInstance = leafletInstance;
|
||||
this.leafletTileLayer = tileLayer;
|
||||
this.leafletZoomControl = zoomControl;
|
||||
|
||||
@@ -1639,6 +1639,9 @@
|
||||
"Location on Map": "Standort auf der Karte",
|
||||
"Update Geographic Location": "Geografischen Standort aktualisieren",
|
||||
"Clear Geographic Location": "Geografischen Standort löschen",
|
||||
"Click on Map to Set Geographic Location": "Click on Map to Set Geographic Location",
|
||||
"Enable Click to Set Location": "Enable Click to Set Location",
|
||||
"Disable Click to Set Location": "Disable Click to Set Location",
|
||||
"Unable to retrieve current position": "Aktuelle Position kann nicht abgerufen werden",
|
||||
"Cannot Initialize Map": "Karte kann nicht initialisiert werden",
|
||||
"Unsupported Map Provider": "Nicht unterstützter Kartenanbieter",
|
||||
|
||||
@@ -1639,6 +1639,9 @@
|
||||
"Location on Map": "Location on Map",
|
||||
"Update Geographic Location": "Update Geographic Location",
|
||||
"Clear Geographic Location": "Clear Geographic Location",
|
||||
"Click on Map to Set Geographic Location": "Click on Map to Set Geographic Location",
|
||||
"Enable Click to Set Location": "Enable Click to Set Location",
|
||||
"Disable Click to Set Location": "Disable Click to Set Location",
|
||||
"Unable to retrieve current position": "Unable to retrieve current position",
|
||||
"Cannot Initialize Map": "Cannot Initialize Map",
|
||||
"Unsupported Map Provider": "Unsupported Map Provider",
|
||||
|
||||
@@ -1638,6 +1638,9 @@
|
||||
"Location on Map": "Ubicación en el mapa",
|
||||
"Update Geographic Location": "Actualizar ubicación geográfica",
|
||||
"Clear Geographic Location": "Borrar ubicación geográfica",
|
||||
"Click on Map to Set Geographic Location": "Click on Map to Set Geographic Location",
|
||||
"Enable Click to Set Location": "Enable Click to Set Location",
|
||||
"Disable Click to Set Location": "Disable Click to Set Location",
|
||||
"Unable to retrieve current position": "No se puede recuperar la posición actual",
|
||||
"Cannot Initialize Map": "No se puede inicializar el mapa",
|
||||
"Unsupported Map Provider": "Proveedor de mapas no compatible",
|
||||
|
||||
@@ -1639,6 +1639,9 @@
|
||||
"Location on Map": "Posizione sulla mappa",
|
||||
"Update Geographic Location": "Aggiorna posizione geografica",
|
||||
"Clear Geographic Location": "Cancella posizione geografica",
|
||||
"Click on Map to Set Geographic Location": "Click on Map to Set Geographic Location",
|
||||
"Enable Click to Set Location": "Enable Click to Set Location",
|
||||
"Disable Click to Set Location": "Disable Click to Set Location",
|
||||
"Unable to retrieve current position": "Impossibile recuperare la posizione corrente",
|
||||
"Cannot Initialize Map": "Impossibile inizializzare la mappa",
|
||||
"Unsupported Map Provider": "Fornitore mappa non supportato",
|
||||
|
||||
@@ -1639,6 +1639,9 @@
|
||||
"Location on Map": "マップ上の座標",
|
||||
"Update Geographic Location": "地理座標の更新",
|
||||
"Clear Geographic Location": "地理座標を削除",
|
||||
"Click on Map to Set Geographic Location": "Click on Map to Set Geographic Location",
|
||||
"Enable Click to Set Location": "Enable Click to Set Location",
|
||||
"Disable Click to Set Location": "Disable Click to Set Location",
|
||||
"Unable to retrieve current position": "現在位置を取得できません",
|
||||
"Cannot Initialize Map": "マップを初期化できません",
|
||||
"Unsupported Map Provider": "サポートされていないマッププロバイダーです",
|
||||
|
||||
@@ -1639,6 +1639,9 @@
|
||||
"Location on Map": "Местоположение на карте",
|
||||
"Update Geographic Location": "Обновить географическое местоположение",
|
||||
"Clear Geographic Location": "Очистить географическое местоположение",
|
||||
"Click on Map to Set Geographic Location": "Click on Map to Set Geographic Location",
|
||||
"Enable Click to Set Location": "Enable Click to Set Location",
|
||||
"Disable Click to Set Location": "Disable Click to Set Location",
|
||||
"Unable to retrieve current position": "Не удалось получить текущее местоположение",
|
||||
"Cannot Initialize Map": "Не удалось инициализировать карту",
|
||||
"Unsupported Map Provider": "Неподдерживаемый поставщик карт",
|
||||
|
||||
@@ -1639,6 +1639,9 @@
|
||||
"Location on Map": "Розташування на карті",
|
||||
"Update Geographic Location": "Оновити геолокацію",
|
||||
"Clear Geographic Location": "Очистити геолокацію",
|
||||
"Click on Map to Set Geographic Location": "Click on Map to Set Geographic Location",
|
||||
"Enable Click to Set Location": "Enable Click to Set Location",
|
||||
"Disable Click to Set Location": "Disable Click to Set Location",
|
||||
"Unable to retrieve current position": "Не вдалося отримати поточне розташування",
|
||||
"Cannot Initialize Map": "Не вдалося ініціалізувати карту",
|
||||
"Unsupported Map Provider": "Непідтримуваний провайдер карт",
|
||||
|
||||
@@ -1639,6 +1639,9 @@
|
||||
"Location on Map": "Vị trí trên bản đồ",
|
||||
"Update Geographic Location": "Cập nhật vị trí địa lý",
|
||||
"Clear Geographic Location": "Xóa vị trí địa lý",
|
||||
"Click on Map to Set Geographic Location": "Click on Map to Set Geographic Location",
|
||||
"Enable Click to Set Location": "Enable Click to Set Location",
|
||||
"Disable Click to Set Location": "Disable Click to Set Location",
|
||||
"Unable to retrieve current position": "Không thể lấy vị trí hiện tại",
|
||||
"Cannot Initialize Map": "Không thể khởi tạo bản đồ",
|
||||
"Unsupported Map Provider": "Nhà cung cấp bản đồ không được hỗ trợ",
|
||||
|
||||
@@ -1639,6 +1639,9 @@
|
||||
"Location on Map": "地图上的位置",
|
||||
"Update Geographic Location": "更新地理位置",
|
||||
"Clear Geographic Location": "清除地理位置",
|
||||
"Click on Map to Set Geographic Location": "地图上点击设置地理位置",
|
||||
"Enable Click to Set Location": "启用点击设置位置",
|
||||
"Disable Click to Set Location": "禁用点击设置位置",
|
||||
"Unable to retrieve current position": "无法获取当前地理位置",
|
||||
"Cannot Initialize Map": "无法初始化地图",
|
||||
"Unsupported Map Provider": "不支持的地图提供方",
|
||||
|
||||
@@ -1639,6 +1639,9 @@
|
||||
"Location on Map": "地圖上的位置",
|
||||
"Update Geographic Location": "更新地理位置",
|
||||
"Clear Geographic Location": "清除地理位置",
|
||||
"Click on Map to Set Geographic Location": "地圖上點選設定地理位置",
|
||||
"Enable Click to Set Location": "啟用點選設定位置",
|
||||
"Disable Click to Set Location": "停用點選設定位置",
|
||||
"Unable to retrieve current position": "無法取得目前位置",
|
||||
"Cannot Initialize Map": "無法初始化地圖",
|
||||
"Unsupported Map Provider": "不支援的地圖提供者",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { PartialRecord } from '@/core/base.ts';
|
||||
import type { YearMonth, StartEndTime } from '@/core/datetime.ts';
|
||||
import type { MapPosition } from '@/core/map.ts';
|
||||
import { TransactionType } from '@/core/transaction.ts';
|
||||
|
||||
import { Account, type AccountInfoResponse } from './account.ts';
|
||||
@@ -72,6 +73,11 @@ export class Transaction implements TransactionInfoResponse {
|
||||
return this._geoLocation;
|
||||
}
|
||||
|
||||
|
||||
public set geoLocation(value: MapPosition) {
|
||||
this._geoLocation = TransactionGeoLocation.of(value);
|
||||
}
|
||||
|
||||
public get categoryId(): string {
|
||||
return this.getCategoryId();
|
||||
}
|
||||
@@ -404,8 +410,8 @@ export class TransactionGeoLocation implements TransactionGeoLocationRequest {
|
||||
return new TransactionGeoLocation(latitude, longitude);
|
||||
}
|
||||
|
||||
public static of(geoLocation: TransactionGeoLocationRequest): TransactionGeoLocation {
|
||||
return new TransactionGeoLocation(geoLocation.latitude, geoLocation.longitude);
|
||||
public static of(mapPosition: MapPosition): TransactionGeoLocation {
|
||||
return new TransactionGeoLocation(mapPosition.latitude, mapPosition.longitude);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -496,10 +502,7 @@ export interface TransactionListInMonthByPageRequest {
|
||||
readonly keyword: string;
|
||||
}
|
||||
|
||||
export interface TransactionGeoLocationResponse {
|
||||
readonly latitude: number;
|
||||
readonly longitude: number;
|
||||
}
|
||||
export type TransactionGeoLocationResponse = MapPosition;
|
||||
|
||||
export interface TransactionInfoResponse {
|
||||
readonly id: string;
|
||||
|
||||
@@ -79,6 +79,7 @@ export function useTransactionEditPageBase(type: TransactionEditPageType, initMo
|
||||
const submitting = ref<boolean>(false);
|
||||
const uploadingPicture = ref<boolean>(false);
|
||||
const geoLocationStatus = ref<GeoLocationStatus | null>(null);
|
||||
const setGeoLocationByClickMap = ref<boolean>(false);
|
||||
|
||||
const transaction = ref<Transaction | TransactionTemplate>(createNewTransactionModel(transactionDefaultType));
|
||||
|
||||
@@ -378,6 +379,7 @@ export function useTransactionEditPageBase(type: TransactionEditPageType, initMo
|
||||
submitting,
|
||||
uploadingPicture,
|
||||
geoLocationStatus,
|
||||
setGeoLocationByClickMap,
|
||||
transaction,
|
||||
// computed states
|
||||
currentTimezoneOffsetMinutes,
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
<v-progress-circular indeterminate size="22" class="ml-2" v-if="loading"></v-progress-circular>
|
||||
</div>
|
||||
<v-btn density="comfortable" color="default" variant="text" class="ml-2" :icon="true"
|
||||
:disabled="loading || submitting" v-if="mode !== TransactionEditPageMode.View">
|
||||
:disabled="loading || submitting" v-if="mode !== TransactionEditPageMode.View && (activeTab === 'basicInfo' || (activeTab === 'map' && isSupportGetGeoLocationByClick()))">
|
||||
<v-icon :icon="mdiDotsVertical" />
|
||||
<v-menu activator="parent">
|
||||
<v-list>
|
||||
<v-list v-if="activeTab === 'basicInfo'">
|
||||
<v-list-item :prepend-icon="mdiSwapHorizontal"
|
||||
:title="tt('Swap Account')"
|
||||
v-if="transaction.type === TransactionType.Transfer"
|
||||
@@ -32,6 +32,19 @@
|
||||
:title="tt('Hide Amount')"
|
||||
v-if="!transaction.hideAmount" @click="transaction.hideAmount = true"></v-list-item>
|
||||
</v-list>
|
||||
<v-list v-if="activeTab === 'map'">
|
||||
<v-list-item key="setGeoLocationByClickMap" value="setGeoLocationByClickMap"
|
||||
:prepend-icon="mdiMapMarkerOutline"
|
||||
:disabled="!transaction.geoLocation" v-if="isSupportGetGeoLocationByClick()">
|
||||
<v-list-item-title class="cursor-pointer" @click="setGeoLocationByClickMap = !setGeoLocationByClickMap; geoMenuState = false">
|
||||
<div class="d-flex align-center">
|
||||
<span>{{ tt('Click on Map to Set Geographic Location') }}</span>
|
||||
<v-spacer/>
|
||||
<v-icon :icon="mdiCheck" v-if="setGeoLocationByClickMap" />
|
||||
</div>
|
||||
</v-list-item-title>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</v-btn>
|
||||
</div>
|
||||
@@ -346,7 +359,7 @@
|
||||
<v-window-item value="map">
|
||||
<v-row>
|
||||
<v-col cols="12" md="12">
|
||||
<map-view ref="map" map-class="transaction-edit-map-view" :geo-location="transaction.geoLocation">
|
||||
<map-view ref="map" map-class="transaction-edit-map-view" :geo-location="transaction.geoLocation" @click="updateSpecifiedGeoLocation">
|
||||
<template #error-title="{ mapSupported, mapDependencyLoaded }">
|
||||
<span class="text-subtitle-1" v-if="!mapSupported"><b>{{ tt('Unsupported Map Provider') }}</b></span>
|
||||
<span class="text-subtitle-1" v-else-if="!mapDependencyLoaded"><b>{{ tt('Cannot Initialize Map') }}</b></span>
|
||||
@@ -463,6 +476,7 @@ import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
||||
import { useTransactionsStore } from '@/stores/transaction.ts';
|
||||
import { useTransactionTemplatesStore } from '@/stores/transactionTemplate.ts';
|
||||
|
||||
import type { MapPosition } from '@/core/map.ts';
|
||||
import { CategoryType } from '@/core/category.ts';
|
||||
import { TransactionType, TransactionEditScopeType } from '@/core/transaction.ts';
|
||||
import { TemplateType, ScheduledTemplateFrequencyType } from '@/core/template.ts';
|
||||
@@ -488,6 +502,9 @@ import {
|
||||
isTransactionPicturesEnabled,
|
||||
getMapProvider
|
||||
} from '@/lib/server_settings.ts';
|
||||
import {
|
||||
isSupportGetGeoLocationByClick
|
||||
} from '@/lib/map/index.ts';
|
||||
import logger from '@/lib/logger.ts';
|
||||
|
||||
import {
|
||||
@@ -495,6 +512,8 @@ import {
|
||||
mdiEyeOffOutline,
|
||||
mdiEyeOutline,
|
||||
mdiSwapHorizontal,
|
||||
mdiMapMarkerOutline,
|
||||
mdiCheck,
|
||||
mdiPound,
|
||||
mdiMenuDown,
|
||||
mdiImagePlusOutline,
|
||||
@@ -537,6 +556,7 @@ const {
|
||||
submitting,
|
||||
uploadingPicture,
|
||||
geoLocationStatus,
|
||||
setGeoLocationByClickMap,
|
||||
transaction,
|
||||
defaultCurrency,
|
||||
defaultAccountId,
|
||||
@@ -671,6 +691,7 @@ function open(options: TransactionEditOptions): Promise<TransactionEditResponse
|
||||
loading.value = true;
|
||||
submitting.value = false;
|
||||
geoLocationStatus.value = null;
|
||||
setGeoLocationByClickMap.value = false;
|
||||
originalTransactionEditable.value = false;
|
||||
|
||||
initCategoryId.value = options.categoryId;
|
||||
@@ -1044,6 +1065,13 @@ function updateGeoLocation(forceUpdate: boolean): void {
|
||||
geoLocationStatus.value = GeoLocationStatus.Getting;
|
||||
}
|
||||
|
||||
function updateSpecifiedGeoLocation(mapPosition: MapPosition): void {
|
||||
if (isSupportGetGeoLocationByClick() && setGeoLocationByClickMap.value) {
|
||||
transaction.value.setLatitudeAndLongitude(mapPosition.latitude, mapPosition.longitude);
|
||||
map.value?.setMarkerPosition(transaction.value.geoLocation);
|
||||
}
|
||||
}
|
||||
|
||||
function clearGeoLocation(): void {
|
||||
geoMenuState.value = false;
|
||||
geoLocationStatus.value = null;
|
||||
|
||||
@@ -344,6 +344,7 @@
|
||||
</template>
|
||||
|
||||
<map-sheet v-model="transaction.geoLocation"
|
||||
v-model:set-geo-location-by-click-map="setGeoLocationByClickMap"
|
||||
v-model:show="showGeoLocationMapSheet">
|
||||
</map-sheet>
|
||||
</f7-list-item>
|
||||
@@ -549,6 +550,7 @@ const {
|
||||
submitting,
|
||||
uploadingPicture,
|
||||
geoLocationStatus,
|
||||
setGeoLocationByClickMap,
|
||||
transaction,
|
||||
currentTimezoneOffsetMinutes,
|
||||
defaultCurrency,
|
||||
|
||||
Reference in New Issue
Block a user