-
Notifications
You must be signed in to change notification settings - Fork 5
Allow removal and adding for plugins in iconMenu #861
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: next
Are you sure you want to change the base?
Changes from all commits
e14ded9
8f36876
4888d29
866b395
d7e23ae
b47d6cf
28a8ef6
bb128d2
1d136e7
fe13760
d2b0008
ee8f935
962aa61
441b0be
42c1204
b6d0d30
7b57647
b44a099
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,14 +4,12 @@ | |
| */ | ||
| /* eslint-enable tsdoc/syntax */ | ||
|
|
||
| import type { Component } from 'vue' | ||
| import type { Icon } from '@/core' | ||
| import type { Menu } from './types' | ||
| import type { FocusMenu, Menu } from './types' | ||
|
|
||
| import { toMerged } from 'es-toolkit' | ||
| import { t } from 'i18next' | ||
| import { acceptHMRUpdate, defineStore } from 'pinia' | ||
| import { computed, markRaw, ref, toRaw } from 'vue' | ||
| import { computed, markRaw, readonly, ref, toRaw } from 'vue' | ||
|
|
||
| import { useCoreStore } from '@/core/stores' | ||
|
|
||
|
|
@@ -28,7 +26,7 @@ export const useIconMenuStore = defineStore('plugins/iconMenu', () => { | |
| const coreStore = useCoreStore() | ||
|
|
||
| const menus = ref<Array<Menu[]>>([]) | ||
| const focusMenus = ref<(Menu & { icon: Icon })[]>([]) | ||
| const focusMenus = ref<FocusMenu[]>([]) | ||
| const open = ref<string | null>(null) | ||
| const focusOpen = ref<string | null>(null) | ||
|
|
||
|
|
@@ -42,6 +40,50 @@ export const useIconMenuStore = defineStore('plugins/iconMenu', () => { | |
| () => coreStore.configuration.iconMenu?.layoutTag ?? '' | ||
| ) | ||
|
|
||
| function isPluginInIconMenu(pluginId: string) { | ||
| const display = coreStore.configuration[pluginId]?.displayComponent | ||
| return typeof display === 'boolean' ? display : true | ||
| } | ||
|
Comment on lines
+43
to
+46
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not related to the intention of this PR thus 🎩, but I realized that this never did anything if the configuration was directly added to the plugin. If you see a quick solution, add it here, otherwise, I'll make a note for myself.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do not get why this check is necessary at all. I kept it here to prohibit regression, but in what scenario I'd add a plugin to the iconMenu (not standalone) but then do not display it?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So, if you agree, I'll remove this check |
||
| function addPlugin(menuGroup: Menu[]) { | ||
| const filteredMenuGroup = menuGroup.filter(({ plugin: { id } }) => | ||
| isPluginInIconMenu(id) | ||
| ) | ||
| filteredMenuGroup.forEach(({ plugin }) => { | ||
| if (plugin.component) { | ||
| markRaw(toRaw(plugin.component)) | ||
| } | ||
| coreStore.addPlugin(toMerged(plugin, { independent: false })) | ||
| }) | ||
| menus.value.push(filteredMenuGroup) | ||
| } | ||
| function addFocusPlugin(menu: FocusMenu) { | ||
| if (!isPluginInIconMenu(menu.plugin.id)) { | ||
| return | ||
| } | ||
| if (menu.plugin.component) { | ||
| markRaw(toRaw(menu.plugin.component)) | ||
| } | ||
| coreStore.addPlugin(toMerged(menu.plugin, { independent: false })) | ||
| focusMenus.value.push(menu) | ||
| } | ||
| function removePlugin(pluginId: string) { | ||
| if (open.value === pluginId) { | ||
| open.value = null | ||
| } | ||
| menus.value = menus.value | ||
| .map((menuGroup) => | ||
| menuGroup.filter(({ plugin: { id } }) => id !== pluginId) | ||
| ) | ||
| .filter((menuGroup) => menuGroup.length > 0) | ||
| if (focusOpen.value === pluginId) { | ||
| focusOpen.value = null | ||
| } | ||
| focusMenus.value = focusMenus.value.filter( | ||
| ({ plugin: { id } }) => id !== pluginId | ||
| ) | ||
| coreStore.removePlugin(pluginId) | ||
| } | ||
|
|
||
| const visibleMenus = computed(() => | ||
| menus.value.map((menuGroup) => | ||
| menuGroup.filter( | ||
|
|
@@ -56,41 +98,12 @@ export const useIconMenuStore = defineStore('plugins/iconMenu', () => { | |
| ) | ||
|
|
||
| function setupPlugin() { | ||
| // Components are marked raw so they themselves are not made reactive | ||
| menus.value = (coreStore.configuration.iconMenu?.menus || []).map( | ||
| (menuGroup) => | ||
| menuGroup | ||
| .filter(({ plugin: { id } }) => { | ||
| const display = coreStore.configuration[id]?.displayComponent | ||
| return typeof display === 'boolean' ? display : true | ||
| }) | ||
| .map((menuItem) => ({ | ||
| ...menuItem, | ||
| plugin: { | ||
| ...menuItem.plugin, | ||
| component: markRaw(toRaw(menuItem.plugin.component as Component)), | ||
| }, | ||
| })) | ||
| ) | ||
| focusMenus.value = (coreStore.configuration.iconMenu?.focusMenus || []) | ||
| .filter(({ plugin: { id } }) => { | ||
| const display = coreStore.configuration[id]?.displayComponent | ||
| return typeof display === 'boolean' ? display : true | ||
| }) | ||
| .map((menuItem) => ({ | ||
| ...menuItem, | ||
| plugin: { | ||
| ...menuItem.plugin, | ||
| component: markRaw(toRaw(menuItem.plugin.component as Component)), | ||
| }, | ||
| })) | ||
|
|
||
| menus.value | ||
| .concat(focusMenus.value) | ||
| .flat() | ||
| .forEach(({ plugin }) => { | ||
| coreStore.addPlugin(toMerged(plugin, { independent: false })) | ||
| }) | ||
| ;(coreStore.configuration.iconMenu?.menus || []).forEach((menuGroup) => { | ||
| addPlugin(menuGroup) | ||
| }) | ||
| ;(coreStore.configuration.iconMenu?.focusMenus || []).forEach((menu) => { | ||
| addFocusPlugin(menu) | ||
| }) | ||
|
|
||
| const initiallyOpen = coreStore.configuration.iconMenu?.initiallyOpen | ||
| if ( | ||
|
|
@@ -112,21 +125,25 @@ export const useIconMenuStore = defineStore('plugins/iconMenu', () => { | |
| } | ||
| function teardownPlugin() {} | ||
|
|
||
| function openMenuById(openId: string) { | ||
| function openMenuById(openId: string | null) { | ||
| const entry = menus.value.flat().find(({ plugin: { id } }) => id === openId) | ||
|
|
||
| if (entry) { | ||
| if (openId && entry) { | ||
| open.value = openId | ||
| openInMoveHandle(openId) | ||
| } else { | ||
| open.value = null | ||
| coreStore.setMoveHandle(null) | ||
| } | ||
| } | ||
|
|
||
| function openFocusMenuById(openId: string) { | ||
| function openFocusMenuById(openId: string | null) { | ||
| const entry = focusMenus.value.find(({ plugin: { id } }) => id === openId) | ||
|
|
||
| if (entry) { | ||
| if (openId && entry) { | ||
| focusOpen.value = openId | ||
| openInMoveHandle(openId, true) | ||
| } else { | ||
| focusOpen.value = null | ||
| coreStore.setMoveHandle(null) | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -172,13 +189,55 @@ export const useIconMenuStore = defineStore('plugins/iconMenu', () => { | |
| return { | ||
| visibleMenus, | ||
| visibleFocusMenus, | ||
| open, | ||
| focusOpen, | ||
|
|
||
| /** | ||
| * Determines which menu is currently open. | ||
| * | ||
| * To change the open menu, use {@link openMenuById}. | ||
| * | ||
| * @readonly | ||
|
oeninghe-dataport marked this conversation as resolved.
|
||
| * @alpha | ||
| */ | ||
| open: readonly(open), | ||
|
|
||
| /** | ||
| * Determines which focus menu is currently open. | ||
| * | ||
| * To change the open focus menu, use {@link openFocusMenuById}. | ||
| * | ||
| * @readonly | ||
|
oeninghe-dataport marked this conversation as resolved.
|
||
| * @alpha | ||
| */ | ||
| focusOpen: readonly(focusOpen), | ||
|
|
||
| buttonComponent, | ||
| openInMoveHandle, | ||
| openMenuById, | ||
| openFocusMenuById, | ||
|
|
||
| /** | ||
| * Appends a group of plugins to the icon menu. | ||
| * | ||
| * @param menu - The menu item group to add. | ||
|
oeninghe-dataport marked this conversation as resolved.
|
||
| * @alpha | ||
| */ | ||
| addPlugin, | ||
|
|
||
| /** | ||
| * Appends a plugin to the icon menu as a focus menu. | ||
| * | ||
| * @param menu - The focus menu item to add. | ||
|
oeninghe-dataport marked this conversation as resolved.
|
||
| * @alpha | ||
| */ | ||
| addFocusPlugin, | ||
|
|
||
| /** | ||
| * Removes a plugin from the icon menu. | ||
| * | ||
| * @param pluginId - The ID of the plugin to remove. | ||
|
oeninghe-dataport marked this conversation as resolved.
|
||
| * @alpha | ||
| */ | ||
| removePlugin, | ||
|
|
||
| /** @alpha */ | ||
| layoutTag, | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.