feat(property): add Iranian date fields with Date conversion and fix edit coordinates/map loading
deploy-chabokan / deploy (push) Canceled after 0s
deploy-chabokan / deploy (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
/**
|
||||
* Jalali (Solar Hijri / Shamsi) calendar conversion utilities
|
||||
*/
|
||||
|
||||
export const persianMonths = [
|
||||
{ value: 1, label: 'فروردین' },
|
||||
{ value: 2, label: 'اردیبهشت' },
|
||||
{ value: 3, label: 'خرداد' },
|
||||
{ value: 4, label: 'تیر' },
|
||||
{ value: 5, label: 'مرداد' },
|
||||
{ value: 6, label: 'شهریور' },
|
||||
{ value: 7, label: 'مهر' },
|
||||
{ value: 8, label: 'آبان' },
|
||||
{ value: 9, label: 'آذر' },
|
||||
{ value: 10, label: 'دی' },
|
||||
{ value: 11, label: 'بهمن' },
|
||||
{ value: 12, label: 'اسفند' }
|
||||
];
|
||||
|
||||
/**
|
||||
* Converts Persian and Arabic digits in a string to English digits
|
||||
*/
|
||||
export function toEnglishDigits(str) {
|
||||
if (str === null || str === undefined) return '';
|
||||
return String(str)
|
||||
.replace(/[۰-۹]/g, (d) => '۰۱۲۳۴۵۶۷۸۹'.indexOf(d))
|
||||
.replace(/[٠-٩]/g, (d) => '٠١٢٣٤٥٦٧٨٩'.indexOf(d));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts Jalali date (year, month, day) to Gregorian date (gy, gm, gd)
|
||||
*/
|
||||
export function jalaliToGregorian(jy, jm, jd) {
|
||||
jy = Number(jy);
|
||||
jm = Number(jm);
|
||||
jd = Number(jd);
|
||||
|
||||
let gy = jy > 979 ? 1600 : 621;
|
||||
jy = jy > 979 ? jy - 979 : jy;
|
||||
|
||||
let days =
|
||||
365 * jy +
|
||||
Math.floor(jy / 33) * 8 +
|
||||
Math.floor(((jy % 33) + 3) / 4) +
|
||||
78 +
|
||||
jd +
|
||||
(jm < 7 ? (jm - 1) * 31 : (jm - 7) * 30 + 186);
|
||||
|
||||
gy += 400 * Math.floor(days / 146097);
|
||||
days %= 146097;
|
||||
|
||||
if (days > 36524) {
|
||||
gy += 100 * Math.floor(--days / 36524);
|
||||
days %= 36524;
|
||||
if (days >= 365) days++;
|
||||
}
|
||||
|
||||
gy += 4 * Math.floor(days / 1461);
|
||||
days %= 1461;
|
||||
|
||||
if (days > 365) {
|
||||
gy += Math.floor((days - 1) / 365);
|
||||
days = (days - 1) % 365;
|
||||
}
|
||||
|
||||
let gd = days + 1;
|
||||
const isLeap = (gy % 4 === 0 && gy % 100 !== 0) || gy % 400 === 0;
|
||||
const sal_a = [0, 31, isLeap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
||||
|
||||
let gm;
|
||||
for (gm = 0; gm < 13; gm++) {
|
||||
const v = sal_a[gm];
|
||||
if (gd <= v) break;
|
||||
gd -= v;
|
||||
}
|
||||
|
||||
return { gy, gm, gd };
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts Gregorian date (gy, gm, gd) to Jalali date (jy, jm, jd)
|
||||
*/
|
||||
export function gregorianToJalali(gy, gm, gd) {
|
||||
gy = Number(gy);
|
||||
gm = Number(gm);
|
||||
gd = Number(gd);
|
||||
|
||||
const g_d_m = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
|
||||
let jy = gy > 1600 ? 979 : 0;
|
||||
gy = gy > 1600 ? gy - 1600 : gy - 621;
|
||||
|
||||
const gy2 = gm > 2 ? gy + 1 : gy;
|
||||
let days =
|
||||
365 * gy +
|
||||
Math.floor((gy2 + 3) / 4) -
|
||||
Math.floor((gy2 + 99) / 100) +
|
||||
Math.floor((gy2 + 399) / 400) -
|
||||
80 +
|
||||
gd +
|
||||
g_d_m[gm - 1];
|
||||
|
||||
jy += 33 * Math.floor(days / 12053);
|
||||
days %= 12053;
|
||||
|
||||
jy += 4 * Math.floor(days / 1461);
|
||||
days %= 1461;
|
||||
|
||||
if (days > 365) {
|
||||
jy += Math.floor((days - 1) / 365);
|
||||
days = (days - 1) % 365;
|
||||
}
|
||||
|
||||
const jm = days < 186 ? 1 + Math.floor(days / 31) : 7 + Math.floor((days - 186) / 30);
|
||||
const jd = 1 + (days < 186 ? days % 31 : (days - 186) % 30);
|
||||
|
||||
return { jy, jm, jd };
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts Jalali year, month, day to a standard JS Date object at 12:00 UTC
|
||||
*/
|
||||
export function jalaliToDate(jy, jm, jd) {
|
||||
const y = parseInt(toEnglishDigits(jy), 10);
|
||||
const m = parseInt(toEnglishDigits(jm), 10);
|
||||
const d = parseInt(toEnglishDigits(jd), 10);
|
||||
|
||||
if (isNaN(y) || isNaN(m) || isNaN(d) || y <= 0 || m < 1 || m > 12 || d < 1 || d > 31) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { gy, gm, gd } = jalaliToGregorian(y, m, d);
|
||||
return new Date(Date.UTC(gy, gm - 1, gd, 12, 0, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a JS Date object, ISO string, or legacy Jalali string (YYYY/MM/DD) to { jy, jm, jd }
|
||||
*/
|
||||
export function parseDateToJalali(dateVal) {
|
||||
if (!dateVal) return null;
|
||||
|
||||
// Check if it's already a JS Date or ISO string
|
||||
if (dateVal instanceof Date || (typeof dateVal === 'string' && (dateVal.includes('T') || dateVal.includes('-')))) {
|
||||
const d = new Date(dateVal);
|
||||
if (!isNaN(d.getTime())) {
|
||||
return gregorianToJalali(d.getUTCFullYear(), d.getUTCMonth() + 1, d.getUTCDate());
|
||||
}
|
||||
}
|
||||
|
||||
// Check if it's a legacy string format e.g. "1399/04/15" or "۱۳۹۹/۰۴/۱۵"
|
||||
if (typeof dateVal === 'string' && dateVal.includes('/')) {
|
||||
const clean = toEnglishDigits(dateVal.trim());
|
||||
const parts = clean.split('/');
|
||||
if (parts.length === 3) {
|
||||
const jy = parseInt(parts[0], 10);
|
||||
const jm = parseInt(parts[1], 10);
|
||||
const jd = parseInt(parts[2], 10);
|
||||
if (!isNaN(jy) && !isNaN(jm) && !isNaN(jd)) {
|
||||
return { jy, jm, jd };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup>
|
||||
import { onBeforeMount, ref, watch, computed } from 'vue';
|
||||
import { onBeforeMount, ref, watch, computed, nextTick } from 'vue';
|
||||
import { useToast } from 'primevue/usetoast';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { CategoryService } from '@/service/CategoryService';
|
||||
@@ -9,7 +9,8 @@ import ImageUploader from '@/views/uikit/ImageUploader.vue';
|
||||
import ImageGallery from '@/views/uikit/ImageGallery.vue';
|
||||
import KiwiChips from '@/views/uikit/KiwiChips.vue';
|
||||
import MapComponent from '@/views/uikit/MapComponent.vue';
|
||||
import { UTMtoLatLon } from '@/utm';
|
||||
import { UTMtoLatLon, LatLontoUTM } from '@/utm';
|
||||
import { persianMonths, jalaliToDate, parseDateToJalali, toEnglishDigits } from '@/utils/jalali';
|
||||
|
||||
// PrimeVue Components
|
||||
import Dropdown from 'primevue/dropdown';
|
||||
@@ -37,6 +38,11 @@ const documentUrlsWithData = ref([]);
|
||||
const editMode = ref(false);
|
||||
const isSaving = ref(false);
|
||||
|
||||
// Registration Date Fields (Jalali: Year, Month, Day)
|
||||
const regYear = ref('');
|
||||
const regMonth = ref(null);
|
||||
const regDay = ref('');
|
||||
|
||||
const propertyTypes = ref([
|
||||
{ label: 'زمین', value: 'Land' },
|
||||
{ label: 'ساختمان', value: 'Building' }
|
||||
@@ -61,7 +67,7 @@ const property = ref({
|
||||
serialNumber: '',
|
||||
provinceRegistry: '',
|
||||
localRegistryOffice: '',
|
||||
registrationDate: '',
|
||||
registrationDate: null,
|
||||
documentUrls: [],
|
||||
mainImageUrls: [],
|
||||
location: {
|
||||
@@ -120,9 +126,10 @@ const property = ref({
|
||||
|
||||
// Map state
|
||||
const mapRef = ref(null);
|
||||
const easting = ref();
|
||||
const northing = ref();
|
||||
const zone = ref();
|
||||
const mapMarker = ref([]);
|
||||
const easting = ref('');
|
||||
const northing = ref('');
|
||||
const zone = ref('');
|
||||
const lat = ref();
|
||||
const long = ref();
|
||||
|
||||
@@ -148,18 +155,52 @@ const dongOptions = [
|
||||
{ value: 6, label: '۶ دانگ', fraction: 'تمام (مالکیت کامل)' },
|
||||
];
|
||||
|
||||
/**
|
||||
* Centrally updates lat, long, location, mapMarker, and UTM fields
|
||||
*/
|
||||
const setCoordinatesAndUTM = (latitude, longitude, utmE = null, utmN = null, utmZ = null) => {
|
||||
if (latitude !== null && longitude !== null && !isNaN(latitude) && !isNaN(longitude)) {
|
||||
const numLat = Number(latitude);
|
||||
const numLon = Number(longitude);
|
||||
lat.value = numLat;
|
||||
long.value = numLon;
|
||||
mapMarker.value = [numLat, numLon];
|
||||
property.value.location = {
|
||||
type: 'Point',
|
||||
coordinates: [numLon, numLat]
|
||||
};
|
||||
|
||||
if (utmE !== null && utmN !== null && utmZ !== null && utmE !== '' && utmN !== '' && utmZ !== '') {
|
||||
easting.value = String(utmE);
|
||||
northing.value = String(utmN);
|
||||
zone.value = String(utmZ);
|
||||
} else {
|
||||
const utm = LatLontoUTM(numLat, numLon);
|
||||
if (utm && !isNaN(utm.easting) && !isNaN(utm.northing)) {
|
||||
easting.value = String(Math.round(utm.easting));
|
||||
northing.value = String(Math.round(utm.northing));
|
||||
zone.value = String(utm.zoneNumber);
|
||||
}
|
||||
}
|
||||
|
||||
nextTick(() => {
|
||||
if (mapRef.value && typeof mapRef.value.setCenterAndMarker === 'function') {
|
||||
mapRef.value.setCenterAndMarker(numLat, numLon);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const convertUTMtoLatLng = () => {
|
||||
if (easting.value && northing.value && zone.value) {
|
||||
try {
|
||||
const result = UTMtoLatLon(
|
||||
Number(easting.value),
|
||||
Number(northing.value),
|
||||
Number(zone.value),
|
||||
'N'
|
||||
);
|
||||
lat.value = result.latitude;
|
||||
long.value = result.longitude;
|
||||
searchLocation(lat.value, long.value);
|
||||
const cleanE = Number(toEnglishDigits(easting.value));
|
||||
const cleanN = Number(toEnglishDigits(northing.value));
|
||||
const cleanZ = Number(toEnglishDigits(zone.value));
|
||||
const result = UTMtoLatLon(cleanE, cleanN, cleanZ, 'N');
|
||||
if (result && !isNaN(result.latitude) && !isNaN(result.longitude)) {
|
||||
setCoordinatesAndUTM(result.latitude, result.longitude, cleanE, cleanN, cleanZ);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error converting UTM to Lat/Lng:', error);
|
||||
}
|
||||
@@ -167,19 +208,37 @@ const convertUTMtoLatLng = () => {
|
||||
};
|
||||
|
||||
const handleMarkerUpdated = (coords) => {
|
||||
if (coords && Array.isArray(coords)) {
|
||||
if (coords && Array.isArray(coords) && coords.length === 2 && coords[0] !== undefined && coords[1] !== undefined) {
|
||||
const [cLat, cLon] = coords;
|
||||
setCoordinatesAndUTM(cLat, cLon);
|
||||
} else {
|
||||
mapMarker.value = [];
|
||||
lat.value = null;
|
||||
long.value = null;
|
||||
property.value.location = {
|
||||
type: 'Point',
|
||||
coordinates: [coords[1], coords[0]]
|
||||
coordinates: [0, 0]
|
||||
};
|
||||
lat.value = coords[0];
|
||||
long.value = coords[1];
|
||||
}
|
||||
};
|
||||
|
||||
const handleMapCleared = () => {
|
||||
property.value.nationalGeoCode = '';
|
||||
easting.value = '';
|
||||
northing.value = '';
|
||||
zone.value = '';
|
||||
lat.value = null;
|
||||
long.value = null;
|
||||
mapMarker.value = [];
|
||||
property.value.location = {
|
||||
type: 'Point',
|
||||
coordinates: [0, 0]
|
||||
};
|
||||
};
|
||||
|
||||
const searchLocation = (latitude, longitude) => {
|
||||
if (mapRef.value && latitude && longitude) {
|
||||
mapRef.value.setCenterAndMarker(Number(latitude), Number(longitude));
|
||||
if (latitude && longitude) {
|
||||
setCoordinatesAndUTM(latitude, longitude);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -193,7 +252,8 @@ let geoCodeDebounceTimeout = null;
|
||||
* If the code doesn't match the 15-digit pattern, falls back to zone 39.
|
||||
*/
|
||||
const parseNationalGeoCode = (code) => {
|
||||
const digits = code.replace(/\D/g, ''); // strip non-digits
|
||||
if (!code) return null;
|
||||
const digits = toEnglishDigits(String(code)).replace(/\D/g, ''); // strip non-digits
|
||||
if (digits.length === 15) {
|
||||
// Standard JAM: 6 easting + 7 northing + 2 zone
|
||||
const e = parseInt(digits.slice(0, 6), 10);
|
||||
@@ -211,18 +271,16 @@ const parseNationalGeoCode = (code) => {
|
||||
};
|
||||
|
||||
const applyNationalGeoCode = (val) => {
|
||||
if (!val) return;
|
||||
// 1. Try parsing as a JAM UTM code (15-digit or 13-digit)
|
||||
const parsed = parseNationalGeoCode(val);
|
||||
if (parsed) {
|
||||
try {
|
||||
const result = UTMtoLatLon(parsed.easting, parsed.northing, parsed.zone, 'N');
|
||||
lat.value = result.latitude;
|
||||
long.value = result.longitude;
|
||||
easting.value = parsed.easting;
|
||||
northing.value = parsed.northing;
|
||||
zone.value = parsed.zone;
|
||||
searchLocation(result.latitude, result.longitude);
|
||||
if (result && !isNaN(result.latitude) && !isNaN(result.longitude)) {
|
||||
setCoordinatesAndUTM(result.latitude, result.longitude, parsed.easting, parsed.northing, parsed.zone);
|
||||
return;
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('UTM conversion failed:', err);
|
||||
}
|
||||
@@ -237,7 +295,7 @@ const handleNationalGeoCodeChange = () => {
|
||||
const val = property.value.nationalGeoCode?.trim();
|
||||
if (!val) return;
|
||||
|
||||
const digits = val.replace(/\D/g, '');
|
||||
const digits = toEnglishDigits(val).replace(/\D/g, '');
|
||||
|
||||
// Fire immediately once a full 15-digit JAM code is complete — no waiting
|
||||
if (digits.length === 15) {
|
||||
@@ -399,6 +457,39 @@ onBeforeMount(async () => {
|
||||
property.value = { ...property.value, ...data };
|
||||
featuresValues.value = extractFeaturesValues(data.features);
|
||||
|
||||
// 1. Parse registrationDate into Jalali Year, Month, Day
|
||||
if (data.registrationDate) {
|
||||
const jDate = parseDateToJalali(data.registrationDate);
|
||||
if (jDate) {
|
||||
regYear.value = String(jDate.jy);
|
||||
regMonth.value = jDate.jm;
|
||||
regDay.value = String(jDate.jd).padStart(2, '0');
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Initialize Coordinates, UTM fields, and Map Marker
|
||||
if (data.nationalGeoCode) {
|
||||
const parsed = parseNationalGeoCode(data.nationalGeoCode);
|
||||
if (parsed) {
|
||||
try {
|
||||
const result = UTMtoLatLon(parsed.easting, parsed.northing, parsed.zone, 'N');
|
||||
if (result && !isNaN(result.latitude) && !isNaN(result.longitude)) {
|
||||
setCoordinatesAndUTM(result.latitude, result.longitude, parsed.easting, parsed.northing, parsed.zone);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('UTM conversion error on load:', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to location.coordinates if mapMarker not set yet
|
||||
if ((!mapMarker.value || mapMarker.value.length === 0) && data.location?.coordinates && Array.isArray(data.location.coordinates) && data.location.coordinates.length === 2) {
|
||||
const [cLon, cLat] = data.location.coordinates;
|
||||
if ((cLon !== 0 || cLat !== 0) && !isNaN(cLon) && !isNaN(cLat)) {
|
||||
setCoordinatesAndUTM(cLat, cLon);
|
||||
}
|
||||
}
|
||||
|
||||
const mainImages = (data.signedMainImageUrls && data.signedMainImageUrls.length > 0)
|
||||
? data.signedMainImageUrls
|
||||
: (data.mainImageUrls || []);
|
||||
@@ -438,6 +529,14 @@ const saveProperty = async () => {
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert Jalali date to standard Date object
|
||||
if (regYear.value && regMonth.value && regDay.value) {
|
||||
const dObj = jalaliToDate(regYear.value, regMonth.value, regDay.value);
|
||||
property.value.registrationDate = dObj ? dObj.toISOString() : null;
|
||||
} else {
|
||||
property.value.registrationDate = null;
|
||||
}
|
||||
|
||||
isSaving.value = true;
|
||||
try {
|
||||
property.value.mainImageUrls = (mainImageUrlsWithData.value || [])
|
||||
@@ -587,10 +686,46 @@ const saveProperty = async () => {
|
||||
<InputText v-model="property.localRegistryOffice" placeholder="مثلاً: کرج - ناحیه ۱" class="w-full !rounded-xl" fluid />
|
||||
</div>
|
||||
|
||||
<!-- 5. تاریخ ثبت -->
|
||||
<!-- 5. تاریخ ثبت سند -->
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-surface-700 dark:text-surface-200 mb-1.5">تاریخ ثبت</label>
|
||||
<InputText v-model="property.registrationDate" placeholder="مثلاً: ۱۳۹۹/۰۴/۱۵" class="w-full !rounded-xl" fluid />
|
||||
<label class="block text-sm font-medium text-surface-700 dark:text-surface-200 mb-1.5">
|
||||
تاریخ ثبت سند
|
||||
</label>
|
||||
<div class="grid grid-cols-12 gap-2 items-center">
|
||||
<!-- روز -->
|
||||
<div class="col-span-3">
|
||||
<InputText
|
||||
v-model="regDay"
|
||||
placeholder="روز"
|
||||
class="w-full !rounded-xl text-center"
|
||||
maxlength="2"
|
||||
fluid
|
||||
/>
|
||||
</div>
|
||||
<!-- ماه -->
|
||||
<div class="col-span-5">
|
||||
<Dropdown
|
||||
v-model="regMonth"
|
||||
:options="persianMonths"
|
||||
optionLabel="label"
|
||||
optionValue="value"
|
||||
placeholder="انتخاب ماه"
|
||||
class="w-full !rounded-xl"
|
||||
showClear
|
||||
fluid
|
||||
/>
|
||||
</div>
|
||||
<!-- سال -->
|
||||
<div class="col-span-4">
|
||||
<InputText
|
||||
v-model="regYear"
|
||||
placeholder="سال (مثلاً ۱۴۰۲)"
|
||||
class="w-full !rounded-xl text-center"
|
||||
maxlength="4"
|
||||
fluid
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Auto Name Preview -->
|
||||
@@ -918,9 +1053,10 @@ const saveProperty = async () => {
|
||||
<div class="h-[600px] rounded-xl overflow-hidden border border-surface-200 dark:border-surface-800">
|
||||
<MapComponent
|
||||
ref="mapRef"
|
||||
v-model="mapMarker"
|
||||
:locked="!!property.nationalGeoCode?.trim()"
|
||||
@marker-updated="handleMarkerUpdated"
|
||||
@cleared="property.nationalGeoCode = ''"
|
||||
@cleared="handleMapCleared"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
@click="handleClick($event)"
|
||||
@mousemove="handleMouseMove($event)"
|
||||
@mouseout="hoverCoords = null"
|
||||
@ready="onMapReady"
|
||||
>
|
||||
<!-- Layer switcher -->
|
||||
<l-control-layers position="bottomright" />
|
||||
@@ -274,20 +275,44 @@ const handleClick = (event) => {
|
||||
emit('marker-updated', coords);
|
||||
};
|
||||
|
||||
// ── Ready handler ──────────────────────────────────────────────────────────
|
||||
const onMapReady = () => {
|
||||
if (Array.isArray(marker.value) && marker.value.length === 2 && marker.value[0] && marker.value[1]) {
|
||||
center.value = [...marker.value];
|
||||
zoom.value = 16;
|
||||
nextTick(() => {
|
||||
if (map.value?.leafletObject) {
|
||||
map.value.leafletObject.setView(marker.value, 16);
|
||||
map.value.leafletObject.invalidateSize();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// ── Sync modelValue prop → marker ──────────────────────────────────────────
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val) => {
|
||||
if (Array.isArray(val) && val.length === 2) {
|
||||
marker.value = [...val];
|
||||
center.value = [...val];
|
||||
if (Array.isArray(val) && val.length === 2 && val[0] && val[1]) {
|
||||
const newCoords = [parseFloat(val[0]), parseFloat(val[1])];
|
||||
marker.value = newCoords;
|
||||
center.value = newCoords;
|
||||
zoom.value = 16;
|
||||
nextTick(() => {
|
||||
if (map.value?.leafletObject) {
|
||||
map.value.leafletObject.flyTo(newCoords, 16, { animate: true, duration: 0.8 });
|
||||
map.value.leafletObject.invalidateSize();
|
||||
}
|
||||
});
|
||||
} else if (Array.isArray(val) && val.length === 0) {
|
||||
marker.value = [];
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
{ immediate: true, deep: true }
|
||||
);
|
||||
|
||||
// ── Expose to parent ───────────────────────────────────────────────────────
|
||||
defineExpose({ searchByCoordinates: setMarker, setCenterAndMarker: setMarker, searchLocation });
|
||||
defineExpose({ searchByCoordinates: setMarker, setCenterAndMarker: setMarker, searchLocation, onMapReady });
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
Reference in New Issue
Block a user