cabloy 5.1.45 → 5.1.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/package.json +1 -1
- package/vona/packages-vona/vona/package.json +1 -1
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/package.json +1 -1
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/lib/beanSsrSiteBase.ts +6 -0
- package/vona/src/suite-vendor/a-cabloy/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-executor/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-executor/src/service/executor.ts +4 -1
- package/vona/src/suite-vendor/a-vona/package.json +1 -1
- package/zova/src/suite/a-demo/modules/demo-basic/src/routes.ts +8 -6
- package/zova/src/suite/a-home/modules/home-base/src/component/itemLink/controller.tsx +3 -1
- package/zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/render.header.tsx +1 -1
- package/zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/render.tabs.tsx +152 -62
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 5.1.47
|
|
4
|
+
|
|
5
|
+
### Bug Fixes
|
|
6
|
+
|
|
7
|
+
- Fix web header navigation rendering.
|
|
8
|
+
- Prevent web header dropdown menus from being clipped.
|
|
9
|
+
|
|
10
|
+
### Improvements
|
|
11
|
+
|
|
12
|
+
- Update internal project dependencies and maintenance changes.
|
|
13
|
+
|
|
14
|
+
## 5.1.46
|
|
15
|
+
|
|
16
|
+
### Improvements
|
|
17
|
+
|
|
18
|
+
- Refine SSR site base handling in `beanSsrSiteBase.ts`.
|
|
19
|
+
- Improve executor behavior in `executor.ts`.
|
|
20
|
+
- Update tab rendering logic in `render.tabs.tsx`.
|
|
21
|
+
- Adjust route configuration in `routes.ts`.
|
|
22
|
+
|
|
3
23
|
## 5.1.45
|
|
4
24
|
|
|
5
25
|
### Features
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vona",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.40",
|
|
4
4
|
"gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
|
|
5
5
|
"description": "Vona is an intuitive, elegant and powerful Node.js framework for rapidly developing enterprise applications of any size",
|
|
6
6
|
"keywords": [
|
|
@@ -209,6 +209,12 @@ export class BeanSsrSiteBase<
|
|
|
209
209
|
headers.accept = headers.Accept;
|
|
210
210
|
delete headers.Accept;
|
|
211
211
|
}
|
|
212
|
+
for (const headerKey of ['x-vona-locale', 'x-vona-tz']) {
|
|
213
|
+
const headerValue = headers[headerKey];
|
|
214
|
+
if (headerValue !== undefined) {
|
|
215
|
+
this.ctx.request.headers[headerKey] = headerValue;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
212
218
|
// passport
|
|
213
219
|
if (!ctxInited) {
|
|
214
220
|
// init instance
|
|
@@ -11,24 +11,26 @@ import { ZPageToolOne } from './.metadata/page/toolOne.js';
|
|
|
11
11
|
import { ZPageToolTwo } from './.metadata/page/toolTwo.js';
|
|
12
12
|
|
|
13
13
|
export const routes: IModuleRoute[] = [
|
|
14
|
-
{ path: 'state', component: ZPageState },
|
|
15
|
-
{ path: 'component', component: ZPageComponent },
|
|
16
|
-
{ path: 'locale', component: ZPageLocale },
|
|
17
|
-
{ path: 'style', component: ZPageStyle },
|
|
18
|
-
{ path: 'routeQuery', component: ZPageRouteQuery },
|
|
14
|
+
{ path: 'state', component: ZPageState, meta: { requiresAuth: false } },
|
|
15
|
+
{ path: 'component', component: ZPageComponent, meta: { requiresAuth: false } },
|
|
16
|
+
{ path: 'locale', component: ZPageLocale, meta: { requiresAuth: false } },
|
|
17
|
+
{ path: 'style', component: ZPageStyle, meta: { requiresAuth: false } },
|
|
18
|
+
{ path: 'routeQuery', component: ZPageRouteQuery, meta: { requiresAuth: false } },
|
|
19
19
|
{
|
|
20
20
|
name: 'routeParams',
|
|
21
21
|
path: 'routeParams/:id?',
|
|
22
22
|
component: ZPageRouteParams,
|
|
23
23
|
meta: {
|
|
24
24
|
componentKeyMode: 'nameOnly',
|
|
25
|
+
requiresAuth: false,
|
|
25
26
|
},
|
|
26
27
|
},
|
|
27
|
-
{ path: 'routeQueryB', component: ZPageRouteQueryB },
|
|
28
|
+
{ path: 'routeQueryB', component: ZPageRouteQueryB, meta: { requiresAuth: false } },
|
|
28
29
|
{
|
|
29
30
|
name: 'toolOne',
|
|
30
31
|
path: 'toolOne/:id?',
|
|
31
32
|
component: ZPageToolOne,
|
|
33
|
+
meta: { requiresAuth: false },
|
|
32
34
|
},
|
|
33
35
|
{
|
|
34
36
|
name: 'toolTwo',
|
|
@@ -9,6 +9,7 @@ export interface ControllerItemLinkProps {
|
|
|
9
9
|
icon?: keyof IIconRecord;
|
|
10
10
|
href?: string;
|
|
11
11
|
to?: string | object;
|
|
12
|
+
target?: string;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
@Controller()
|
|
@@ -16,6 +17,7 @@ export class ControllerItemLink extends BeanControllerBase {
|
|
|
16
17
|
static $propsDefault = {
|
|
17
18
|
description: '',
|
|
18
19
|
icon: '',
|
|
20
|
+
target: '_blank',
|
|
19
21
|
};
|
|
20
22
|
|
|
21
23
|
_renderLink() {
|
|
@@ -28,7 +30,7 @@ export class ControllerItemLink extends BeanControllerBase {
|
|
|
28
30
|
];
|
|
29
31
|
if (this.$props.href) {
|
|
30
32
|
return (
|
|
31
|
-
<a href={this.$props.href} target=
|
|
33
|
+
<a href={this.$props.href} target={this.$props.target}>
|
|
32
34
|
{domContent}
|
|
33
35
|
</a>
|
|
34
36
|
);
|
package/zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/render.header.tsx
CHANGED
|
@@ -24,7 +24,7 @@ export class RenderHeader extends BeanRenderBase {
|
|
|
24
24
|
</button>
|
|
25
25
|
</div>
|
|
26
26
|
<div class="text-xl px-4">{this.sys.env.APP_TITLE}</div>
|
|
27
|
-
<div class="mx-2 flex-
|
|
27
|
+
<div class="mx-2 min-w-0 flex-1 px-2">{this.$$r.$$renderTabs.renderTabs()}</div>
|
|
28
28
|
<div class="hidden flex-none lg:block">
|
|
29
29
|
<ul class="menu menu-horizontal">
|
|
30
30
|
{this.$$r.$$renderLocale.render()}
|
package/zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/render.tabs.tsx
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import type { VNode } from 'vue';
|
|
2
|
-
import type { RouteTab } from 'zova-module-a-routertabs';
|
|
3
2
|
|
|
3
|
+
import { RouterLink } from '@cabloy/vue-router';
|
|
4
4
|
import { BeanRenderBase, ClientOnly } from 'zova';
|
|
5
5
|
import { Render } from 'zova-module-a-bean';
|
|
6
|
-
import {
|
|
6
|
+
import { ZIcon } from 'zova-module-a-icon';
|
|
7
7
|
import { ZRouterViewTabs } from 'zova-module-a-routertabs';
|
|
8
|
-
import { closeNearestDetails
|
|
8
|
+
import { closeNearestDetails } from 'zova-module-home-base';
|
|
9
|
+
|
|
10
|
+
import type { TypeMenuGroup, TypeMenuItem } from '../../model/menu.js';
|
|
11
|
+
|
|
12
|
+
type TypeMenuLeaf = Exclude<TypeMenuItem, TypeMenuGroup>;
|
|
9
13
|
|
|
10
14
|
@Render()
|
|
11
15
|
export class RenderTabs extends BeanRenderBase {
|
|
@@ -13,85 +17,171 @@ export class RenderTabs extends BeanRenderBase {
|
|
|
13
17
|
const $$modelTabs = this.$$modelTabs;
|
|
14
18
|
if (!$$modelTabs) return;
|
|
15
19
|
|
|
16
|
-
const domTabs = $$modelTabs.tabs.map(tab =>
|
|
20
|
+
const domTabs = $$modelTabs.tabs.map(tab => {
|
|
21
|
+
return this._renderMenuItem(tab.info as TypeMenuItem, true, tab.tabKey);
|
|
22
|
+
});
|
|
17
23
|
const domWrapper = (
|
|
18
|
-
<
|
|
19
|
-
{domTabs}
|
|
20
|
-
</div>
|
|
24
|
+
<ul class="menu menu-horizontal w-max min-w-full flex-nowrap gap-1 px-0">{domTabs}</ul>
|
|
21
25
|
);
|
|
22
26
|
if (!$$modelTabs.cache) return domWrapper;
|
|
23
|
-
|
|
24
27
|
return <ClientOnly>{domWrapper}</ClientOnly>;
|
|
25
28
|
}
|
|
26
29
|
|
|
27
|
-
private
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
private _renderMenuItem(item: TypeMenuItem, topLevel: boolean = false, tabKey?: string): VNode {
|
|
31
|
+
if (item.folder) {
|
|
32
|
+
return this._renderMenuFolder(item, topLevel);
|
|
33
|
+
}
|
|
34
|
+
if (item.separator) {
|
|
35
|
+
return this._renderMenuSeparator(item, topLevel);
|
|
36
|
+
}
|
|
37
|
+
return this._renderMenuLeaf(item, topLevel, tabKey);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
private _renderMenuFolder(item: TypeMenuGroup, topLevel: boolean): VNode {
|
|
41
|
+
const isActive = this._hasActiveDescendant(item);
|
|
42
|
+
const className = this._getMenuItemClassName(isActive);
|
|
43
|
+
const title = item.title ?? '';
|
|
44
|
+
const childrenClass = topLevel ? 'w-56' : 'w-52';
|
|
45
|
+
return (
|
|
46
|
+
<li key={this._getMenuItemKey(item)}>
|
|
47
|
+
<details>
|
|
48
|
+
<summary class={className}>
|
|
49
|
+
{this._renderItemIcon(item.icon as any)}
|
|
50
|
+
<span>{title}</span>
|
|
51
|
+
</summary>
|
|
52
|
+
<ul class={`bg-base-100 rounded-t-none p-2 shadow ${childrenClass}`}>
|
|
53
|
+
{item.children.map(child => this._renderMenuItem(child))}
|
|
54
|
+
</ul>
|
|
55
|
+
</details>
|
|
56
|
+
</li>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private _renderMenuLeaf(item: TypeMenuLeaf, topLevel: boolean, tabKey?: string): VNode {
|
|
61
|
+
const title = item.title ?? '';
|
|
62
|
+
const key = this._getMenuItemKey(item);
|
|
63
|
+
const className = this._getMenuItemClassName(this._isMenuLeafActive(item, tabKey));
|
|
64
|
+
const domContent = this._renderMenuItemContent(item.icon as any, title);
|
|
65
|
+
const onClick = topLevel ? undefined : closeNearestDetails;
|
|
66
|
+
|
|
67
|
+
if (item.external) {
|
|
33
68
|
return (
|
|
34
|
-
<li>
|
|
35
|
-
<
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
{titleLocale}
|
|
39
|
-
</summary>
|
|
40
|
-
<ClientOnly>
|
|
41
|
-
<ul class="bg-base-100 rounded-t-none p-2 w-48">
|
|
42
|
-
{info.children
|
|
43
|
-
?.filter(item => !item.folder)
|
|
44
|
-
.map(item => (
|
|
45
|
-
<li key={item.link} onClick={closeNearestDetails}>
|
|
46
|
-
<ZItemLink
|
|
47
|
-
title={item.title!}
|
|
48
|
-
icon={(item.icon as any) ?? $iconName('::none')}
|
|
49
|
-
href={item.link && item.external ? item.link : undefined}
|
|
50
|
-
to={item.link && !item.external ? item.link : undefined}
|
|
51
|
-
></ZItemLink>
|
|
52
|
-
</li>
|
|
53
|
-
))}
|
|
54
|
-
</ul>
|
|
55
|
-
</ClientOnly>
|
|
56
|
-
</details>
|
|
69
|
+
<li key={key} onClick={onClick}>
|
|
70
|
+
<a class={className} href={item.link} target={item.target ?? '_blank'}>
|
|
71
|
+
{domContent}
|
|
72
|
+
</a>
|
|
57
73
|
</li>
|
|
58
74
|
);
|
|
59
75
|
}
|
|
60
|
-
// not external
|
|
61
|
-
if (!info.external) {
|
|
62
|
-
const className = tabKey === $$modelTabs.tabKeyCurrent ? 'text-primary' : '';
|
|
63
76
|
|
|
77
|
+
if (topLevel && tabKey) {
|
|
78
|
+
return (
|
|
79
|
+
<li key={key}>
|
|
80
|
+
<a
|
|
81
|
+
class={className}
|
|
82
|
+
onClick={() => {
|
|
83
|
+
void this.$$modelTabs.activeTab(tabKey);
|
|
84
|
+
}}
|
|
85
|
+
>
|
|
86
|
+
{domContent}
|
|
87
|
+
</a>
|
|
88
|
+
</li>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return (
|
|
93
|
+
<li key={key} onClick={onClick}>
|
|
94
|
+
<RouterLink class={className} to={this._buildMenuTo(item)}>
|
|
95
|
+
{domContent}
|
|
96
|
+
</RouterLink>
|
|
97
|
+
</li>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
private _renderMenuSeparator(item: TypeMenuLeaf, topLevel: boolean): VNode {
|
|
102
|
+
const key = `${this._getMenuItemKey(item)}:separator`;
|
|
103
|
+
if (topLevel) {
|
|
64
104
|
return (
|
|
65
|
-
<
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
class={`tab ${className}`}
|
|
69
|
-
onClick={() => {
|
|
70
|
-
$$modelTabs.activeTab(tabKey);
|
|
71
|
-
}}
|
|
72
|
-
>
|
|
73
|
-
{!!tabIcon && <ZIcon name={tabIcon as any} width="24"></ZIcon>}
|
|
74
|
-
{titleLocale}
|
|
75
|
-
</a>
|
|
105
|
+
<li key={key} class="mx-1 self-center opacity-30">
|
|
106
|
+
<span class="pointer-events-none px-0">|</span>
|
|
107
|
+
</li>
|
|
76
108
|
);
|
|
77
109
|
}
|
|
78
|
-
|
|
110
|
+
return <li key={key} class="menu-disabled my-1 h-px bg-base-300"></li>;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
private _buildMenuTo(item: TypeMenuLeaf) {
|
|
114
|
+
let to: any;
|
|
115
|
+
if (!item.external) {
|
|
116
|
+
to = {};
|
|
117
|
+
if (this.$router.isRouterName(item.link)) {
|
|
118
|
+
to.name = item.link;
|
|
119
|
+
} else {
|
|
120
|
+
to.path = item.link;
|
|
121
|
+
}
|
|
122
|
+
if (item.meta?.params && to.name) {
|
|
123
|
+
to.params = item.meta.params;
|
|
124
|
+
}
|
|
125
|
+
if (item.meta?.query) {
|
|
126
|
+
to.query = item.meta.query;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return to;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
private _hasActiveDescendant(item: TypeMenuGroup): boolean {
|
|
133
|
+
return item.children.some(child => {
|
|
134
|
+
if (child.folder) return this._hasActiveDescendant(child);
|
|
135
|
+
return this._isMenuLeafCurrent(child);
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
private _isMenuLeafActive(item: TypeMenuLeaf, tabKey?: string): boolean {
|
|
140
|
+
if (item.external || !item.link) return false;
|
|
141
|
+
if (tabKey && tabKey === this.$$modelTabs.tabKeyCurrent) return true;
|
|
142
|
+
return this._isMenuLeafCurrent(item);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
private _isMenuLeafCurrent(item: TypeMenuLeaf): boolean {
|
|
146
|
+
if (item.external || !item.link) return false;
|
|
147
|
+
const currentRoute = this.$currentRoute;
|
|
148
|
+
if (!currentRoute) return false;
|
|
149
|
+
const fullPath = this.$router.isRouterName(item.link)
|
|
150
|
+
? this.$router.resolveName(
|
|
151
|
+
item.link as never,
|
|
152
|
+
{
|
|
153
|
+
params: item.meta?.params,
|
|
154
|
+
query: item.meta?.query,
|
|
155
|
+
} as never,
|
|
156
|
+
)
|
|
157
|
+
: this.$router.resolvePath(item.link as never, item.meta?.query as never);
|
|
158
|
+
return currentRoute.fullPath === fullPath;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
private _getMenuItemKey(item: TypeMenuItem): string {
|
|
162
|
+
if (item.folder) return item.name || item.title || '';
|
|
163
|
+
return item.name || item.link || item.title || '';
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
private _getMenuItemClassName(isActive: boolean): string {
|
|
167
|
+
return isActive ? 'active text-primary' : '';
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
private _renderMenuItemContent(icon: string | undefined, title: string): VNode {
|
|
79
171
|
return (
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
title
|
|
83
|
-
|
|
84
|
-
href={info.link}
|
|
85
|
-
></ZItemLink>
|
|
172
|
+
<>
|
|
173
|
+
{this._renderItemIcon(icon)}
|
|
174
|
+
<span>{title}</span>
|
|
175
|
+
</>
|
|
86
176
|
);
|
|
87
177
|
}
|
|
88
178
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
return
|
|
179
|
+
private _renderItemIcon(icon?: string): VNode | undefined {
|
|
180
|
+
if (!icon) return;
|
|
181
|
+
return <ZIcon name={icon as any} width="20" height="20"></ZIcon>;
|
|
92
182
|
}
|
|
93
183
|
|
|
94
|
-
_renderRouterViewTabs() {
|
|
184
|
+
public _renderRouterViewTabs(): VNode {
|
|
95
185
|
return <ZRouterViewTabs></ZRouterViewTabs>;
|
|
96
186
|
}
|
|
97
187
|
}
|