diff --git a/.storybook/main.ts b/.storybook/main.ts deleted file mode 100644 index cca485b..0000000 --- a/.storybook/main.ts +++ /dev/null @@ -1,46 +0,0 @@ -import path from 'node:path' -import type { StorybookConfig } from '@storybook/vue3-vite' -import vue from '@vitejs/plugin-vue' - -const config: StorybookConfig = { - stories: ['../app/components/**/*.stories.@(js|ts)'], - addons: ['@storybook/addon-essentials', '@storybook/addon-interactions'], - framework: { - name: '@storybook/vue3-vite', - options: {} - }, - core: { - disableTelemetry: true - }, - docs: { - autodocs: false - }, - viteFinal: async (baseConfig) => { - const projectRoot = path.resolve(__dirname, '..') - baseConfig.resolve = baseConfig.resolve || {} - baseConfig.resolve.alias = { - ...baseConfig.resolve.alias, - '~': path.resolve(__dirname, '../app'), - '@': path.resolve(__dirname, '../app'), - '@graphql-typed-document-node/core': path.resolve(__dirname, './shims/graphql-typed-document-node-core.ts') - } - baseConfig.plugins = baseConfig.plugins || [] - baseConfig.plugins.push(vue()) - baseConfig.root = projectRoot - baseConfig.server = { - ...(baseConfig.server || {}), - fs: { - ...(baseConfig.server?.fs || {}), - allow: Array.from( - new Set([ - ...(baseConfig.server?.fs?.allow || []), - projectRoot - ]) - ) - } - } - return baseConfig - } -} - -export default config diff --git a/.storybook/preview.ts b/.storybook/preview.ts deleted file mode 100644 index 2dd4ec9..0000000 --- a/.storybook/preview.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { Preview } from '@storybook/vue3' -import { setup } from '@storybook/vue3' - -import '../app/assets/css/tailwind.css' - -setup((app) => { - app.config.globalProperties.$t = (key: string) => key - app.config.globalProperties.$d = (value: any) => value -}) - -const preview: Preview = { - parameters: { - actions: { argTypesRegex: '^on[A-Z].*' }, - controls: { - matchers: { - color: /(background|color)$/i, - date: /Date$/ - } - } - } -} - -export default preview diff --git a/.storybook/shims/graphql-typed-document-node-core.ts b/.storybook/shims/graphql-typed-document-node-core.ts deleted file mode 100644 index 90030ff..0000000 --- a/.storybook/shims/graphql-typed-document-node-core.ts +++ /dev/null @@ -1,10 +0,0 @@ -// Minimal runtime shim so Vite/Storybook can resolve generated GraphQL imports. -import type { DocumentNode } from 'graphql' - -export type TypedDocumentNode> = DocumentNode & { - __resultType?: TResult - __variablesType?: TVariables -} - -// Runtime placeholder; generated files import the symbol but do not use the value. -export const TypedDocumentNode = {} as unknown as TypedDocumentNode diff --git a/app/components/BankSearchRussia.stories.ts b/app/components/BankSearchRussia.stories.ts deleted file mode 100644 index af669de..0000000 --- a/app/components/BankSearchRussia.stories.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/vue3' -import StoryComponent from './BankSearchRussia.vue' - -const meta: Meta = { - title: 'BankSearchRussia', - component: StoryComponent, - render: (args) => ({ - components: { StoryComponent }, - setup() { - return { args } - }, - template: '' - }) -} - -export default meta -type Story = StoryObj - -export const Primary: Story = { - args: {} -} diff --git a/app/components/BankSearchRussia.vue b/app/components/BankSearchRussia.vue index 13349c4..e230734 100644 --- a/app/components/BankSearchRussia.vue +++ b/app/components/BankSearchRussia.vue @@ -66,15 +66,24 @@ const props = withDefaults(defineProps(), { const emit = defineEmits() +interface BankSuggestion { + value: string + data: { + bic: string + correspondent_account?: string + address?: { value: string } + } +} + const query = ref('') -const suggestions = ref([]) +const suggestions = ref([]) const loading = ref(false) const showDropdown = ref(false) // Hide dropdown when clicking outside onMounted(() => { - document.addEventListener('click', (e) => { - if (!e.target?.closest('.relative')) { + document.addEventListener('click', (e: MouseEvent) => { + if (!(e.target as HTMLElement)?.closest('.relative')) { showDropdown.value = false } }) diff --git a/app/components/CabinetBreadcrumbs.vue b/app/components/CabinetBreadcrumbs.vue index ed7addc..e05538a 100644 --- a/app/components/CabinetBreadcrumbs.vue +++ b/app/components/CabinetBreadcrumbs.vue @@ -44,6 +44,7 @@ const breadcrumbs = computed(() => { let currentPath = '/clientarea' for (let i = 0; i < segments.length; i++) { const segment = segments[i] + if (!segment) continue currentPath += `/${segment}` const isLast = i === segments.length - 1 diff --git a/app/components/CalcResultContent.stories.ts b/app/components/CalcResultContent.stories.ts deleted file mode 100644 index dc94921..0000000 --- a/app/components/CalcResultContent.stories.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/vue3' -import StoryComponent from './CalcResultContent.vue' - -const meta: Meta = { - title: 'CalcResultContent', - component: StoryComponent, - render: (args) => ({ - components: { StoryComponent }, - setup() { - return { args } - }, - template: '' - }) -} - -export default meta -type Story = StoryObj - -export const Primary: Story = { - args: {} -} diff --git a/app/components/CalcResultContent.vue b/app/components/CalcResultContent.vue index 97fadff..56c0277 100644 --- a/app/components/CalcResultContent.vue +++ b/app/components/CalcResultContent.vue @@ -18,8 +18,8 @@
import { GetNodeDocument, NearestOffersDocument, RouteToCoordinateDocument } from '~/composables/graphql/public/geo-generated' import type { RouteStageItem } from '~/components/RouteStagesList.vue' + +interface RouteStage { + fromUuid?: string | null + fromName?: string | null + toName?: string | null + distanceKm?: number | null + travelTimeSeconds?: number | null + transportType?: string | null +} + +interface RoutePathType { + totalDistanceKm?: number | null + totalTimeSeconds?: number | null + stages?: (RouteStage | null)[] +} import { GetOfferDocument, GetSupplierProfileByTeamDocument } from '~/composables/graphql/public/exchange-generated' const route = useRoute() @@ -140,8 +155,8 @@ const fetchOffersByHub = async () => { RouteToCoordinateDocument, { offerUuid: offer.uuid, - lat: hub.latitude, - lon: hub.longitude + lat: hub.latitude!, + lon: hub.longitude! }, 'public', 'geo' @@ -186,7 +201,7 @@ const productRouteOptions = computed(() => { return options?.filter(Boolean) || [] }) -const legacyRoutes = computed(() => { +const legacyRoutes = computed(() => { return [] // Legacy routes removed }) diff --git a/app/components/CompanyCard.stories.ts b/app/components/CompanyCard.stories.ts deleted file mode 100644 index 276f991..0000000 --- a/app/components/CompanyCard.stories.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/vue3' -import StoryComponent from './CompanyCard.vue' - -const meta: Meta = { - title: 'CompanyCard', - component: StoryComponent, - render: (args) => ({ - components: { StoryComponent }, - setup() { - return { args } - }, - template: '' - }) -} - -export default meta -type Story = StoryObj - -export const Primary: Story = { - args: {} -} diff --git a/app/components/CompanySearchRussia.stories.ts b/app/components/CompanySearchRussia.stories.ts deleted file mode 100644 index 1bc64f2..0000000 --- a/app/components/CompanySearchRussia.stories.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/vue3' -import StoryComponent from './CompanySearchRussia.vue' - -const meta: Meta = { - title: 'CompanySearchRussia', - component: StoryComponent, - render: (args) => ({ - components: { StoryComponent }, - setup() { - return { args } - }, - template: '' - }) -} - -export default meta -type Story = StoryObj - -export const Primary: Story = { - args: {} -} diff --git a/app/components/CompanySearchRussia.vue b/app/components/CompanySearchRussia.vue index 6b6b71b..d319a2c 100644 --- a/app/components/CompanySearchRussia.vue +++ b/app/components/CompanySearchRussia.vue @@ -48,13 +48,24 @@ interface CompanyData { address: string } +interface CompanySuggestion { + value: string + unrestricted_value: string + data: { + inn: string + kpp?: string + ogrn?: string + address?: { value: string } + } +} + interface Props { modelValue?: CompanyData } interface Emits { (e: 'update:modelValue', value: CompanyData): void - (e: 'select', company: any): void + (e: 'select', company: CompanySuggestion): void } const props = withDefaults(defineProps(), { @@ -71,14 +82,14 @@ const props = withDefaults(defineProps(), { const emit = defineEmits() const query = ref('') -const suggestions = ref([]) +const suggestions = ref([]) const loading = ref(false) const showDropdown = ref(false) // Hide dropdown when clicking outside onMounted(() => { - document.addEventListener('click', (e) => { - if (!e.target?.closest('.relative')) { + document.addEventListener('click', (e: MouseEvent) => { + if (!(e.target as HTMLElement)?.closest('.relative')) { showDropdown.value = false } }) @@ -118,10 +129,10 @@ const onInput = async () => { } } -const selectCompany = (company: any) => { +const selectCompany = (company: CompanySuggestion) => { query.value = company.value showDropdown.value = false - + const companyData: CompanyData = { companyName: company.value, companyFullName: company.unrestricted_value, @@ -130,7 +141,7 @@ const selectCompany = (company: any) => { ogrn: company.data.ogrn || '', address: company.data.address?.value || '' } - + emit('update:modelValue', companyData) emit('select', company) } diff --git a/app/components/FooterPublic.stories.ts b/app/components/FooterPublic.stories.ts deleted file mode 100644 index 8830c3b..0000000 --- a/app/components/FooterPublic.stories.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/vue3' -import StoryComponent from './FooterPublic.vue' - -const meta: Meta = { - title: 'FooterPublic', - component: StoryComponent, - render: (args) => ({ - components: { StoryComponent }, - setup() { - return { args } - }, - template: '' - }) -} - -export default meta -type Story = StoryObj - -export const Primary: Story = { - args: {} -} diff --git a/app/components/GanttTimeline.stories.ts b/app/components/GanttTimeline.stories.ts deleted file mode 100644 index 7fc3726..0000000 --- a/app/components/GanttTimeline.stories.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/vue3' -import StoryComponent from './GanttTimeline.vue' - -const meta: Meta = { - title: 'GanttTimeline', - component: StoryComponent, - render: (args) => ({ - components: { StoryComponent }, - setup() { - return { args } - }, - template: '' - }) -} - -export default meta -type Story = StoryObj - -export const Primary: Story = { - args: {} -} diff --git a/app/components/GoodsContent.stories.ts b/app/components/GoodsContent.stories.ts deleted file mode 100644 index 256e704..0000000 --- a/app/components/GoodsContent.stories.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/vue3' -import StoryComponent from './GoodsContent.vue' - -const meta: Meta = { - title: 'GoodsContent', - component: StoryComponent, - render: (args) => ({ - components: { StoryComponent }, - setup() { - return { args } - }, - template: '' - }) -} - -export default meta -type Story = StoryObj - -export const Primary: Story = { - args: {} -} diff --git a/app/components/GoodsContent.vue b/app/components/GoodsContent.vue index a770e05..eef9a8d 100644 --- a/app/components/GoodsContent.vue +++ b/app/components/GoodsContent.vue @@ -24,11 +24,11 @@ diff --git a/app/components/KYCFormRussia.stories.ts b/app/components/KYCFormRussia.stories.ts deleted file mode 100644 index b574106..0000000 --- a/app/components/KYCFormRussia.stories.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/vue3' -import StoryComponent from './KYCFormRussia.vue' - -const meta: Meta = { - title: 'KYCFormRussia', - component: StoryComponent, - render: (args) => ({ - components: { StoryComponent }, - setup() { - return { args } - }, - template: '' - }) -} - -export default meta -type Story = StoryObj - -export const Primary: Story = { - args: {} -} diff --git a/app/components/KycProfileCard.vue b/app/components/KycProfileCard.vue index 4cbf5c8..1dd2a44 100644 --- a/app/components/KycProfileCard.vue +++ b/app/components/KycProfileCard.vue @@ -112,8 +112,8 @@ const profileData = ref<{ address?: string | null director?: string | null capital?: string | null - activities?: string[] | null - sources?: string[] | null + activities?: (string | null)[] | null + sources?: (string | null)[] | null lastUpdated?: string | null } | null>(null) diff --git a/app/components/LangSwitcher.stories.ts b/app/components/LangSwitcher.stories.ts deleted file mode 100644 index 4036f2b..0000000 --- a/app/components/LangSwitcher.stories.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/vue3' -import StoryComponent from './LangSwitcher.vue' - -const meta: Meta = { - title: 'LangSwitcher', - component: StoryComponent, - render: (args) => ({ - components: { StoryComponent }, - setup() { - return { args } - }, - template: '' - }) -} - -export default meta -type Story = StoryObj - -export const Primary: Story = { - args: {} -} diff --git a/app/components/LocationsContent.stories.ts b/app/components/LocationsContent.stories.ts deleted file mode 100644 index c606ca2..0000000 --- a/app/components/LocationsContent.stories.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/vue3' -import StoryComponent from './LocationsContent.vue' - -const meta: Meta = { - title: 'LocationsContent', - component: StoryComponent, - render: (args) => ({ - components: { StoryComponent }, - setup() { - return { args } - }, - template: '' - }) -} - -export default meta -type Story = StoryObj - -export const Primary: Story = { - args: {} -} diff --git a/app/components/LocationsContent.vue b/app/components/LocationsContent.vue index e993483..9fb170f 100644 --- a/app/components/LocationsContent.vue +++ b/app/components/LocationsContent.vue @@ -86,7 +86,7 @@ const calculateDistance = (lat: number, lng: number) => { // Load logistics hubs const { data: locationsDataRaw, pending, error, refresh } = await useServerQuery('locations', GetNodesDocument, {}, 'public', 'geo') const locationsData = computed(() => { - return (locationsDataRaw.value || []).map((location: any) => ({ + return (locationsDataRaw.value?.nodes || []).map((location: any) => ({ ...location, distance: location?.latitude && location?.longitude ? calculateDistance(location.latitude, location.longitude) diff --git a/app/components/MapboxGlobe.client.stories.ts b/app/components/MapboxGlobe.client.stories.ts deleted file mode 100644 index 463d689..0000000 --- a/app/components/MapboxGlobe.client.stories.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/vue3' -import StoryComponent from './MapboxGlobe.client.vue' - -const meta: Meta = { - title: 'MapboxGlobe.client', - component: StoryComponent, - render: (args) => ({ - components: { StoryComponent }, - setup() { - return { args } - }, - template: '' - }) -} - -export default meta -type Story = StoryObj - -export const Primary: Story = { - args: {} -} diff --git a/app/components/MapboxGlobe.client.vue b/app/components/MapboxGlobe.client.vue index abd4ddb..87e2045 100644 --- a/app/components/MapboxGlobe.client.vue +++ b/app/components/MapboxGlobe.client.vue @@ -228,15 +228,16 @@ const onMapCreated = (map: MapboxMap) => { // Click on cluster to zoom in map.on('click', 'clusters', (e) => { const features = map.queryRenderedFeatures(e.point, { layers: ['clusters'] }) - if (!features.length) return + const feature = features[0] + if (!feature) return - const clusterId = features[0].properties?.cluster_id + const clusterId = feature.properties?.cluster_id const source = map.getSource('locations') as mapboxgl.GeoJSONSource source.getClusterExpansionZoom(clusterId, (err, zoom) => { if (err) return - const geometry = features[0].geometry as GeoJSON.Point + const geometry = feature.geometry as GeoJSON.Point map.easeTo({ center: geometry.coordinates as [number, number], zoom: zoom || 4 @@ -247,10 +248,11 @@ const onMapCreated = (map: MapboxMap) => { // Click on individual point map.on('click', 'unclustered-point', (e) => { const features = map.queryRenderedFeatures(e.point, { layers: ['unclustered-point'] }) - if (!features.length) return + const feature = features[0] + if (!feature) return - const featureProps = features[0].properties - const geometry = features[0].geometry as GeoJSON.Point + const featureProps = feature.properties + const geometry = feature.geometry as GeoJSON.Point const location: Location = { uuid: featureProps?.uuid, diff --git a/app/components/NearbyConnectionsSection.vue b/app/components/NearbyConnectionsSection.vue index d564221..9a59adc 100644 --- a/app/components/NearbyConnectionsSection.vue +++ b/app/components/NearbyConnectionsSection.vue @@ -38,8 +38,8 @@
@@ -70,8 +70,8 @@ @@ -292,8 +292,10 @@ const addHubSource = (map: MapboxMapType, id: string, hub: CurrentHub, color: st }) map.on('click', `${id}-circle`, (e) => { - const coordinates = (e.features![0].geometry as GeoJSON.Point).coordinates.slice() as [number, number] - const name = e.features![0].properties?.name + const feature = e.features?.[0] + if (!feature) return + const coordinates = (feature.geometry as GeoJSON.Point).coordinates.slice() as [number, number] + const name = feature.properties?.name new Popup() .setLngLat(coordinates) @@ -390,8 +392,10 @@ const onMapCreated = (map: MapboxMapType) => { }) const onNeighborsClick = (e: mapboxgl.MapLayerMouseEvent) => { - const coordinates = (e.features![0].geometry as GeoJSON.Point).coordinates.slice() as [number, number] - const featureProps = e.features![0].properties + const feature = e.features?.[0] + if (!feature) return + const coordinates = (feature.geometry as GeoJSON.Point).coordinates.slice() as [number, number] + const featureProps = feature.properties const name = featureProps?.name const distanceKm = featureProps?.distanceKm diff --git a/app/components/NearbyHubsSection.vue b/app/components/NearbyHubsSection.vue index 539ac63..69b65f0 100644 --- a/app/components/NearbyHubsSection.vue +++ b/app/components/NearbyHubsSection.vue @@ -37,8 +37,8 @@
@@ -304,8 +304,10 @@ const onMapCreated = (map: MapboxMapType) => { // Popups on click map.on('click', 'current-hub-circle', (e) => { - const coordinates = (e.features![0].geometry as GeoJSON.Point).coordinates.slice() as [number, number] - const name = e.features![0].properties?.name + const feature = e.features?.[0] + if (!feature) return + const coordinates = (feature.geometry as GeoJSON.Point).coordinates.slice() as [number, number] + const name = feature.properties?.name new Popup() .setLngLat(coordinates) @@ -314,8 +316,10 @@ const onMapCreated = (map: MapboxMapType) => { }) map.on('click', 'neighbors-circles', (e) => { - const coordinates = (e.features![0].geometry as GeoJSON.Point).coordinates.slice() as [number, number] - const featureProps = e.features![0].properties + const feature = e.features?.[0] + if (!feature) return + const coordinates = (feature.geometry as GeoJSON.Point).coordinates.slice() as [number, number] + const featureProps = feature.properties const name = featureProps?.name const distanceKm = featureProps?.distanceKm diff --git a/app/components/NovuNotificationBell.client.stories.ts b/app/components/NovuNotificationBell.client.stories.ts deleted file mode 100644 index 74cd986..0000000 --- a/app/components/NovuNotificationBell.client.stories.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/vue3' -import StoryComponent from './NovuNotificationBell.client.vue' - -const meta: Meta = { - title: 'NovuNotificationBell.client', - component: StoryComponent, - render: (args) => ({ - components: { StoryComponent }, - setup() { - return { args } - }, - template: '' - }) -} - -export default meta -type Story = StoryObj - -export const Primary: Story = { - args: {} -} diff --git a/app/components/OrderCalendar.stories.ts b/app/components/OrderCalendar.stories.ts deleted file mode 100644 index 00368bc..0000000 --- a/app/components/OrderCalendar.stories.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/vue3' -import StoryComponent from './OrderCalendar.vue' - -const meta: Meta = { - title: 'OrderCalendar', - component: StoryComponent, - render: (args) => ({ - components: { StoryComponent }, - setup() { - return { args } - }, - template: '' - }) -} - -export default meta -type Story = StoryObj - -export const Primary: Story = { - args: {} -} diff --git a/app/components/OrderMap.stories.ts b/app/components/OrderMap.stories.ts deleted file mode 100644 index 1423fd9..0000000 --- a/app/components/OrderMap.stories.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/vue3' -import StoryComponent from './OrderMap.vue' - -const meta: Meta = { - title: 'OrderMap', - component: StoryComponent, - render: (args) => ({ - components: { StoryComponent }, - setup() { - return { args } - }, - template: '' - }) -} - -export default meta -type Story = StoryObj - -export const Primary: Story = { - args: {} -} diff --git a/app/components/OrderTimeline.stories.ts b/app/components/OrderTimeline.stories.ts deleted file mode 100644 index 94c6d6c..0000000 --- a/app/components/OrderTimeline.stories.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/vue3' -import StoryComponent from './OrderTimeline.vue' - -const meta: Meta = { - title: 'OrderTimeline', - component: StoryComponent, - render: (args) => ({ - components: { StoryComponent }, - setup() { - return { args } - }, - template: '' - }) -} - -export default meta -type Story = StoryObj - -export const Primary: Story = { - args: {} -} diff --git a/app/components/OrdersRoutesMap.client.vue b/app/components/OrdersRoutesMap.client.vue index 347614c..b2ec056 100644 --- a/app/components/OrdersRoutesMap.client.vue +++ b/app/components/OrdersRoutesMap.client.vue @@ -120,7 +120,7 @@ const fetchRouteGeometry = async (stage: RouteStage): Promise<[number, number][] fromLon: stage.fromLon, toLat: stage.toLat, toLon: stage.toLon - }, 'public', 'geo') + }, 'public', 'geo') as Record const geometry = routeData?.[routeField]?.geometry if (typeof geometry === 'string') { @@ -363,13 +363,15 @@ const onMapCreated = (map: MapboxMapType) => { // Click on marker map.on('click', 'orders-markers-circles', (e) => { - const props = e.features?.[0]?.properties + const feature = e.features?.[0] + if (!feature) return + const props = feature.properties const orderId = props?.orderId if (orderId) { emit('select-order', orderId) } - const coordinates = (e.features?.[0].geometry as GeoJSON.Point).coordinates.slice() as [number, number] + const coordinates = (feature.geometry as GeoJSON.Point).coordinates.slice() as [number, number] new Popup() .setLngLat(coordinates) .setHTML(`${props?.name || 'Point'}
${props?.orderName || ''}`) diff --git a/app/components/RequestRoutesMap.vue b/app/components/RequestRoutesMap.vue index 10ded7e..4fbda1d 100644 --- a/app/components/RequestRoutesMap.vue +++ b/app/components/RequestRoutesMap.vue @@ -90,6 +90,7 @@ const routeMarkers = computed(() => { if (!stages.length) return const first = stages[0] const last = stages[stages.length - 1] + if (!first || !last) return if (typeof first.fromLat === 'number' && typeof first.fromLon === 'number') { markers.push({ @@ -183,7 +184,7 @@ const fetchStageGeometry = async (stage: RouteStage, routeIndex: number, stageIn const RouteDocument = stage.transportType === 'auto' ? GetAutoRouteDocument : GetRailRouteDocument const routeField = stage.transportType === 'auto' ? 'autoRoute' : 'railRoute' - const routeData = await execute(RouteDocument, { fromLat, fromLon, toLat, toLon }, 'public', 'geo') + const routeData = await execute(RouteDocument, { fromLat, fromLon, toLat, toLon }, 'public', 'geo') as Record const geometry = routeData?.[routeField]?.geometry if (typeof geometry === 'string') { @@ -341,8 +342,10 @@ const onMapCreated = (map: MapboxMapType) => { }) map.on('click', 'request-markers-circles', (e) => { - const coordinates = (e.features?.[0].geometry as GeoJSON.Point).coordinates.slice() as [number, number] - const featureProps = e.features?.[0].properties + const feature = e.features?.[0] + if (!feature) return + const coordinates = (feature.geometry as GeoJSON.Point).coordinates.slice() as [number, number] + const featureProps = feature.properties const title = featureProps?.name || 'Точка' const label = featureProps?.label || '' diff --git a/app/components/RouteMap.stories.ts b/app/components/RouteMap.stories.ts deleted file mode 100644 index b4efbcb..0000000 --- a/app/components/RouteMap.stories.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/vue3' -import StoryComponent from './RouteMap.vue' - -const meta: Meta = { - title: 'RouteMap', - component: StoryComponent, - render: (args) => ({ - components: { StoryComponent }, - setup() { - return { args } - }, - template: '' - }) -} - -export default meta -type Story = StoryObj - -export const Primary: Story = { - args: {} -} diff --git a/app/components/RouteMap.vue b/app/components/RouteMap.vue index 1558394..cef63a5 100644 --- a/app/components/RouteMap.vue +++ b/app/components/RouteMap.vue @@ -227,8 +227,10 @@ const onMapCreated = (map: MapboxMapType) => { }) map.on('click', 'route-points-layer', (e) => { - const coordinates = (e.features?.[0].geometry as GeoJSON.Point).coordinates.slice() as [number, number] - const props = e.features?.[0].properties + const feature = e.features?.[0] + if (!feature) return + const coordinates = (feature.geometry as GeoJSON.Point).coordinates.slice() as [number, number] + const props = feature.properties const name = props?.name || t('routeMap.points.service') new Popup() diff --git a/app/components/TeamCard.stories.ts b/app/components/TeamCard.stories.ts deleted file mode 100644 index 57a2fa8..0000000 --- a/app/components/TeamCard.stories.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/vue3' -import StoryComponent from './TeamCard.vue' - -const meta: Meta = { - title: 'TeamCard', - component: StoryComponent, - render: (args) => ({ - components: { StoryComponent }, - setup() { - return { args } - }, - template: '' - }) -} - -export default meta -type Story = StoryObj - -export const Primary: Story = { - args: {} -} diff --git a/app/components/TeamCard.vue b/app/components/TeamCard.vue index 55cee85..0d178aa 100644 --- a/app/components/TeamCard.vue +++ b/app/components/TeamCard.vue @@ -40,6 +40,19 @@ diff --git a/app/components/catalog/CatalogHubsSection.vue b/app/components/catalog/CatalogHubsSection.vue index b48ebc0..081a31b 100644 --- a/app/components/catalog/CatalogHubsSection.vue +++ b/app/components/catalog/CatalogHubsSection.vue @@ -17,8 +17,8 @@ {{ country.name }} diff --git a/app/components/catalog/CatalogMap.vue b/app/components/catalog/CatalogMap.vue index 2f27c38..ceab260 100644 --- a/app/components/catalog/CatalogMap.vue +++ b/app/components/catalog/CatalogMap.vue @@ -319,20 +319,22 @@ const initClientClusteringLayers = async (map: MapboxMapType) => { map.on('click', 'clusters', (e) => { const features = map.queryRenderedFeatures(e.point, { layers: ['clusters'] }) - if (!features.length) return - const clusterId = features[0].properties?.cluster_id + const feature = features[0] + if (!feature) return + const clusterId = feature.properties?.cluster_id const source = map.getSource(sourceId.value) as mapboxgl.GeoJSONSource source.getClusterExpansionZoom(clusterId, (err, zoom) => { if (err) return - const geometry = features[0].geometry as GeoJSON.Point + const geometry = feature.geometry as GeoJSON.Point map.easeTo({ center: geometry.coordinates as [number, number], zoom: zoom || 4 }) }) }) map.on('click', 'unclustered-point', (e) => { const features = map.queryRenderedFeatures(e.point, { layers: ['unclustered-point'] }) - if (!features.length) return - emit('select-item', features[0].properties?.uuid) + const feature = features[0] + if (!feature) return + emit('select-item', feature.properties?.uuid) }) map.on('mouseenter', 'clusters', () => { map.getCanvas().style.cursor = 'pointer' }) @@ -406,8 +408,9 @@ const initClientClusteringLayers = async (map: MapboxMapType) => { // Click handlers for related points map.on('click', `${props.mapId}-related-circles`, (e) => { const features = map.queryRenderedFeatures(e.point, { layers: [`${props.mapId}-related-circles`] }) - if (!features.length) return - const props_data = features[0].properties + const feature = features[0] + if (!feature) return + const props_data = feature.properties as Record | undefined emit('select-item', props_data?.uuid, props_data) }) @@ -500,9 +503,10 @@ const initServerClusteringLayers = async (map: MapboxMapType) => { // Click on cluster to zoom in map.on('click', 'server-clusters', (e) => { const features = map.queryRenderedFeatures(e.point, { layers: ['server-clusters'] }) - if (!features.length) return - const expansionZoom = features[0].properties?.expansionZoom - const geometry = features[0].geometry as GeoJSON.Point + const feature = features[0] + if (!feature) return + const expansionZoom = feature.properties?.expansionZoom + const geometry = feature.geometry as GeoJSON.Point map.easeTo({ center: geometry.coordinates as [number, number], zoom: expansionZoom || map.getZoom() + 2 @@ -512,8 +516,9 @@ const initServerClusteringLayers = async (map: MapboxMapType) => { // Click on individual point - emit full properties map.on('click', 'server-points', (e) => { const features = map.queryRenderedFeatures(e.point, { layers: ['server-points'] }) - if (!features.length) return - const props = features[0].properties || {} + const feature = features[0] + if (!feature) return + const props = feature.properties || {} emit('select-item', props.id, props) }) @@ -588,8 +593,9 @@ const initServerClusteringLayers = async (map: MapboxMapType) => { // Click handlers for related points map.on('click', `${props.mapId}-related-circles`, (e) => { const features = map.queryRenderedFeatures(e.point, { layers: [`${props.mapId}-related-circles`] }) - if (!features.length) return - const props_data = features[0].properties + const feature = features[0] + if (!feature) return + const props_data = feature.properties as Record | undefined emit('select-item', props_data?.uuid, props_data) }) diff --git a/app/components/catalog/CatalogMapPanel.vue b/app/components/catalog/CatalogMapPanel.vue index 8b227c1..31d7b8e 100644 --- a/app/components/catalog/CatalogMapPanel.vue +++ b/app/components/catalog/CatalogMapPanel.vue @@ -23,8 +23,8 @@