diff --git a/packages/abc/page-header/index.md b/packages/abc/page-header/index.md index 661ca27be..ea9a4912e 100644 --- a/packages/abc/page-header/index.md +++ b/packages/abc/page-header/index.md @@ -20,6 +20,7 @@ config: PageHeaderConfig `[homeLink]` | 首页链接 | `string` | `/` `[homeI18n]` | 首页链接国际化参数 | `string` | - `[autoBreadcrumb]` | 自动生成导航,以当前路由从主菜单中定位 | `boolean` | `true` +`[recursiveBreadcrumb]` | 自动向上递归查找,菜单数据源包含 `/ware`,则 `/ware/1` 也视为 `/ware` 项 | `boolean` | `false` `[loading]` | 是否加载中 | `boolean` | `false` `[wide]` | 是否定宽 | `boolean` | `false` `[fixed]` | 是否固定模式 | `boolean` | `false` diff --git a/packages/abc/page-header/page-header.component.ts b/packages/abc/page-header/page-header.component.ts index 2f9c04d78..263099cb6 100644 --- a/packages/abc/page-header/page-header.component.ts +++ b/packages/abc/page-header/page-header.component.ts @@ -51,7 +51,7 @@ export class PageHeaderComponent if (this._menus) { return this._menus; } - this._menus = this.menuSrv.getPathByUrl(this.route.url.split('?')[0]); + this._menus = this.menuSrv.getPathByUrl(this.route.url.split('?')[0], this.recursiveBreadcrumb); return this._menus; } @@ -121,6 +121,10 @@ export class PageHeaderComponent @Input() breadcrumb: TemplateRef; + @Input() + @InputBoolean() + recursiveBreadcrumb: boolean; + @Input() logo: TemplateRef; diff --git a/packages/abc/page-header/page-header.config.ts b/packages/abc/page-header/page-header.config.ts index c8309a378..d1db22291 100644 --- a/packages/abc/page-header/page-header.config.ts +++ b/packages/abc/page-header/page-header.config.ts @@ -15,6 +15,11 @@ export class PageHeaderConfig { * 自动生成导航,以当前路由从主菜单中定位 */ autoBreadcrumb?: boolean = true; + /** + * 自动向上递归查找 + * - 菜单数据源包含 `/ware`,则 `/ware/1` 也视为 `/ware` 项 + */ + recursiveBreadcrumb?: boolean = false; /** * 自动生成标题,以当前路由从主菜单中定位 */ diff --git a/packages/theme/src/services/menu/index.en-US.md b/packages/theme/src/services/menu/index.en-US.md index 89575f8e7..8ef62933c 100644 --- a/packages/theme/src/services/menu/index.en-US.md +++ b/packages/theme/src/services/menu/index.en-US.md @@ -19,5 +19,9 @@ This is because menus it's essential part of the applications, And it can be use | `add` | `items: Menu[]` | Setting menu data | | `clear` | - | Clear menu data | | `resume` | `callback: Funection` | Reset menu, may need call when I18N, user acl changed | -| `openedByUrl` | `url: string` | Set menu `_open` attribute by URL (`_open` expands the submenu) | -| `getPathByUrl` | `url: string` | Get menu list based on url | +| `openedByUrl` | `url, recursive = false` | Set menu `_open` attribute by URL (`_open` expands the submenu) | +| `getPathByUrl` | `url, recursive = false` | Get menu list based on url | + +**recursive** + +Recursive upward find, for example, the menu data source contains `/ware`, then `/ware/1` is equivalent to `/ware`. diff --git a/packages/theme/src/services/menu/index.zh-CN.md b/packages/theme/src/services/menu/index.zh-CN.md index 5e2177e4f..95e791353 100644 --- a/packages/theme/src/services/menu/index.zh-CN.md +++ b/packages/theme/src/services/menu/index.zh-CN.md @@ -17,5 +17,9 @@ type: Service | `add` | `items: Menu[]` | 设置菜单数据 | | `clear` | - | 清空菜单数据 | | `resume` | `callback: Funection` | 重置菜单,可能I18N、用户权限变动时需要调用刷新 | -| `openedByUrl` | `url: string` | 根据URL设置菜单 `_open` 属性(`_open`用于是否展开菜单的条件值) | -| `getPathByUrl` | `url: string` | 根据url获取菜单列表 | +| `openedByUrl` | `url, recursive = false` | 根据URL设置菜单 `_open` 属性(`_open`用于是否展开菜单的条件值) | +| `getPathByUrl` | `url, recursive = false` | 根据url获取菜单列表 | + +**recursive** + +表示自动向上递归查找,例如菜单数据源包含 `/ware`,则 `/ware/1` 也视为 `/ware` 项。 diff --git a/packages/theme/src/services/menu/menu.service.spec.ts b/packages/theme/src/services/menu/menu.service.spec.ts index 4689a220b..c55fe72c3 100644 --- a/packages/theme/src/services/menu/menu.service.spec.ts +++ b/packages/theme/src/services/menu/menu.service.spec.ts @@ -116,6 +116,11 @@ describe('Service: Menu', () => { srv.openedByUrl(null); expect(srv.menus.filter(w => w._open === false).length).toBe(0); }); + it('recursive up find', () => { + srv.add(deepCopy(DATA)); + srv.openedByUrl(`/dashboard/v1/1`, true); + expect(srv.menus[0]._open).toBe(true); + }); }); describe('#getPathByUrl', () => { @@ -130,6 +135,11 @@ describe('Service: Menu', () => { const menus = srv.getPathByUrl(`/dashboard/v1111`); expect(menus.length).toBe(0); }); + it('recursive up find', () => { + srv.add(deepCopy(DATA)); + expect(srv.getPathByUrl(`/dashboard/1`).length).toBe(0); + expect(srv.getPathByUrl(`/dashboard/1`, true).length).toBe(1); + }); }); describe('#shortcuts', () => { diff --git a/packages/theme/src/services/menu/menu.service.ts b/packages/theme/src/services/menu/menu.service.ts index fd2a3897b..1361f6055 100644 --- a/packages/theme/src/services/menu/menu.service.ts +++ b/packages/theme/src/services/menu/menu.service.ts @@ -85,7 +85,10 @@ export class MenuService implements OnDestroy { // compatible `anticon anticon-user` if (~item.icon.indexOf(`anticon-`)) { type = 'icon'; - value = value.split('-').slice(1).join('-'); + value = value + .split('-') + .slice(1) + .join('-'); } else if (/^https?:\/\//.test(item.icon)) { type = 'img'; } @@ -168,23 +171,39 @@ export class MenuService implements OnDestroy { this._change$.next(this.data); } + private getHit(url: string, recursive = false, cb: (i: Menu) => void = null) { + let item: Menu = null; + + while (!item && url) { + this.visit(i => { + if (cb) { + cb(i); + } + if (i.link != null && i.link === url) { + item = i; + } + }); + + if (!recursive) break; + + url = url + .split('/') + .slice(0, -1) + .join('/'); + } + + return item; + } + /** * 根据URL设置菜单 `_open` 属性 - * @param url URL地址 + * - 若 `recursive: true` 则会自动向上递归查找 + * - 菜单数据源包含 `/ware`,则 `/ware/1` 也视为 `/ware` 项 */ - openedByUrl(url: string) { + openedByUrl(url: string, recursive = false) { if (!url) return; - let findItem: Menu = null; - this.visit(item => { - item._open = false; - if (!item.link) { - return; - } - if (!findItem && url.startsWith(item.link)) { - findItem = item; - } - }); + let findItem = this.getHit(url, recursive, i => (i._open = false)); if (!findItem) return; do { @@ -195,17 +214,13 @@ export class MenuService implements OnDestroy { /** * 根据url获取菜单列表 - * @param url + * - 若 `recursive: true` 则会自动向上递归查找 + * - 菜单数据源包含 `/ware`,则 `/ware/1` 也视为 `/ware` 项 */ - getPathByUrl(url: string): Menu[] { - let item: Menu = null; - this.visit((i, parent, depth) => { - if (i.link === url) { - item = i; - } - }); - + getPathByUrl(url: string, recursive = false): Menu[] { const ret: Menu[] = []; + let item = this.getHit(url, recursive); + if (!item) return ret; do { diff --git a/scripts/ci/deploy.sh b/scripts/ci/deploy.sh index 6688659ca..62c64257d 100644 --- a/scripts/ci/deploy.sh +++ b/scripts/ci/deploy.sh @@ -76,11 +76,6 @@ travisFoldStart "publish.dist" echo "Removed everything from ${packageRepo}#${branchName} and added the new build output." - if [[ $(git ls-remote origin "refs/tags/${buildTagName}") ]]; then - echo "Skipping publish because tag is already published" - exit 0 - fi - # 替换版本号 if [[ $commitMessageCheck =~ "release(" ]]; then echo "===== Release version does not need to change version =====" @@ -98,6 +93,11 @@ travisFoldStart "publish.dist" echo "https://${DELON_BUILDS_TOKEN}:@github.com" > .git/credentials + if [[ $(git ls-remote origin "refs/tags/${buildTagName}") ]]; then + echo "removed tag because tag is already published" + git push origin :refs/tags/${buildTagName} + fi + echo "Git configuration has been updated to match the last commit author. Publishing now.." git add -A