From 03ec2a35d311eeba3eac425e3efda44668afc5a4 Mon Sep 17 00:00:00 2001 From: jameszow Date: Fri, 15 Dec 2023 12:42:29 +0800 Subject: [PATCH 01/17] fetch: remove old file --- web/src/components/Menu/index.ts | 3 - web/src/components/Menu/src/BasicMenu.vue | 164 --------- .../Menu/src/components/BasicMenuItem.vue | 21 -- .../Menu/src/components/BasicSubMenuItem.vue | 55 --- .../Menu/src/components/MenuItemContent.vue | 34 -- web/src/components/Menu/src/index.less | 74 ---- web/src/components/Menu/src/props.ts | 61 ---- web/src/components/Menu/src/types.ts | 25 -- web/src/components/Menu/src/useOpenKeys.ts | 81 ----- web/src/components/SimpleMenu/index.ts | 2 - .../components/SimpleMenu/src/SimpleMenu.vue | 161 --------- .../SimpleMenu/src/SimpleMenuTag.vue | 68 ---- .../SimpleMenu/src/SimpleSubMenu.vue | 114 ------ .../SimpleMenu/src/components/Menu.vue | 159 --------- .../src/components/MenuCollapseTransition.vue | 78 ---- .../SimpleMenu/src/components/MenuItem.vue | 107 ------ .../SimpleMenu/src/components/SubMenuItem.vue | 336 ------------------ .../SimpleMenu/src/components/menu.less | 309 ---------------- .../SimpleMenu/src/components/types.ts | 25 -- .../SimpleMenu/src/components/useMenu.ts | 84 ----- .../src/components/useSimpleMenuContext.ts | 18 - web/src/components/SimpleMenu/src/index.less | 77 ---- web/src/components/SimpleMenu/src/types.ts | 0 .../components/SimpleMenu/src/useOpenKeys.ts | 48 --- 24 files changed, 2104 deletions(-) delete mode 100644 web/src/components/Menu/index.ts delete mode 100644 web/src/components/Menu/src/BasicMenu.vue delete mode 100644 web/src/components/Menu/src/components/BasicMenuItem.vue delete mode 100644 web/src/components/Menu/src/components/BasicSubMenuItem.vue delete mode 100644 web/src/components/Menu/src/components/MenuItemContent.vue delete mode 100644 web/src/components/Menu/src/index.less delete mode 100644 web/src/components/Menu/src/props.ts delete mode 100644 web/src/components/Menu/src/types.ts delete mode 100644 web/src/components/Menu/src/useOpenKeys.ts delete mode 100644 web/src/components/SimpleMenu/index.ts delete mode 100644 web/src/components/SimpleMenu/src/SimpleMenu.vue delete mode 100644 web/src/components/SimpleMenu/src/SimpleMenuTag.vue delete mode 100644 web/src/components/SimpleMenu/src/SimpleSubMenu.vue delete mode 100644 web/src/components/SimpleMenu/src/components/Menu.vue delete mode 100644 web/src/components/SimpleMenu/src/components/MenuCollapseTransition.vue delete mode 100644 web/src/components/SimpleMenu/src/components/MenuItem.vue delete mode 100644 web/src/components/SimpleMenu/src/components/SubMenuItem.vue delete mode 100644 web/src/components/SimpleMenu/src/components/menu.less delete mode 100644 web/src/components/SimpleMenu/src/components/types.ts delete mode 100644 web/src/components/SimpleMenu/src/components/useMenu.ts delete mode 100644 web/src/components/SimpleMenu/src/components/useSimpleMenuContext.ts delete mode 100644 web/src/components/SimpleMenu/src/index.less delete mode 100644 web/src/components/SimpleMenu/src/types.ts delete mode 100644 web/src/components/SimpleMenu/src/useOpenKeys.ts diff --git a/web/src/components/Menu/index.ts b/web/src/components/Menu/index.ts deleted file mode 100644 index 4a592259..00000000 --- a/web/src/components/Menu/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import BasicMenu from './src/BasicMenu.vue'; - -export { BasicMenu }; diff --git a/web/src/components/Menu/src/BasicMenu.vue b/web/src/components/Menu/src/BasicMenu.vue deleted file mode 100644 index ca8dcaaa..00000000 --- a/web/src/components/Menu/src/BasicMenu.vue +++ /dev/null @@ -1,164 +0,0 @@ - - - diff --git a/web/src/components/Menu/src/components/BasicMenuItem.vue b/web/src/components/Menu/src/components/BasicMenuItem.vue deleted file mode 100644 index 4d483624..00000000 --- a/web/src/components/Menu/src/components/BasicMenuItem.vue +++ /dev/null @@ -1,21 +0,0 @@ - - diff --git a/web/src/components/Menu/src/components/BasicSubMenuItem.vue b/web/src/components/Menu/src/components/BasicSubMenuItem.vue deleted file mode 100644 index d5139fce..00000000 --- a/web/src/components/Menu/src/components/BasicSubMenuItem.vue +++ /dev/null @@ -1,55 +0,0 @@ - - diff --git a/web/src/components/Menu/src/components/MenuItemContent.vue b/web/src/components/Menu/src/components/MenuItemContent.vue deleted file mode 100644 index 3d3351dd..00000000 --- a/web/src/components/Menu/src/components/MenuItemContent.vue +++ /dev/null @@ -1,34 +0,0 @@ - - diff --git a/web/src/components/Menu/src/index.less b/web/src/components/Menu/src/index.less deleted file mode 100644 index ff85930f..00000000 --- a/web/src/components/Menu/src/index.less +++ /dev/null @@ -1,74 +0,0 @@ -@basic-menu-prefix-cls: ~'@{namespace}-basic-menu'; - -.app-top-menu-popup { - min-width: 150px; -} - -.@{basic-menu-prefix-cls} { - width: 100%; - - .ant-menu-item { - transition: unset; - } - - &__sidebar-hor { - &.ant-menu-horizontal { - display: flex; - align-items: center; - - &.ant-menu-dark { - background-color: transparent; - - .ant-menu-submenu:hover, - .ant-menu-item-open, - .ant-menu-submenu-open, - .ant-menu-item-selected, - .ant-menu-submenu-selected, - .ant-menu-item:hover, - .ant-menu-item-active, - .ant-menu:not(.ant-menu-inline) .ant-menu-submenu-open, - .ant-menu-submenu-active, - .ant-menu-submenu-title:hover { - background-color: @top-menu-active-bg-color !important; - color: #fff; - } - - .ant-menu-item:hover, - .ant-menu-item-active, - .ant-menu:not(.ant-menu-inline) .ant-menu-submenu-open, - .ant-menu-submenu-active, - .ant-menu-submenu-title:hover { - background-color: @top-menu-active-bg-color; - } - - .@{basic-menu-prefix-cls}-item__level1 { - background-color: transparent; - - &.ant-menu-item-selected, - &.ant-menu-submenu-selected { - background-color: @top-menu-active-bg-color !important; - } - } - - .ant-menu-item, - .ant-menu-submenu { - &.@{basic-menu-prefix-cls}-item__level1, - .ant-menu-submenu-title { - height: @header-height; - line-height: @header-height; - } - } - } - } - } - - .ant-menu-submenu, - .ant-menu-submenu-inline { - transition: unset; - } - - .ant-menu-inline.ant-menu-sub { - transition: unset; - box-shadow: unset !important; - } -} diff --git a/web/src/components/Menu/src/props.ts b/web/src/components/Menu/src/props.ts deleted file mode 100644 index 480297db..00000000 --- a/web/src/components/Menu/src/props.ts +++ /dev/null @@ -1,61 +0,0 @@ -import type { Menu } from '/@/router/types'; -import type { PropType } from 'vue'; - -import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum'; -import { ThemeEnum } from '/@/enums/appEnum'; -import { propTypes } from '/@/utils/propTypes'; -import type { MenuTheme } from 'ant-design-vue'; -import type { MenuMode } from 'ant-design-vue/lib/menu/src/interface'; - -export const basicProps = { - items: { - type: Array as PropType, - default: () => [], - }, - collapsedShowTitle: propTypes.bool, - // 最好是4 倍数 - inlineIndent: propTypes.number.def(20), - // 菜单组件的mode属性 - mode: { - type: String as PropType, - default: MenuModeEnum.INLINE, - }, - - type: { - type: String as PropType, - default: MenuTypeEnum.MIX, - }, - theme: { - type: String as PropType, - default: ThemeEnum.DARK, - }, - inlineCollapsed: propTypes.bool, - mixSider: propTypes.bool, - - isHorizontal: propTypes.bool, - accordion: propTypes.bool.def(true), - beforeClickFn: { - type: Function as PropType<(key: string) => Promise>, - }, -}; - -export const itemProps = { - item: { - type: Object as PropType, - default: () => ({}), - }, - level: propTypes.number, - theme: propTypes.oneOf(['dark', 'light']), - showTitle: propTypes.bool, - isHorizontal: propTypes.bool, -}; - -export const contentProps = { - item: { - type: Object as PropType, - default: null, - }, - showTitle: propTypes.bool.def(true), - level: propTypes.number.def(0), - isHorizontal: propTypes.bool.def(true), -}; diff --git a/web/src/components/Menu/src/types.ts b/web/src/components/Menu/src/types.ts deleted file mode 100644 index ad711c27..00000000 --- a/web/src/components/Menu/src/types.ts +++ /dev/null @@ -1,25 +0,0 @@ -// import { ComputedRef } from 'vue'; -// import { ThemeEnum } from '/@/enums/appEnum'; -// import { MenuModeEnum } from '/@/enums/menuEnum'; -export interface MenuState { - // 默认选中的列表 - defaultSelectedKeys: string[]; - - // 模式 - // mode: MenuModeEnum; - - // // 主题 - // theme: ComputedRef | ThemeEnum; - - // 缩进 - inlineIndent?: number; - - // 展开数组 - openKeys: string[]; - - // 当前选中的菜单项 key 数组 - selectedKeys: string[]; - - // 收缩状态下展开的数组 - collapsedOpenKeys: string[]; -} diff --git a/web/src/components/Menu/src/useOpenKeys.ts b/web/src/components/Menu/src/useOpenKeys.ts deleted file mode 100644 index fc0b5a5a..00000000 --- a/web/src/components/Menu/src/useOpenKeys.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { MenuModeEnum } from '/@/enums/menuEnum'; -import type { Menu as MenuType } from '/@/router/types'; -import type { MenuState } from './types'; -import { computed, Ref, toRaw, unref } from 'vue'; -import { useTimeoutFn } from '@vben/hooks'; -import { uniq } from 'lodash-es'; -import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; -import { getAllParentPath } from '/@/router/helper/menuHelper'; - -export function useOpenKeys( - menuState: MenuState, - menus: Ref, - mode: Ref, - accordion: Ref, -) { - const { getCollapsed, getIsMixSidebar } = useMenuSetting(); - - async function setOpenKeys(path: string) { - if (mode.value === MenuModeEnum.HORIZONTAL) { - return; - } - const native = unref(getIsMixSidebar); - const handle = () => { - const menuList = toRaw(menus.value); - if (menuList?.length === 0) { - menuState.openKeys = []; - return; - } - if (!unref(accordion)) { - menuState.openKeys = uniq([...menuState.openKeys, ...getAllParentPath(menuList, path)]); - } else { - menuState.openKeys = getAllParentPath(menuList, path); - } - }; - if (native) { - handle(); - } else { - useTimeoutFn(handle, 16); - } - } - - const getOpenKeys = computed(() => { - const collapse = unref(getIsMixSidebar) ? false : unref(getCollapsed); - - return collapse ? menuState.collapsedOpenKeys : menuState.openKeys; - }); - - /** - * @description: 重置值 - */ - function resetKeys() { - menuState.selectedKeys = []; - menuState.openKeys = []; - } - - function handleOpenChange(openKeys: string[]) { - if (unref(mode) === MenuModeEnum.HORIZONTAL || !unref(accordion) || unref(getIsMixSidebar)) { - menuState.openKeys = openKeys; - } else { - // const menuList = toRaw(menus.value); - // getAllParentPath(menuList, path); - const rootSubMenuKeys: string[] = []; - for (const { children, path } of unref(menus)) { - if (children && children.length > 0) { - rootSubMenuKeys.push(path); - } - } - if (!unref(getCollapsed)) { - const latestOpenKey = openKeys.find((key) => menuState.openKeys.indexOf(key) === -1); - if (rootSubMenuKeys.indexOf(latestOpenKey as string) === -1) { - menuState.openKeys = openKeys; - } else { - menuState.openKeys = latestOpenKey ? [latestOpenKey] : []; - } - } else { - menuState.collapsedOpenKeys = openKeys; - } - } - } - return { setOpenKeys, resetKeys, getOpenKeys, handleOpenChange }; -} diff --git a/web/src/components/SimpleMenu/index.ts b/web/src/components/SimpleMenu/index.ts deleted file mode 100644 index 0dfd2485..00000000 --- a/web/src/components/SimpleMenu/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default as SimpleMenu } from './src/SimpleMenu.vue'; -export { default as SimpleMenuTag } from './src/SimpleMenuTag.vue'; diff --git a/web/src/components/SimpleMenu/src/SimpleMenu.vue b/web/src/components/SimpleMenu/src/SimpleMenu.vue deleted file mode 100644 index a391d069..00000000 --- a/web/src/components/SimpleMenu/src/SimpleMenu.vue +++ /dev/null @@ -1,161 +0,0 @@ - - - diff --git a/web/src/components/SimpleMenu/src/SimpleMenuTag.vue b/web/src/components/SimpleMenu/src/SimpleMenuTag.vue deleted file mode 100644 index b7d3cb36..00000000 --- a/web/src/components/SimpleMenu/src/SimpleMenuTag.vue +++ /dev/null @@ -1,68 +0,0 @@ - - diff --git a/web/src/components/SimpleMenu/src/SimpleSubMenu.vue b/web/src/components/SimpleMenu/src/SimpleSubMenu.vue deleted file mode 100644 index 068d0c21..00000000 --- a/web/src/components/SimpleMenu/src/SimpleSubMenu.vue +++ /dev/null @@ -1,114 +0,0 @@ - - diff --git a/web/src/components/SimpleMenu/src/components/Menu.vue b/web/src/components/SimpleMenu/src/components/Menu.vue deleted file mode 100644 index 28e0b3e6..00000000 --- a/web/src/components/SimpleMenu/src/components/Menu.vue +++ /dev/null @@ -1,159 +0,0 @@ - - - - diff --git a/web/src/components/SimpleMenu/src/components/MenuCollapseTransition.vue b/web/src/components/SimpleMenu/src/components/MenuCollapseTransition.vue deleted file mode 100644 index 5295439a..00000000 --- a/web/src/components/SimpleMenu/src/components/MenuCollapseTransition.vue +++ /dev/null @@ -1,78 +0,0 @@ - - diff --git a/web/src/components/SimpleMenu/src/components/MenuItem.vue b/web/src/components/SimpleMenu/src/components/MenuItem.vue deleted file mode 100644 index 3a99796c..00000000 --- a/web/src/components/SimpleMenu/src/components/MenuItem.vue +++ /dev/null @@ -1,107 +0,0 @@ - - - diff --git a/web/src/components/SimpleMenu/src/components/SubMenuItem.vue b/web/src/components/SimpleMenu/src/components/SubMenuItem.vue deleted file mode 100644 index 87c9e074..00000000 --- a/web/src/components/SimpleMenu/src/components/SubMenuItem.vue +++ /dev/null @@ -1,336 +0,0 @@ - - - diff --git a/web/src/components/SimpleMenu/src/components/menu.less b/web/src/components/SimpleMenu/src/components/menu.less deleted file mode 100644 index 2fe0b54c..00000000 --- a/web/src/components/SimpleMenu/src/components/menu.less +++ /dev/null @@ -1,309 +0,0 @@ -@menu-prefix-cls: ~'@{namespace}-menu'; -@menu-popup-prefix-cls: ~'@{namespace}-menu-popup'; -@submenu-popup-prefix-cls: ~'@{namespace}-menu-submenu-popup'; - -@transition-time: 0.2s; -@menu-dark-subsidiary-color: rgba(255, 255, 255, 0.7); - -.light-border { - &::after { - content: ''; - display: block; - position: absolute; - top: 0; - right: 0; - bottom: 0; - width: 2px; - background-color: @primary-color; - } -} - -.@{menu-prefix-cls}-menu-popover { - .ant-popover-arrow { - display: none; - } - - .ant-popover-inner-content { - padding: 0; - } - - .@{menu-prefix-cls} { - &-opened > * > &-submenu-title-icon { - transform: translateY(-50%) rotate(90deg) !important; - } - - &-item, - &-submenu-title { - position: relative; - z-index: 1; - padding: 12px 20px; - transition: all @transition-time @ease-in-out; - color: @menu-dark-subsidiary-color; - cursor: pointer; - - &-icon { - position: absolute; - top: 50%; - right: 18px; - transform: translateY(-50%) rotate(-90deg); - transition: transform @transition-time @ease-in-out; - } - } - - &-dark { - .@{menu-prefix-cls}-item, - .@{menu-prefix-cls}-submenu-title { - color: @menu-dark-subsidiary-color; - // background: @menu-dark-active-bg; - - &:hover { - color: #fff; - } - - &-selected { - background-color: @primary-color !important; - color: #fff; - } - } - } - - &-light { - .@{menu-prefix-cls}-item, - .@{menu-prefix-cls}-submenu-title { - color: @text-color-base; - - &:hover { - color: @primary-color; - } - - &-selected { - z-index: 2; - background-color: fade(@primary-color, 10); - color: @primary-color; - - .light-border(); - } - } - } - } -} - -.content(); -.content() { - .@{menu-prefix-cls} { - display: block; - position: relative; - width: 100%; - margin: 0; - padding: 0; - outline: none; - color: @text-color-base; - font-size: @font-size-base; - list-style: none; - - // .collapse-transition { - // transition: @transition-time height ease-in-out, @transition-time padding-top ease-in-out, - // @transition-time padding-bottom ease-in-out; - // } - - &-light { - background-color: #fff; - - .@{menu-prefix-cls}-submenu-active { - color: @primary-color !important; - - &-border { - .light-border(); - } - } - } - - &-dark { - .@{menu-prefix-cls}-submenu-active { - color: #fff !important; - } - } - - &-item { - display: flex; - position: relative; - z-index: 1; - align-items: center; - outline: none; - color: inherit; - font-size: @font-size-base; - list-style: none; - cursor: pointer; - - &:hover, - &:active { - color: inherit; - } - } - - &-item > i { - margin-right: 6px; - } - - &-submenu-title > i, - &-submenu-title span > i { - margin-right: 8px; - } - - // vertical - &-vertical &-item, - &-vertical &-submenu-title { - position: relative; - z-index: 1; - padding: 14px 24px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - cursor: pointer; - - &:hover { - color: @primary-color; - } - - .@{menu-prefix-cls}-tooltip { - width: calc(100% - 0px); - padding: 12px 0; - text-align: center; - } - .@{menu-prefix-cls}-submenu-popup { - padding: 12px 0; - } - } - - &-vertical &-submenu-collapse { - .@{submenu-popup-prefix-cls} { - display: flex; - align-items: center; - justify-content: center; - } - .@{menu-prefix-cls}-submenu-collapsed-show-tit { - flex-direction: column; - } - } - - &-vertical&-collapse &-item, - &-vertical&-collapse &-submenu-title { - padding: 0; - } - - &-vertical &-submenu-title-icon { - position: absolute; - top: 50%; - right: 18px; - transform: translateY(-50%); - } - - &-submenu-title-icon { - transition: transform @transition-time @ease-in-out; - } - - &-vertical &-opened > * > &-submenu-title-icon { - transform: translateY(-50%) rotate(180deg); - } - - &-vertical &-submenu { - &-nested { - padding-left: 20px; - } - .@{menu-prefix-cls}-item { - padding-left: 43px; - } - } - - &-light&-vertical &-item { - &-active:not(.@{menu-prefix-cls}-submenu) { - z-index: 2; - background-color: fade(@primary-color, 10); - color: @primary-color; - - .light-border(); - } - &-active.@{menu-prefix-cls}-submenu { - color: @primary-color; - } - } - - &-light&-vertical&-collapse { - > li.@{menu-prefix-cls}-item-active, - .@{menu-prefix-cls}-submenu-active { - position: relative; - background-color: fade(@primary-color, 5); - - &::after { - display: none; - } - - &::before { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 3px; - height: 100%; - background-color: @primary-color; - } - } - } - - &-dark&-vertical &-item, - &-dark&-vertical &-submenu-title { - color: @menu-dark-subsidiary-color; - &-active:not(.@{menu-prefix-cls}-submenu) { - background-color: @primary-color !important; - color: #fff !important; - } - - &:hover { - color: #fff; - } - } - - &-dark&-vertical&-collapse { - > li.@{menu-prefix-cls}-item-active, - .@{menu-prefix-cls}-submenu-active { - position: relative; - background-color: @sider-dark-darken-bg-color !important; - color: #fff !important; - - &::before { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 3px; - height: 100%; - background-color: @primary-color; - } - - .@{menu-prefix-cls}-submenu-collapse { - background-color: transparent; - } - } - } - - &-dark&-vertical &-submenu &-item { - &-active, - &-active:hover { - border-right: none; - color: #fff; - } - } - - &-dark&-vertical &-child-item-active > &-submenu-title { - color: #fff; - } - - &-dark&-vertical &-opened { - .@{menu-prefix-cls}-submenu-has-parent-submenu { - .@{menu-prefix-cls}-submenu-title { - background-color: transparent; - } - } - } - } -} diff --git a/web/src/components/SimpleMenu/src/components/types.ts b/web/src/components/SimpleMenu/src/components/types.ts deleted file mode 100644 index d828e89a..00000000 --- a/web/src/components/SimpleMenu/src/components/types.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Ref } from 'vue'; - -export interface Props { - theme: string; - activeName?: string | number | undefined; - openNames: string[]; - accordion: boolean; - width: string; - collapsedWidth: string; - indentSize: number; - collapse: boolean; - activeSubMenuNames: (string | number)[]; -} - -export interface SubMenuProvider { - addSubMenu: (name: string | number, update?: boolean) => void; - removeSubMenu: (name: string | number, update?: boolean) => void; - removeAll: () => void; - sliceIndex: (index: number) => void; - isRemoveAllPopup: Ref; - getOpenNames: () => (string | number)[]; - handleMouseleave?: Fn; - level: number; - props: Props; -} diff --git a/web/src/components/SimpleMenu/src/components/useMenu.ts b/web/src/components/SimpleMenu/src/components/useMenu.ts deleted file mode 100644 index 8830559d..00000000 --- a/web/src/components/SimpleMenu/src/components/useMenu.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { computed, ComponentInternalInstance, unref } from 'vue'; -import type { CSSProperties } from 'vue'; - -export function useMenuItem(instance: ComponentInternalInstance | null) { - const getParentMenu = computed(() => { - return findParentMenu(['Menu', 'SubMenu']); - }); - - const getParentRootMenu = computed(() => { - return findParentMenu(['Menu']); - }); - - const getParentSubMenu = computed(() => { - return findParentMenu(['SubMenu']); - }); - - const getItemStyle = computed((): CSSProperties => { - let parent = instance?.parent; - if (!parent) return {}; - const indentSize = (unref(getParentRootMenu)?.props.indentSize as number) ?? 20; - let padding = indentSize; - - if (unref(getParentRootMenu)?.props.collapse) { - padding = indentSize; - } else { - while (parent && parent.type.name !== 'Menu') { - if (parent.type.name === 'SubMenu') { - padding += indentSize; - } - parent = parent.parent; - } - } - return { paddingLeft: padding + 'px' }; - }); - - function findParentMenu(name: string[]) { - let parent = instance?.parent; - if (!parent) return null; - while (parent && name.indexOf(parent.type.name!) === -1) { - parent = parent.parent; - } - return parent; - } - - function getParentList() { - let parent = instance; - if (!parent) - return { - uidList: [], - list: [], - }; - const ret: any[] = []; - while (parent && parent.type.name !== 'Menu') { - if (parent.type.name === 'SubMenu') { - ret.push(parent); - } - parent = parent.parent; - } - return { - uidList: ret.map((item) => item.uid), - list: ret, - }; - } - - function getParentInstance(instance: ComponentInternalInstance, name = 'SubMenu') { - let parent = instance.parent; - while (parent) { - if (parent.type.name !== name) { - return parent; - } - parent = parent.parent; - } - return parent; - } - - return { - getParentMenu, - getParentInstance, - getParentRootMenu, - getParentList, - getParentSubMenu, - getItemStyle, - }; -} diff --git a/web/src/components/SimpleMenu/src/components/useSimpleMenuContext.ts b/web/src/components/SimpleMenu/src/components/useSimpleMenuContext.ts deleted file mode 100644 index f3d81003..00000000 --- a/web/src/components/SimpleMenu/src/components/useSimpleMenuContext.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { InjectionKey, Ref } from 'vue'; -import type { Emitter } from '/@/utils/mitt'; -import { createContext, useContext } from '/@/hooks/core/useContext'; - -export interface SimpleRootMenuContextProps { - rootMenuEmitter: Emitter; - activeName: Ref; -} - -const key: InjectionKey = Symbol(); - -export function createSimpleRootMenuContext(context: SimpleRootMenuContextProps) { - return createContext(context, key, { readonly: false, native: true }); -} - -export function useSimpleRootMenuContext() { - return useContext(key); -} diff --git a/web/src/components/SimpleMenu/src/index.less b/web/src/components/SimpleMenu/src/index.less deleted file mode 100644 index 74fe82b7..00000000 --- a/web/src/components/SimpleMenu/src/index.less +++ /dev/null @@ -1,77 +0,0 @@ -@simple-prefix-cls: ~'@{namespace}-simple-menu'; -@prefix-cls: ~'@{namespace}-menu'; - -.@{prefix-cls} { - &-dark&-vertical .@{simple-prefix-cls}__parent { - background-color: @sider-dark-bg-color; - > .@{prefix-cls}-submenu-title { - background-color: @sider-dark-bg-color; - } - } - - &-dark&-vertical .@{simple-prefix-cls}__children, - &-dark&-popup .@{simple-prefix-cls}__children { - background-color: @sider-dark-lighten-bg-color; - > .@{prefix-cls}-submenu-title { - background-color: @sider-dark-lighten-bg-color; - } - } - - .collapse-title { - overflow: hidden; - font-size: 12px; - text-overflow: ellipsis; - white-space: nowrap; - } -} - -.@{simple-prefix-cls} { - &-sub-title { - overflow: hidden; - transition: all 0.3s; - text-overflow: ellipsis; - white-space: nowrap; - } - - &-tag { - display: inline-block; - position: absolute; - top: calc(50% - 8px); - right: 30px; - margin-right: 4px; - padding: 2px 3px; - border-radius: 2px; - color: #fff; - font-size: 10px; - line-height: 14px; - - &--collapse { - top: 6px !important; - right: 2px; - } - - &--dot { - top: calc(50% - 2px); - width: 6px; - height: 6px; - padding: 0; - border-radius: 50%; - } - - &--primary { - background-color: @primary-color; - } - - &--error { - background-color: @error-color; - } - - &--success { - background-color: @success-color; - } - - &--warn { - background-color: @warning-color; - } - } -} diff --git a/web/src/components/SimpleMenu/src/types.ts b/web/src/components/SimpleMenu/src/types.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/web/src/components/SimpleMenu/src/useOpenKeys.ts b/web/src/components/SimpleMenu/src/useOpenKeys.ts deleted file mode 100644 index 1028f974..00000000 --- a/web/src/components/SimpleMenu/src/useOpenKeys.ts +++ /dev/null @@ -1,48 +0,0 @@ -import type { Menu as MenuType } from '/@/router/types'; -import type { MenuState } from './types'; -import { computed, Ref, toRaw, unref } from 'vue'; -import { uniq } from 'lodash-es'; -import { getAllParentPath } from '/@/router/helper/menuHelper'; -import { useTimeoutFn } from '@vben/hooks'; -import { useDebounceFn } from '@vueuse/core'; - -export function useOpenKeys( - menuState: MenuState, - menus: Ref, - accordion: Ref, - mixSider: Ref, - collapse: Ref, -) { - const debounceSetOpenKeys = useDebounceFn(setOpenKeys, 50); - async function setOpenKeys(path: string) { - const native = !mixSider.value; - const menuList = toRaw(menus.value); - - const handle = () => { - if (menuList?.length === 0) { - menuState.activeSubMenuNames = []; - menuState.openNames = []; - return; - } - const keys = getAllParentPath(menuList, path); - - if (!unref(accordion)) { - menuState.openNames = uniq([...menuState.openNames, ...keys]); - } else { - menuState.openNames = keys; - } - menuState.activeSubMenuNames = menuState.openNames; - }; - if (native) { - handle(); - } else { - useTimeoutFn(handle, 30); - } - } - - const getOpenKeys = computed(() => { - return unref(collapse) ? [] : menuState.openNames; - }); - - return { setOpenKeys: debounceSetOpenKeys, getOpenKeys }; -} From a0312dae7bfa5a412b2cad55c1b050fa2785d5a8 Mon Sep 17 00:00:00 2001 From: jameszow Date: Fri, 15 Dec 2023 12:42:48 +0800 Subject: [PATCH 02/17] fetch: add new file --- web/src/components/Menu/index.ts | 3 + web/src/components/Menu/src/BasicMenu.vue | 164 +++++++++ .../Menu/src/components/BasicMenuItem.vue | 21 ++ .../Menu/src/components/BasicSubMenuItem.vue | 55 +++ .../Menu/src/components/MenuItemContent.vue | 34 ++ web/src/components/Menu/src/index.less | 74 ++++ web/src/components/Menu/src/props.ts | 61 ++++ web/src/components/Menu/src/types.ts | 25 ++ web/src/components/Menu/src/useOpenKeys.ts | 81 +++++ web/src/components/SimpleMenu/index.ts | 2 + .../components/SimpleMenu/src/SimpleMenu.vue | 161 +++++++++ .../SimpleMenu/src/SimpleMenuTag.vue | 68 ++++ .../SimpleMenu/src/SimpleSubMenu.vue | 116 ++++++ .../SimpleMenu/src/components/Menu.vue | 159 +++++++++ .../src/components/MenuCollapseTransition.vue | 78 ++++ .../SimpleMenu/src/components/MenuItem.vue | 107 ++++++ .../SimpleMenu/src/components/SubMenuItem.vue | 336 ++++++++++++++++++ .../SimpleMenu/src/components/menu.less | 309 ++++++++++++++++ .../SimpleMenu/src/components/types.ts | 25 ++ .../SimpleMenu/src/components/useMenu.ts | 84 +++++ .../src/components/useSimpleMenuContext.ts | 18 + web/src/components/SimpleMenu/src/index.less | 77 ++++ web/src/components/SimpleMenu/src/types.ts | 0 .../components/SimpleMenu/src/useOpenKeys.ts | 48 +++ 24 files changed, 2106 insertions(+) create mode 100644 web/src/components/Menu/index.ts create mode 100644 web/src/components/Menu/src/BasicMenu.vue create mode 100644 web/src/components/Menu/src/components/BasicMenuItem.vue create mode 100644 web/src/components/Menu/src/components/BasicSubMenuItem.vue create mode 100644 web/src/components/Menu/src/components/MenuItemContent.vue create mode 100644 web/src/components/Menu/src/index.less create mode 100644 web/src/components/Menu/src/props.ts create mode 100644 web/src/components/Menu/src/types.ts create mode 100644 web/src/components/Menu/src/useOpenKeys.ts create mode 100644 web/src/components/SimpleMenu/index.ts create mode 100644 web/src/components/SimpleMenu/src/SimpleMenu.vue create mode 100644 web/src/components/SimpleMenu/src/SimpleMenuTag.vue create mode 100644 web/src/components/SimpleMenu/src/SimpleSubMenu.vue create mode 100644 web/src/components/SimpleMenu/src/components/Menu.vue create mode 100644 web/src/components/SimpleMenu/src/components/MenuCollapseTransition.vue create mode 100644 web/src/components/SimpleMenu/src/components/MenuItem.vue create mode 100644 web/src/components/SimpleMenu/src/components/SubMenuItem.vue create mode 100644 web/src/components/SimpleMenu/src/components/menu.less create mode 100644 web/src/components/SimpleMenu/src/components/types.ts create mode 100644 web/src/components/SimpleMenu/src/components/useMenu.ts create mode 100644 web/src/components/SimpleMenu/src/components/useSimpleMenuContext.ts create mode 100644 web/src/components/SimpleMenu/src/index.less create mode 100644 web/src/components/SimpleMenu/src/types.ts create mode 100644 web/src/components/SimpleMenu/src/useOpenKeys.ts diff --git a/web/src/components/Menu/index.ts b/web/src/components/Menu/index.ts new file mode 100644 index 00000000..4a592259 --- /dev/null +++ b/web/src/components/Menu/index.ts @@ -0,0 +1,3 @@ +import BasicMenu from './src/BasicMenu.vue'; + +export { BasicMenu }; diff --git a/web/src/components/Menu/src/BasicMenu.vue b/web/src/components/Menu/src/BasicMenu.vue new file mode 100644 index 00000000..ca8dcaaa --- /dev/null +++ b/web/src/components/Menu/src/BasicMenu.vue @@ -0,0 +1,164 @@ + + + diff --git a/web/src/components/Menu/src/components/BasicMenuItem.vue b/web/src/components/Menu/src/components/BasicMenuItem.vue new file mode 100644 index 00000000..4d483624 --- /dev/null +++ b/web/src/components/Menu/src/components/BasicMenuItem.vue @@ -0,0 +1,21 @@ + + diff --git a/web/src/components/Menu/src/components/BasicSubMenuItem.vue b/web/src/components/Menu/src/components/BasicSubMenuItem.vue new file mode 100644 index 00000000..d5139fce --- /dev/null +++ b/web/src/components/Menu/src/components/BasicSubMenuItem.vue @@ -0,0 +1,55 @@ + + diff --git a/web/src/components/Menu/src/components/MenuItemContent.vue b/web/src/components/Menu/src/components/MenuItemContent.vue new file mode 100644 index 00000000..3d3351dd --- /dev/null +++ b/web/src/components/Menu/src/components/MenuItemContent.vue @@ -0,0 +1,34 @@ + + diff --git a/web/src/components/Menu/src/index.less b/web/src/components/Menu/src/index.less new file mode 100644 index 00000000..ff85930f --- /dev/null +++ b/web/src/components/Menu/src/index.less @@ -0,0 +1,74 @@ +@basic-menu-prefix-cls: ~'@{namespace}-basic-menu'; + +.app-top-menu-popup { + min-width: 150px; +} + +.@{basic-menu-prefix-cls} { + width: 100%; + + .ant-menu-item { + transition: unset; + } + + &__sidebar-hor { + &.ant-menu-horizontal { + display: flex; + align-items: center; + + &.ant-menu-dark { + background-color: transparent; + + .ant-menu-submenu:hover, + .ant-menu-item-open, + .ant-menu-submenu-open, + .ant-menu-item-selected, + .ant-menu-submenu-selected, + .ant-menu-item:hover, + .ant-menu-item-active, + .ant-menu:not(.ant-menu-inline) .ant-menu-submenu-open, + .ant-menu-submenu-active, + .ant-menu-submenu-title:hover { + background-color: @top-menu-active-bg-color !important; + color: #fff; + } + + .ant-menu-item:hover, + .ant-menu-item-active, + .ant-menu:not(.ant-menu-inline) .ant-menu-submenu-open, + .ant-menu-submenu-active, + .ant-menu-submenu-title:hover { + background-color: @top-menu-active-bg-color; + } + + .@{basic-menu-prefix-cls}-item__level1 { + background-color: transparent; + + &.ant-menu-item-selected, + &.ant-menu-submenu-selected { + background-color: @top-menu-active-bg-color !important; + } + } + + .ant-menu-item, + .ant-menu-submenu { + &.@{basic-menu-prefix-cls}-item__level1, + .ant-menu-submenu-title { + height: @header-height; + line-height: @header-height; + } + } + } + } + } + + .ant-menu-submenu, + .ant-menu-submenu-inline { + transition: unset; + } + + .ant-menu-inline.ant-menu-sub { + transition: unset; + box-shadow: unset !important; + } +} diff --git a/web/src/components/Menu/src/props.ts b/web/src/components/Menu/src/props.ts new file mode 100644 index 00000000..480297db --- /dev/null +++ b/web/src/components/Menu/src/props.ts @@ -0,0 +1,61 @@ +import type { Menu } from '/@/router/types'; +import type { PropType } from 'vue'; + +import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum'; +import { ThemeEnum } from '/@/enums/appEnum'; +import { propTypes } from '/@/utils/propTypes'; +import type { MenuTheme } from 'ant-design-vue'; +import type { MenuMode } from 'ant-design-vue/lib/menu/src/interface'; + +export const basicProps = { + items: { + type: Array as PropType, + default: () => [], + }, + collapsedShowTitle: propTypes.bool, + // 最好是4 倍数 + inlineIndent: propTypes.number.def(20), + // 菜单组件的mode属性 + mode: { + type: String as PropType, + default: MenuModeEnum.INLINE, + }, + + type: { + type: String as PropType, + default: MenuTypeEnum.MIX, + }, + theme: { + type: String as PropType, + default: ThemeEnum.DARK, + }, + inlineCollapsed: propTypes.bool, + mixSider: propTypes.bool, + + isHorizontal: propTypes.bool, + accordion: propTypes.bool.def(true), + beforeClickFn: { + type: Function as PropType<(key: string) => Promise>, + }, +}; + +export const itemProps = { + item: { + type: Object as PropType, + default: () => ({}), + }, + level: propTypes.number, + theme: propTypes.oneOf(['dark', 'light']), + showTitle: propTypes.bool, + isHorizontal: propTypes.bool, +}; + +export const contentProps = { + item: { + type: Object as PropType, + default: null, + }, + showTitle: propTypes.bool.def(true), + level: propTypes.number.def(0), + isHorizontal: propTypes.bool.def(true), +}; diff --git a/web/src/components/Menu/src/types.ts b/web/src/components/Menu/src/types.ts new file mode 100644 index 00000000..ad711c27 --- /dev/null +++ b/web/src/components/Menu/src/types.ts @@ -0,0 +1,25 @@ +// import { ComputedRef } from 'vue'; +// import { ThemeEnum } from '/@/enums/appEnum'; +// import { MenuModeEnum } from '/@/enums/menuEnum'; +export interface MenuState { + // 默认选中的列表 + defaultSelectedKeys: string[]; + + // 模式 + // mode: MenuModeEnum; + + // // 主题 + // theme: ComputedRef | ThemeEnum; + + // 缩进 + inlineIndent?: number; + + // 展开数组 + openKeys: string[]; + + // 当前选中的菜单项 key 数组 + selectedKeys: string[]; + + // 收缩状态下展开的数组 + collapsedOpenKeys: string[]; +} diff --git a/web/src/components/Menu/src/useOpenKeys.ts b/web/src/components/Menu/src/useOpenKeys.ts new file mode 100644 index 00000000..fc0b5a5a --- /dev/null +++ b/web/src/components/Menu/src/useOpenKeys.ts @@ -0,0 +1,81 @@ +import { MenuModeEnum } from '/@/enums/menuEnum'; +import type { Menu as MenuType } from '/@/router/types'; +import type { MenuState } from './types'; +import { computed, Ref, toRaw, unref } from 'vue'; +import { useTimeoutFn } from '@vben/hooks'; +import { uniq } from 'lodash-es'; +import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; +import { getAllParentPath } from '/@/router/helper/menuHelper'; + +export function useOpenKeys( + menuState: MenuState, + menus: Ref, + mode: Ref, + accordion: Ref, +) { + const { getCollapsed, getIsMixSidebar } = useMenuSetting(); + + async function setOpenKeys(path: string) { + if (mode.value === MenuModeEnum.HORIZONTAL) { + return; + } + const native = unref(getIsMixSidebar); + const handle = () => { + const menuList = toRaw(menus.value); + if (menuList?.length === 0) { + menuState.openKeys = []; + return; + } + if (!unref(accordion)) { + menuState.openKeys = uniq([...menuState.openKeys, ...getAllParentPath(menuList, path)]); + } else { + menuState.openKeys = getAllParentPath(menuList, path); + } + }; + if (native) { + handle(); + } else { + useTimeoutFn(handle, 16); + } + } + + const getOpenKeys = computed(() => { + const collapse = unref(getIsMixSidebar) ? false : unref(getCollapsed); + + return collapse ? menuState.collapsedOpenKeys : menuState.openKeys; + }); + + /** + * @description: 重置值 + */ + function resetKeys() { + menuState.selectedKeys = []; + menuState.openKeys = []; + } + + function handleOpenChange(openKeys: string[]) { + if (unref(mode) === MenuModeEnum.HORIZONTAL || !unref(accordion) || unref(getIsMixSidebar)) { + menuState.openKeys = openKeys; + } else { + // const menuList = toRaw(menus.value); + // getAllParentPath(menuList, path); + const rootSubMenuKeys: string[] = []; + for (const { children, path } of unref(menus)) { + if (children && children.length > 0) { + rootSubMenuKeys.push(path); + } + } + if (!unref(getCollapsed)) { + const latestOpenKey = openKeys.find((key) => menuState.openKeys.indexOf(key) === -1); + if (rootSubMenuKeys.indexOf(latestOpenKey as string) === -1) { + menuState.openKeys = openKeys; + } else { + menuState.openKeys = latestOpenKey ? [latestOpenKey] : []; + } + } else { + menuState.collapsedOpenKeys = openKeys; + } + } + } + return { setOpenKeys, resetKeys, getOpenKeys, handleOpenChange }; +} diff --git a/web/src/components/SimpleMenu/index.ts b/web/src/components/SimpleMenu/index.ts new file mode 100644 index 00000000..0dfd2485 --- /dev/null +++ b/web/src/components/SimpleMenu/index.ts @@ -0,0 +1,2 @@ +export { default as SimpleMenu } from './src/SimpleMenu.vue'; +export { default as SimpleMenuTag } from './src/SimpleMenuTag.vue'; diff --git a/web/src/components/SimpleMenu/src/SimpleMenu.vue b/web/src/components/SimpleMenu/src/SimpleMenu.vue new file mode 100644 index 00000000..a391d069 --- /dev/null +++ b/web/src/components/SimpleMenu/src/SimpleMenu.vue @@ -0,0 +1,161 @@ + + + diff --git a/web/src/components/SimpleMenu/src/SimpleMenuTag.vue b/web/src/components/SimpleMenu/src/SimpleMenuTag.vue new file mode 100644 index 00000000..b7d3cb36 --- /dev/null +++ b/web/src/components/SimpleMenu/src/SimpleMenuTag.vue @@ -0,0 +1,68 @@ + + diff --git a/web/src/components/SimpleMenu/src/SimpleSubMenu.vue b/web/src/components/SimpleMenu/src/SimpleSubMenu.vue new file mode 100644 index 00000000..1accfc7f --- /dev/null +++ b/web/src/components/SimpleMenu/src/SimpleSubMenu.vue @@ -0,0 +1,116 @@ + + diff --git a/web/src/components/SimpleMenu/src/components/Menu.vue b/web/src/components/SimpleMenu/src/components/Menu.vue new file mode 100644 index 00000000..28e0b3e6 --- /dev/null +++ b/web/src/components/SimpleMenu/src/components/Menu.vue @@ -0,0 +1,159 @@ + + + + diff --git a/web/src/components/SimpleMenu/src/components/MenuCollapseTransition.vue b/web/src/components/SimpleMenu/src/components/MenuCollapseTransition.vue new file mode 100644 index 00000000..5295439a --- /dev/null +++ b/web/src/components/SimpleMenu/src/components/MenuCollapseTransition.vue @@ -0,0 +1,78 @@ + + diff --git a/web/src/components/SimpleMenu/src/components/MenuItem.vue b/web/src/components/SimpleMenu/src/components/MenuItem.vue new file mode 100644 index 00000000..3a99796c --- /dev/null +++ b/web/src/components/SimpleMenu/src/components/MenuItem.vue @@ -0,0 +1,107 @@ + + + diff --git a/web/src/components/SimpleMenu/src/components/SubMenuItem.vue b/web/src/components/SimpleMenu/src/components/SubMenuItem.vue new file mode 100644 index 00000000..87c9e074 --- /dev/null +++ b/web/src/components/SimpleMenu/src/components/SubMenuItem.vue @@ -0,0 +1,336 @@ + + + diff --git a/web/src/components/SimpleMenu/src/components/menu.less b/web/src/components/SimpleMenu/src/components/menu.less new file mode 100644 index 00000000..2fe0b54c --- /dev/null +++ b/web/src/components/SimpleMenu/src/components/menu.less @@ -0,0 +1,309 @@ +@menu-prefix-cls: ~'@{namespace}-menu'; +@menu-popup-prefix-cls: ~'@{namespace}-menu-popup'; +@submenu-popup-prefix-cls: ~'@{namespace}-menu-submenu-popup'; + +@transition-time: 0.2s; +@menu-dark-subsidiary-color: rgba(255, 255, 255, 0.7); + +.light-border { + &::after { + content: ''; + display: block; + position: absolute; + top: 0; + right: 0; + bottom: 0; + width: 2px; + background-color: @primary-color; + } +} + +.@{menu-prefix-cls}-menu-popover { + .ant-popover-arrow { + display: none; + } + + .ant-popover-inner-content { + padding: 0; + } + + .@{menu-prefix-cls} { + &-opened > * > &-submenu-title-icon { + transform: translateY(-50%) rotate(90deg) !important; + } + + &-item, + &-submenu-title { + position: relative; + z-index: 1; + padding: 12px 20px; + transition: all @transition-time @ease-in-out; + color: @menu-dark-subsidiary-color; + cursor: pointer; + + &-icon { + position: absolute; + top: 50%; + right: 18px; + transform: translateY(-50%) rotate(-90deg); + transition: transform @transition-time @ease-in-out; + } + } + + &-dark { + .@{menu-prefix-cls}-item, + .@{menu-prefix-cls}-submenu-title { + color: @menu-dark-subsidiary-color; + // background: @menu-dark-active-bg; + + &:hover { + color: #fff; + } + + &-selected { + background-color: @primary-color !important; + color: #fff; + } + } + } + + &-light { + .@{menu-prefix-cls}-item, + .@{menu-prefix-cls}-submenu-title { + color: @text-color-base; + + &:hover { + color: @primary-color; + } + + &-selected { + z-index: 2; + background-color: fade(@primary-color, 10); + color: @primary-color; + + .light-border(); + } + } + } + } +} + +.content(); +.content() { + .@{menu-prefix-cls} { + display: block; + position: relative; + width: 100%; + margin: 0; + padding: 0; + outline: none; + color: @text-color-base; + font-size: @font-size-base; + list-style: none; + + // .collapse-transition { + // transition: @transition-time height ease-in-out, @transition-time padding-top ease-in-out, + // @transition-time padding-bottom ease-in-out; + // } + + &-light { + background-color: #fff; + + .@{menu-prefix-cls}-submenu-active { + color: @primary-color !important; + + &-border { + .light-border(); + } + } + } + + &-dark { + .@{menu-prefix-cls}-submenu-active { + color: #fff !important; + } + } + + &-item { + display: flex; + position: relative; + z-index: 1; + align-items: center; + outline: none; + color: inherit; + font-size: @font-size-base; + list-style: none; + cursor: pointer; + + &:hover, + &:active { + color: inherit; + } + } + + &-item > i { + margin-right: 6px; + } + + &-submenu-title > i, + &-submenu-title span > i { + margin-right: 8px; + } + + // vertical + &-vertical &-item, + &-vertical &-submenu-title { + position: relative; + z-index: 1; + padding: 14px 24px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + cursor: pointer; + + &:hover { + color: @primary-color; + } + + .@{menu-prefix-cls}-tooltip { + width: calc(100% - 0px); + padding: 12px 0; + text-align: center; + } + .@{menu-prefix-cls}-submenu-popup { + padding: 12px 0; + } + } + + &-vertical &-submenu-collapse { + .@{submenu-popup-prefix-cls} { + display: flex; + align-items: center; + justify-content: center; + } + .@{menu-prefix-cls}-submenu-collapsed-show-tit { + flex-direction: column; + } + } + + &-vertical&-collapse &-item, + &-vertical&-collapse &-submenu-title { + padding: 0; + } + + &-vertical &-submenu-title-icon { + position: absolute; + top: 50%; + right: 18px; + transform: translateY(-50%); + } + + &-submenu-title-icon { + transition: transform @transition-time @ease-in-out; + } + + &-vertical &-opened > * > &-submenu-title-icon { + transform: translateY(-50%) rotate(180deg); + } + + &-vertical &-submenu { + &-nested { + padding-left: 20px; + } + .@{menu-prefix-cls}-item { + padding-left: 43px; + } + } + + &-light&-vertical &-item { + &-active:not(.@{menu-prefix-cls}-submenu) { + z-index: 2; + background-color: fade(@primary-color, 10); + color: @primary-color; + + .light-border(); + } + &-active.@{menu-prefix-cls}-submenu { + color: @primary-color; + } + } + + &-light&-vertical&-collapse { + > li.@{menu-prefix-cls}-item-active, + .@{menu-prefix-cls}-submenu-active { + position: relative; + background-color: fade(@primary-color, 5); + + &::after { + display: none; + } + + &::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 3px; + height: 100%; + background-color: @primary-color; + } + } + } + + &-dark&-vertical &-item, + &-dark&-vertical &-submenu-title { + color: @menu-dark-subsidiary-color; + &-active:not(.@{menu-prefix-cls}-submenu) { + background-color: @primary-color !important; + color: #fff !important; + } + + &:hover { + color: #fff; + } + } + + &-dark&-vertical&-collapse { + > li.@{menu-prefix-cls}-item-active, + .@{menu-prefix-cls}-submenu-active { + position: relative; + background-color: @sider-dark-darken-bg-color !important; + color: #fff !important; + + &::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 3px; + height: 100%; + background-color: @primary-color; + } + + .@{menu-prefix-cls}-submenu-collapse { + background-color: transparent; + } + } + } + + &-dark&-vertical &-submenu &-item { + &-active, + &-active:hover { + border-right: none; + color: #fff; + } + } + + &-dark&-vertical &-child-item-active > &-submenu-title { + color: #fff; + } + + &-dark&-vertical &-opened { + .@{menu-prefix-cls}-submenu-has-parent-submenu { + .@{menu-prefix-cls}-submenu-title { + background-color: transparent; + } + } + } + } +} diff --git a/web/src/components/SimpleMenu/src/components/types.ts b/web/src/components/SimpleMenu/src/components/types.ts new file mode 100644 index 00000000..d828e89a --- /dev/null +++ b/web/src/components/SimpleMenu/src/components/types.ts @@ -0,0 +1,25 @@ +import { Ref } from 'vue'; + +export interface Props { + theme: string; + activeName?: string | number | undefined; + openNames: string[]; + accordion: boolean; + width: string; + collapsedWidth: string; + indentSize: number; + collapse: boolean; + activeSubMenuNames: (string | number)[]; +} + +export interface SubMenuProvider { + addSubMenu: (name: string | number, update?: boolean) => void; + removeSubMenu: (name: string | number, update?: boolean) => void; + removeAll: () => void; + sliceIndex: (index: number) => void; + isRemoveAllPopup: Ref; + getOpenNames: () => (string | number)[]; + handleMouseleave?: Fn; + level: number; + props: Props; +} diff --git a/web/src/components/SimpleMenu/src/components/useMenu.ts b/web/src/components/SimpleMenu/src/components/useMenu.ts new file mode 100644 index 00000000..8830559d --- /dev/null +++ b/web/src/components/SimpleMenu/src/components/useMenu.ts @@ -0,0 +1,84 @@ +import { computed, ComponentInternalInstance, unref } from 'vue'; +import type { CSSProperties } from 'vue'; + +export function useMenuItem(instance: ComponentInternalInstance | null) { + const getParentMenu = computed(() => { + return findParentMenu(['Menu', 'SubMenu']); + }); + + const getParentRootMenu = computed(() => { + return findParentMenu(['Menu']); + }); + + const getParentSubMenu = computed(() => { + return findParentMenu(['SubMenu']); + }); + + const getItemStyle = computed((): CSSProperties => { + let parent = instance?.parent; + if (!parent) return {}; + const indentSize = (unref(getParentRootMenu)?.props.indentSize as number) ?? 20; + let padding = indentSize; + + if (unref(getParentRootMenu)?.props.collapse) { + padding = indentSize; + } else { + while (parent && parent.type.name !== 'Menu') { + if (parent.type.name === 'SubMenu') { + padding += indentSize; + } + parent = parent.parent; + } + } + return { paddingLeft: padding + 'px' }; + }); + + function findParentMenu(name: string[]) { + let parent = instance?.parent; + if (!parent) return null; + while (parent && name.indexOf(parent.type.name!) === -1) { + parent = parent.parent; + } + return parent; + } + + function getParentList() { + let parent = instance; + if (!parent) + return { + uidList: [], + list: [], + }; + const ret: any[] = []; + while (parent && parent.type.name !== 'Menu') { + if (parent.type.name === 'SubMenu') { + ret.push(parent); + } + parent = parent.parent; + } + return { + uidList: ret.map((item) => item.uid), + list: ret, + }; + } + + function getParentInstance(instance: ComponentInternalInstance, name = 'SubMenu') { + let parent = instance.parent; + while (parent) { + if (parent.type.name !== name) { + return parent; + } + parent = parent.parent; + } + return parent; + } + + return { + getParentMenu, + getParentInstance, + getParentRootMenu, + getParentList, + getParentSubMenu, + getItemStyle, + }; +} diff --git a/web/src/components/SimpleMenu/src/components/useSimpleMenuContext.ts b/web/src/components/SimpleMenu/src/components/useSimpleMenuContext.ts new file mode 100644 index 00000000..f3d81003 --- /dev/null +++ b/web/src/components/SimpleMenu/src/components/useSimpleMenuContext.ts @@ -0,0 +1,18 @@ +import type { InjectionKey, Ref } from 'vue'; +import type { Emitter } from '/@/utils/mitt'; +import { createContext, useContext } from '/@/hooks/core/useContext'; + +export interface SimpleRootMenuContextProps { + rootMenuEmitter: Emitter; + activeName: Ref; +} + +const key: InjectionKey = Symbol(); + +export function createSimpleRootMenuContext(context: SimpleRootMenuContextProps) { + return createContext(context, key, { readonly: false, native: true }); +} + +export function useSimpleRootMenuContext() { + return useContext(key); +} diff --git a/web/src/components/SimpleMenu/src/index.less b/web/src/components/SimpleMenu/src/index.less new file mode 100644 index 00000000..74fe82b7 --- /dev/null +++ b/web/src/components/SimpleMenu/src/index.less @@ -0,0 +1,77 @@ +@simple-prefix-cls: ~'@{namespace}-simple-menu'; +@prefix-cls: ~'@{namespace}-menu'; + +.@{prefix-cls} { + &-dark&-vertical .@{simple-prefix-cls}__parent { + background-color: @sider-dark-bg-color; + > .@{prefix-cls}-submenu-title { + background-color: @sider-dark-bg-color; + } + } + + &-dark&-vertical .@{simple-prefix-cls}__children, + &-dark&-popup .@{simple-prefix-cls}__children { + background-color: @sider-dark-lighten-bg-color; + > .@{prefix-cls}-submenu-title { + background-color: @sider-dark-lighten-bg-color; + } + } + + .collapse-title { + overflow: hidden; + font-size: 12px; + text-overflow: ellipsis; + white-space: nowrap; + } +} + +.@{simple-prefix-cls} { + &-sub-title { + overflow: hidden; + transition: all 0.3s; + text-overflow: ellipsis; + white-space: nowrap; + } + + &-tag { + display: inline-block; + position: absolute; + top: calc(50% - 8px); + right: 30px; + margin-right: 4px; + padding: 2px 3px; + border-radius: 2px; + color: #fff; + font-size: 10px; + line-height: 14px; + + &--collapse { + top: 6px !important; + right: 2px; + } + + &--dot { + top: calc(50% - 2px); + width: 6px; + height: 6px; + padding: 0; + border-radius: 50%; + } + + &--primary { + background-color: @primary-color; + } + + &--error { + background-color: @error-color; + } + + &--success { + background-color: @success-color; + } + + &--warn { + background-color: @warning-color; + } + } +} diff --git a/web/src/components/SimpleMenu/src/types.ts b/web/src/components/SimpleMenu/src/types.ts new file mode 100644 index 00000000..e69de29b diff --git a/web/src/components/SimpleMenu/src/useOpenKeys.ts b/web/src/components/SimpleMenu/src/useOpenKeys.ts new file mode 100644 index 00000000..1028f974 --- /dev/null +++ b/web/src/components/SimpleMenu/src/useOpenKeys.ts @@ -0,0 +1,48 @@ +import type { Menu as MenuType } from '/@/router/types'; +import type { MenuState } from './types'; +import { computed, Ref, toRaw, unref } from 'vue'; +import { uniq } from 'lodash-es'; +import { getAllParentPath } from '/@/router/helper/menuHelper'; +import { useTimeoutFn } from '@vben/hooks'; +import { useDebounceFn } from '@vueuse/core'; + +export function useOpenKeys( + menuState: MenuState, + menus: Ref, + accordion: Ref, + mixSider: Ref, + collapse: Ref, +) { + const debounceSetOpenKeys = useDebounceFn(setOpenKeys, 50); + async function setOpenKeys(path: string) { + const native = !mixSider.value; + const menuList = toRaw(menus.value); + + const handle = () => { + if (menuList?.length === 0) { + menuState.activeSubMenuNames = []; + menuState.openNames = []; + return; + } + const keys = getAllParentPath(menuList, path); + + if (!unref(accordion)) { + menuState.openNames = uniq([...menuState.openNames, ...keys]); + } else { + menuState.openNames = keys; + } + menuState.activeSubMenuNames = menuState.openNames; + }; + if (native) { + handle(); + } else { + useTimeoutFn(handle, 30); + } + } + + const getOpenKeys = computed(() => { + return unref(collapse) ? [] : menuState.openNames; + }); + + return { setOpenKeys: debounceSetOpenKeys, getOpenKeys }; +} From 42b3bfa35c4dc24a4d24a6a1c25d455997637d01 Mon Sep 17 00:00:00 2001 From: jameszow Date: Fri, 15 Dec 2023 12:49:47 +0800 Subject: [PATCH 03/17] Fix: adding status filtering --- .../com/wansenai/service/basic/impl/CustomerServiceImpl.kt | 2 ++ .../kotlin/com/wansenai/service/basic/impl/MemberServiceImpl.kt | 1 + .../com/wansenai/service/basic/impl/SupplierServiceImpl.kt | 2 ++ 3 files changed, 5 insertions(+) diff --git a/core/service/src/main/kotlin/com/wansenai/service/basic/impl/CustomerServiceImpl.kt b/core/service/src/main/kotlin/com/wansenai/service/basic/impl/CustomerServiceImpl.kt index 6730ec60..8e1e3155 100644 --- a/core/service/src/main/kotlin/com/wansenai/service/basic/impl/CustomerServiceImpl.kt +++ b/core/service/src/main/kotlin/com/wansenai/service/basic/impl/CustomerServiceImpl.kt @@ -98,7 +98,9 @@ open class CustomerServiceImpl( queryCustomerDTO?.phoneNumber?.let { like(Customer::getPhoneNumber, it) } queryCustomerDTO?.startDate?.let { ge(Customer::getCreateTime, it) } queryCustomerDTO?.endDate?.let { le(Customer::getCreateTime, it) } + eq(Customer::getStatus, CommonConstants.STATUS_NORMAL) eq(Customer::getDeleteFlag, CommonConstants.NOT_DELETED) + .orderByAsc(Customer::getSort) } val list = customerMapper.selectList(wrapper) val listVo = list.map { customer -> diff --git a/core/service/src/main/kotlin/com/wansenai/service/basic/impl/MemberServiceImpl.kt b/core/service/src/main/kotlin/com/wansenai/service/basic/impl/MemberServiceImpl.kt index fae20eae..38b1e6cd 100644 --- a/core/service/src/main/kotlin/com/wansenai/service/basic/impl/MemberServiceImpl.kt +++ b/core/service/src/main/kotlin/com/wansenai/service/basic/impl/MemberServiceImpl.kt @@ -173,6 +173,7 @@ open class MemberServiceImpl( .eq(StringUtils.hasLength(memberDTO?.phoneNumber), Member::getPhoneNumber, memberDTO?.phoneNumber) .ge(StringUtils.hasLength(memberDTO?.startDate), Member::getCreateTime, memberDTO?.startDate) .le(StringUtils.hasLength(memberDTO?.endDate), Member::getCreateTime, memberDTO?.endDate) + .eq(Member::getStatus, CommonConstants.STATUS_NORMAL) .eq(Member::getDeleteFlag, CommonConstants.NOT_DELETED) .orderByAsc(Member::getSort) ) diff --git a/core/service/src/main/kotlin/com/wansenai/service/basic/impl/SupplierServiceImpl.kt b/core/service/src/main/kotlin/com/wansenai/service/basic/impl/SupplierServiceImpl.kt index 53129cee..b19eaf64 100644 --- a/core/service/src/main/kotlin/com/wansenai/service/basic/impl/SupplierServiceImpl.kt +++ b/core/service/src/main/kotlin/com/wansenai/service/basic/impl/SupplierServiceImpl.kt @@ -136,7 +136,9 @@ open class SupplierServiceImpl( supplier?.phoneNumber?.let { like(Supplier::getPhoneNumber, it) } supplier?.startDate?.let { ge(Supplier::getCreateTime, it) } supplier?.endDate?.let { le(Supplier::getCreateTime, it) } + eq(Supplier::getStatus, CommonConstants.STATUS_NORMAL) eq(Supplier::getDeleteFlag, CommonConstants.NOT_DELETED) + orderByAsc(Supplier::getSort) } val list = supplierMapper.selectList(wrapper) val listVo = list.map { supplier -> From 4164e0c641d2f6db25d5fb0a2f4e6033ec2bae9e Mon Sep 17 00:00:00 2001 From: jameszow Date: Fri, 15 Dec 2023 12:50:23 +0800 Subject: [PATCH 04/17] Fix: add register in emitSuccess --- .../layouts/default/header/components/user-dropdown/index.vue | 1 - web/src/views/basic/member/components/MemberModal.vue | 2 +- .../settlement-account/components/FinancialAccountModal.vue | 2 +- web/src/views/product/info/components/SelectProductModal.vue | 2 +- web/src/views/receipt/LinkReceiptModal.vue | 2 +- web/src/views/receipt/ReceiptDetailModal.vue | 2 +- web/src/views/warehouse/shipments/index.vue | 2 +- 7 files changed, 6 insertions(+), 7 deletions(-) diff --git a/web/src/layouts/default/header/components/user-dropdown/index.vue b/web/src/layouts/default/header/components/user-dropdown/index.vue index d46a5293..11f93183 100644 --- a/web/src/layouts/default/header/components/user-dropdown/index.vue +++ b/web/src/layouts/default/header/components/user-dropdown/index.vue @@ -38,7 +38,6 @@ -