diff --git a/changelog/unreleased/enhancement-nav-item-extension b/changelog/unreleased/enhancement-nav-item-extension new file mode 100644 index 00000000000..668d2ceb6a7 --- /dev/null +++ b/changelog/unreleased/enhancement-nav-item-extension @@ -0,0 +1,11 @@ +Enhancement: Registering nav items as extension + +Nav items can now be registered with the new extension type `SidebarNavExtension`, which consists of a `AppNavigationItem` and optionally `scopes` (a list of app IDs where the nav item should show). + +Also, 2 new optional properties have been added to the `AppNavigationItem` interface: + +`handler` - a click handler that get executes on click. It takes priority over a given route. +`priority` - a number that determines the nav item's position. + +https://github.com/owncloud/web/pull/9814 +https://github.com/owncloud/web/issues/9239 diff --git a/packages/web-app-admin-settings/src/index.ts b/packages/web-app-admin-settings/src/index.ts index bf9b5cf6c73..86203706add 100644 --- a/packages/web-app-admin-settings/src/index.ts +++ b/packages/web-app-admin-settings/src/index.ts @@ -109,7 +109,8 @@ const navItems = ({ $ability }: { $ability: Ability }): AppNavigationItem[] => [ }, enabled: () => { return $ability.can('read-all', 'Setting') - } + }, + priority: 10 }, { name: $gettext('Users'), @@ -119,7 +120,8 @@ const navItems = ({ $ability }: { $ability: Ability }): AppNavigationItem[] => [ }, enabled: () => { return $ability.can('read-all', 'Account') - } + }, + priority: 20 }, { name: $gettext('Groups'), @@ -129,7 +131,8 @@ const navItems = ({ $ability }: { $ability: Ability }): AppNavigationItem[] => [ }, enabled: () => { return $ability.can('read-all', 'Group') - } + }, + priority: 30 }, { name: $gettext('Spaces'), @@ -139,7 +142,8 @@ const navItems = ({ $ability }: { $ability: Ability }): AppNavigationItem[] => [ }, enabled: () => { return $ability.can('read-all', 'Drive') - } + }, + priority: 40 } ] diff --git a/packages/web-app-files/src/index.ts b/packages/web-app-files/src/index.ts index 8498c593a67..b43bf2473af 100644 --- a/packages/web-app-files/src/index.ts +++ b/packages/web-app-files/src/index.ts @@ -62,7 +62,8 @@ export const navItems = (context): AppNavigationItem[] => { return !!context?.$store?.getters['runtime/spaces/spaces'].find( (drive) => isPersonalSpaceResource(drive) && drive.isOwner(context.$store.getters.user) ) - } + }, + priority: 10 }, { name: $gettext('Favorites'), @@ -72,7 +73,8 @@ export const navItems = (context): AppNavigationItem[] => { }, enabled(capabilities) { return capabilities.files?.favorites - } + }, + priority: 20 }, { name: $gettext('Shares'), @@ -91,7 +93,8 @@ export const navItems = (context): AppNavigationItem[] => { ], enabled(capabilities) { return capabilities.files_sharing?.api_enabled !== false - } + }, + priority: 30 }, { name: $gettext('Spaces'), @@ -102,7 +105,8 @@ export const navItems = (context): AppNavigationItem[] => { activeFor: [{ path: `/${appInfo.id}/spaces/project` }], enabled(capabilities) { return capabilities.spaces?.projects - } + }, + priority: 40 }, { name: $gettext('Deleted files'), @@ -113,7 +117,8 @@ export const navItems = (context): AppNavigationItem[] => { activeFor: [{ path: `/${appInfo.id}/trash` }], enabled(capabilities) { return capabilities.dav?.trashbin === '1.0' && capabilities.files?.undelete - } + }, + priority: 50 } ] } diff --git a/packages/web-pkg/src/apps/types.ts b/packages/web-pkg/src/apps/types.ts index 3cfcd492817..bad8853b4a6 100644 --- a/packages/web-pkg/src/apps/types.ts +++ b/packages/web-pkg/src/apps/types.ts @@ -21,6 +21,8 @@ export interface AppNavigationItem { name?: string | ((capabilities?: Record) => string) route?: RouteLocationRaw tag?: string + handler?: () => void + priority?: number } /** diff --git a/packages/web-pkg/src/composables/piniaStores/extensionRegistry.ts b/packages/web-pkg/src/composables/piniaStores/extensionRegistry.ts index 5150b663ce6..57d49ff3c04 100644 --- a/packages/web-pkg/src/composables/piniaStores/extensionRegistry.ts +++ b/packages/web-pkg/src/composables/piniaStores/extensionRegistry.ts @@ -4,10 +4,12 @@ import { defineStore } from 'pinia' import { Ref, hasInjectionContext, unref } from 'vue' import { useConfigurationManager } from '../configuration' import { ConfigurationManager } from '../../configuration' +import { AppNavigationItem } from '../../apps' export type BaseExtension = { id: string type: string + scopes?: string[] } export interface ActionExtension extends BaseExtension { @@ -20,7 +22,12 @@ export interface SearchExtension extends BaseExtension { searchProvider: SearchProvider } -export type Extension = ActionExtension | SearchExtension +export interface SidebarNavExtension extends BaseExtension { + type: 'sidebarNav' + navItem: AppNavigationItem +} + +export type Extension = ActionExtension | SearchExtension | SidebarNavExtension export const useExtensionRegistry = ({ configurationManager @@ -41,13 +48,20 @@ export const useExtensionRegistry = ({ getters: { requestExtensions: (state) => - (type: string) => { + (type: string, scope?: string) => { return state.extensions .map((e) => - unref(e).filter((e) => e.type === type && !options.disabledExtensions.includes(e.id)) + unref(e).filter( + (e) => + e.type === type && + !options.disabledExtensions.includes(e.id) && + (!scope || e.scopes?.includes(scope)) + ) ) .flat() as ExtensionType[] } } })() } + +export type ExtensionRegistry = ReturnType diff --git a/packages/web-runtime/src/components/SidebarNav/SidebarNav.vue b/packages/web-runtime/src/components/SidebarNav/SidebarNav.vue index 0d61c1f1cf7..7933b13d1a7 100644 --- a/packages/web-runtime/src/components/SidebarNav/SidebarNav.vue +++ b/packages/web-runtime/src/components/SidebarNav/SidebarNav.vue @@ -39,6 +39,7 @@ :name="link.name" :collapsed="navigation.closed" :tag="link.tag" + :handler="link.handler" /> @@ -189,7 +190,8 @@ export default defineComponent({ justify-content: flex-end !important; } - .oc-sidebar-nav li a:not(.active) { + .oc-sidebar-nav li a:not(.active), + .oc-sidebar-nav li button:not(.active) { &:hover, &:focus { text-decoration: none !important; @@ -198,7 +200,8 @@ export default defineComponent({ } } - .oc-sidebar-nav li a.active { + .oc-sidebar-nav li a.active, + .oc-sidebar-nav li button.active { &:focus, &:hover { color: var(--oc-color-swatch-primary-contrast); diff --git a/packages/web-runtime/src/components/SidebarNav/SidebarNavItem.vue b/packages/web-runtime/src/components/SidebarNav/SidebarNavItem.vue index a2be5f10a31..b8fbe606e21 100644 --- a/packages/web-runtime/src/components/SidebarNav/SidebarNavItem.vue +++ b/packages/web-runtime/src/components/SidebarNav/SidebarNavItem.vue @@ -2,13 +2,13 @@
  • @@ -19,7 +19,7 @@