diff --git a/examples/snowbox/index.html b/examples/snowbox/index.html index 79a0317df1..14ee71a948 100644 --- a/examples/snowbox/index.html +++ b/examples/snowbox/index.html @@ -58,6 +58,7 @@

POLAR map client

+
Coordinates of currently selected feature:
diff --git a/examples/snowbox/index.js b/examples/snowbox/index.js index ea0bc33808..44dc6c16ed 100644 --- a/examples/snowbox/index.js +++ b/examples/snowbox/index.js @@ -572,3 +572,16 @@ document colorScheme = colorScheme === 'light' ? 'dark' : 'light' updateState(map, 'core', 'colorScheme', colorScheme) }) + +let filterItem = null +document + .getElementById('toggle-filter') + .addEventListener('click', ({ target }) => { + const store = getStore(map, 'iconMenu') + if (!filterItem) { + ;[filterItem] = store.menus.splice(1, 1) + } else { + store.menus.splice(1, 0, filterItem) + filterItem = null + } + }) diff --git a/src/plugins/filter/store.ts b/src/plugins/filter/store.ts index 340db586c6..23eb01dd62 100644 --- a/src/plugins/filter/store.ts +++ b/src/plugins/filter/store.ts @@ -52,10 +52,12 @@ export const useFilterStore = defineStore('plugins/filter', () => { { deep: true, immediate: true } ) ) + teardownCallbacks.push(callback) }) } function teardownPlugin() { + filterMainStore.state = {} teardownCallbacks.forEach((callback) => { callback() }) diff --git a/src/plugins/iconMenu/components/NineRegionsButton.ce.vue b/src/plugins/iconMenu/components/NineRegionsButton.ce.vue index 8bb25a50d5..e7ec75ee16 100644 --- a/src/plugins/iconMenu/components/NineRegionsButton.ce.vue +++ b/src/plugins/iconMenu/components/NineRegionsButton.ce.vue @@ -13,7 +13,6 @@ import { storeToRefs } from 'pinia' import { computed, inject } from 'vue' import PolarIconButton from '@/components/PolarIconButton.ce.vue' -import { useCoreStore } from '@/core/stores' import { useIconMenuStore } from '../store' @@ -30,13 +29,7 @@ const active = computed(() => open.value === props.id) const updateMaxWidth = inject('updateMaxWidth') as () => void function toggle() { - if (open.value === props.id) { - open.value = null - useCoreStore().setMoveHandle(null) - } else { - open.value = props.id - iconMenuStore.openInMoveHandle(props.id) - } + open.value = open.value === props.id ? null : props.id updateMaxWidth() } diff --git a/src/plugins/iconMenu/components/StandardMenuList.ce.vue b/src/plugins/iconMenu/components/StandardMenuList.ce.vue index 1b0df4448f..3485ee63f9 100644 --- a/src/plugins/iconMenu/components/StandardMenuList.ce.vue +++ b/src/plugins/iconMenu/components/StandardMenuList.ce.vue @@ -122,13 +122,7 @@ function updateMaxWidth() { } function toggle(id: string) { - if (open.value === id) { - open.value = null - coreStore.setMoveHandle(null) - } else { - open.value = id - iconMenuStore.openInMoveHandle(id) - } + open.value = open.value === id ? null : id updateMaxWidth() } diff --git a/src/plugins/iconMenu/store.ts b/src/plugins/iconMenu/store.ts index 30a638d72c..64335a3e77 100644 --- a/src/plugins/iconMenu/store.ts +++ b/src/plugins/iconMenu/store.ts @@ -4,14 +4,13 @@ */ /* eslint-enable tsdoc/syntax */ -import type { Component } from 'vue' import type { Icon } from '@/core' import type { Menu } from './types' import { toMerged } from 'es-toolkit' import { t } from 'i18next' import { acceptHMRUpdate, defineStore } from 'pinia' -import { computed, markRaw, ref } from 'vue' +import { computed, markRaw, ref, watch } from 'vue' import { useCoreStore } from '@/core/stores' @@ -42,6 +41,33 @@ export const useIconMenuStore = defineStore('plugins/iconMenu', () => { () => coreStore.configuration.iconMenu?.layoutTag ?? '' ) + const flatMenuItems = computed(() => + menus.value.concat(focusMenus.value).flat() + ) + watch( + flatMenuItems, + (newItems, oldItems) => { + const getDiffItems = (to, from) => + to.filter( + (item) => + !from.some((oldItem) => oldItem.plugin.id === item.plugin.id) + ) + getDiffItems(newItems, oldItems).forEach((newItem) => { + coreStore.addPlugin(toMerged(newItem.plugin, { independent: false })) + }) + getDiffItems(oldItems, newItems).forEach((oldItem) => { + if (open.value === oldItem.plugin.id) { + open.value = null + } + if (focusOpen.value === oldItem.plugin.id) { + focusOpen.value = null + } + coreStore.removePlugin(oldItem.plugin.id) + }) + }, + { deep: true } + ) + function setupPlugin() { menus.value = (coreStore.configuration.iconMenu?.menus || []).map( (menuGroup) => @@ -64,24 +90,6 @@ export const useIconMenuStore = defineStore('plugins/iconMenu', () => { coreStore.addPlugin(toMerged(plugin, { independent: false })) }) - // Otherwise, the component itself is made reactive - menus.value.map((menuGroup) => - menuGroup.map((menuItem) => - toMerged(menuItem, { - plugin: { - component: markRaw(menuItem.plugin.component as Component), - }, - }) - ) - ) - focusMenus.value.map((menuItem) => - toMerged(menuItem, { - plugin: { - component: markRaw(menuItem.plugin.component as Component), - }, - }) - ) - const initiallyOpen = coreStore.configuration.iconMenu?.initiallyOpen if ( !coreStore.hasSmallHeight && @@ -104,21 +112,31 @@ export const useIconMenuStore = defineStore('plugins/iconMenu', () => { function openMenuById(openId: string) { const entry = menus.value.flat().find(({ plugin: { id } }) => id === openId) - if (entry) { open.value = openId - openInMoveHandle(openId) } } + watch(open, (open) => { + if (open) { + openInMoveHandle(open) + } else { + coreStore.setMoveHandle(null) + } + }) function openFocusMenuById(openId: string) { const entry = focusMenus.value.find(({ plugin: { id } }) => id === openId) - if (entry) { focusOpen.value = openId - openInMoveHandle(openId, true) } } + watch(focusOpen, (focusOpen) => { + if (focusOpen) { + openInMoveHandle(focusOpen, true) + } else { + coreStore.setMoveHandle(null) + } + }) function openInMoveHandle(openId: string, focusMenu = false) { const menu = (focusMenu ? focusMenus.value : menus.value.flat()).find(