@owlmeans/client-panel 0.1.18-rc.24 → 0.1.18-rc.26
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/README.md +3 -2
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/client-panel/SKILL.md +3 -3
- package/build/components/nav/helper.d.ts.map +1 -1
- package/build/components/nav/helper.js +7 -8
- package/build/components/nav/helper.js.map +1 -1
- package/build/components/nav/types.d.ts +2 -3
- package/build/components/nav/types.d.ts.map +1 -1
- package/package.json +14 -14
- package/src/components/nav/helper.ts +7 -9
- package/src/components/nav/types.ts +2 -3
package/README.md
CHANGED
|
@@ -26,12 +26,13 @@ A complete form with submit and cancel actions:
|
|
|
26
26
|
```typescript
|
|
27
27
|
import { ClientForm, InputCtrl, ActionCtrl, useFormRef } from '@owlmeans/client-panel'
|
|
28
28
|
import type { FormOnSubmit } from '@owlmeans/client-panel'
|
|
29
|
+
import { appEntrypoints } from 'my-app-common'
|
|
29
30
|
|
|
30
31
|
function CreateProjectForm() {
|
|
31
32
|
const formRef = useFormRef()
|
|
32
33
|
|
|
33
34
|
const onSubmit: FormOnSubmit<CreateProject> = async (data) => {
|
|
34
|
-
await ctx.entrypoint
|
|
35
|
+
await ctx.entrypoint(appEntrypoints.api.projectCreate).call({ body: data })
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
return (
|
|
@@ -152,7 +153,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
152
153
|
your project's skill store (`.agents/skills/`):
|
|
153
154
|
|
|
154
155
|
```sh
|
|
155
|
-
npx @owlmeans/agent-skills@^0.1.18-rc.
|
|
156
|
+
npx @owlmeans/agent-skills@^0.1.18-rc.15
|
|
156
157
|
```
|
|
157
158
|
|
|
158
159
|
The embedded files are version-matched to this package release. Do not edit them
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/client-panel",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-09-
|
|
4
|
+
"version": "0.1.18-rc.26",
|
|
5
|
+
"generatedAt": "2026-09-12T08:39:52.734Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -8,7 +8,7 @@ user-invocable: false
|
|
|
8
8
|
# @owlmeans/client-panel
|
|
9
9
|
|
|
10
10
|
**Layer:** Client
|
|
11
|
-
**Install:** `"@owlmeans/client-panel": "^0.1.18-rc.
|
|
11
|
+
**Install:** `"@owlmeans/client-panel": "^0.1.18-rc.26"` in `dependencies`
|
|
12
12
|
|
|
13
13
|
## Key Exports
|
|
14
14
|
|
|
@@ -122,10 +122,10 @@ alias, or null), `active` (its section), `showSide`, `isSectionActive` / `isItem
|
|
|
122
122
|
first, then by longest prefix, so a detail screen under a listed one still belongs to its section.
|
|
123
123
|
A screen listed in no section resolves its section by walking `route.route.parent` upward.
|
|
124
124
|
- **`hrefOf` gives a menu entry a real URL**, resolved synchronously from
|
|
125
|
-
`context.entrypoint(
|
|
125
|
+
`context.entrypoint(protocol).path()` — a protocol composes its path from its own declaration and
|
|
126
126
|
its ancestors', so matching one is a lookup rather than a guess. It returns undefined for a path
|
|
127
127
|
carrying route parameters (`:id`) — there is no honest URL for a screen whose address is not
|
|
128
|
-
known yet.
|
|
128
|
+
known yet. A protocol the app never bound resolves to null and is skipped rather than taking the
|
|
129
129
|
menu down.
|
|
130
130
|
|
|
131
131
|
## Depends On
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../../../src/components/nav/helper.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../../../src/components/nav/helper.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAgB,aAAa,EAAmB,MAAM,YAAY,CAAA;AAE5G,uFAAuF;AACvF,eAAO,MAAM,mBAAmB,EAAE,YAAmD,CAAA;AAErF;;;GAGG;AACH,eAAO,MAAM,eAAe,UAAW,MAAM,KAAG,MAK/C,CAAA;AAED,eAAO,MAAM,eAAe,cACf,YAAY,SAAS,MAAM,GAAG,SAAS,OAAO,MAAM,UAAU,MAAM,KAC9E,MAAgE,CAAA;AAQnE;;;;;;;;;GASG;AACH,eAAO,MAAM,WAAW,WAAY,cAAc,KAAG,aA6FpD,CAAA"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
|
-
import { aliasOf } from '@owlmeans/entrypoint';
|
|
3
2
|
import { useContext, useNavigate } from '@owlmeans/client';
|
|
4
3
|
/** Default resolver: no i18n, the caller's fallback wins. See {@link NavTranslate}. */
|
|
5
4
|
export const defaultNavTranslate = (_key, defaultValue) => defaultValue;
|
|
@@ -35,12 +34,12 @@ export const usePanelNav = (config) => {
|
|
|
35
34
|
const sections = config.sections
|
|
36
35
|
.filter(section => section.hidden !== true)
|
|
37
36
|
.map(section => ({ ...section, items: visibleItems(section) }));
|
|
38
|
-
const pathOf = (
|
|
37
|
+
const pathOf = (alias) => {
|
|
39
38
|
try {
|
|
40
|
-
return normalizePath(context.entrypoint(
|
|
39
|
+
return normalizePath(context.entrypoint(alias).path());
|
|
41
40
|
}
|
|
42
41
|
catch {
|
|
43
|
-
//
|
|
42
|
+
// A protocol the app never bound addresses nothing — it cannot be the current screen,
|
|
44
43
|
// and it must not take the menu down with it.
|
|
45
44
|
return null;
|
|
46
45
|
}
|
|
@@ -51,7 +50,7 @@ export const usePanelNav = (config) => {
|
|
|
51
50
|
const here = normalizePath(pathname);
|
|
52
51
|
const exact = all.find(item => pathOf(item.alias) === here);
|
|
53
52
|
if (exact != null) {
|
|
54
|
-
current =
|
|
53
|
+
current = exact.alias;
|
|
55
54
|
}
|
|
56
55
|
else {
|
|
57
56
|
// Longest prefix: a detail screen under a listed one still belongs to its section.
|
|
@@ -59,10 +58,10 @@ export const usePanelNav = (config) => {
|
|
|
59
58
|
.map(item => ({ item, path: pathOf(item.alias) }))
|
|
60
59
|
.filter((entry) => entry.path != null && entry.path !== '/' && here.startsWith(`${entry.path}/`))
|
|
61
60
|
.sort((a, b) => b.path.length - a.path.length)[0];
|
|
62
|
-
current = prefixed
|
|
61
|
+
current = prefixed?.item.alias ?? null;
|
|
63
62
|
}
|
|
64
63
|
}
|
|
65
|
-
const sectionOf = (alias) => alias == null ? null : sections.find(section => section.items.some(item =>
|
|
64
|
+
const sectionOf = (alias) => alias == null ? null : sections.find(section => section.items.some(item => item.alias === alias)) ?? null;
|
|
66
65
|
let active = sectionOf(current);
|
|
67
66
|
if (active == null && current != null) {
|
|
68
67
|
// The current screen is not listed anywhere — walk up to the ancestor that is, so a
|
|
@@ -84,7 +83,7 @@ export const usePanelNav = (config) => {
|
|
|
84
83
|
}
|
|
85
84
|
}
|
|
86
85
|
}
|
|
87
|
-
const isItemActive = (item) =>
|
|
86
|
+
const isItemActive = (item) => item.alias === current;
|
|
88
87
|
const isSectionActive = (section) => active != null && section.name === active.name;
|
|
89
88
|
return {
|
|
90
89
|
sections,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helper.js","sourceRoot":"","sources":["../../../src/components/nav/helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"helper.js","sourceRoot":"","sources":["../../../src/components/nav/helper.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { ComponentType } from 'react';
|
|
2
|
-
import type { EntrypointTarget } from '@owlmeans/client';
|
|
3
2
|
/**
|
|
4
3
|
* One screen in the navigation — the second menu level.
|
|
5
4
|
*
|
|
@@ -7,7 +6,7 @@ import type { EntrypointTarget } from '@owlmeans/client';
|
|
|
7
6
|
* resolves it, and a path that changes shape stays correct everywhere it is rendered.
|
|
8
7
|
*/
|
|
9
8
|
export interface PanelNavItem {
|
|
10
|
-
alias:
|
|
9
|
+
alias: string;
|
|
11
10
|
/** Literal label. Absent, the label is resolved through `translate` and falls back to a humanized alias. */
|
|
12
11
|
label?: string;
|
|
13
12
|
Icon?: ComponentType<{
|
|
@@ -32,7 +31,7 @@ export interface PanelNavConfig {
|
|
|
32
31
|
}
|
|
33
32
|
/** A footer link: exactly one of `alias` (an entrypoint) or `href` (anything else). */
|
|
34
33
|
export interface PanelNavLink {
|
|
35
|
-
alias?:
|
|
34
|
+
alias?: string;
|
|
36
35
|
href?: string;
|
|
37
36
|
label?: string;
|
|
38
37
|
/** Open in a new tab. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/nav/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/nav/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAE1C;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,4GAA4G;IAC5G,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC5C,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,+EAA+E;IAC/E,KAAK,EAAE,YAAY,EAAE,CAAA;IACrB,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,eAAe,EAAE,CAAA;CAC5B;AAED,uFAAuF;AACvF,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,yBAAyB;IACzB,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAAA;CAC5C;AAED,MAAM,WAAW,aAAa;IAC5B,qDAAqD;IACrD,QAAQ,EAAE,eAAe,EAAE,CAAA;IAC3B,yEAAyE;IACzE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,MAAM,EAAE,eAAe,GAAG,IAAI,CAAA;IAC9B;;;OAGG;IACH,QAAQ,EAAE,OAAO,CAAA;IACjB,eAAe,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAA;IACtD,YAAY,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,OAAO,CAAA;IAC7C,SAAS,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,MAAM,IAAI,CAAA;IACnD,MAAM,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,MAAM,IAAI,CAAA;IAC1C;;;;;;;OAOG;IACH,MAAM,EAAE,CAAC,MAAM,EAAE,YAAY,GAAG,eAAe,KAAK,MAAM,GAAG,SAAS,CAAA;CACvE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/client-panel",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.26",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -36,19 +36,19 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@hookform/resolvers": "^5.2.2",
|
|
39
|
-
"@owlmeans/client": "^0.1.18-rc.
|
|
40
|
-
"@owlmeans/client-i18n": "^0.1.18-rc.
|
|
41
|
-
"@owlmeans/client-entrypoint": "^0.1.18-rc.
|
|
42
|
-
"@owlmeans/client-route": "^0.1.18-rc.
|
|
43
|
-
"@owlmeans/error": "^0.1.18-rc.
|
|
44
|
-
"@owlmeans/entrypoint": "^0.1.18-rc.
|
|
39
|
+
"@owlmeans/client": "^0.1.18-rc.19",
|
|
40
|
+
"@owlmeans/client-i18n": "^0.1.18-rc.18",
|
|
41
|
+
"@owlmeans/client-entrypoint": "^0.1.18-rc.16",
|
|
42
|
+
"@owlmeans/client-route": "^0.1.18-rc.16",
|
|
43
|
+
"@owlmeans/error": "^0.1.18-rc.11",
|
|
44
|
+
"@owlmeans/entrypoint": "^0.1.18-rc.14"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
|
-
"@owlmeans/auth": "^0.1.18-rc.
|
|
48
|
-
"@owlmeans/client-auth": "^0.1.18-rc.
|
|
49
|
-
"@owlmeans/config": "^0.1.18-rc.
|
|
50
|
-
"@owlmeans/i18n": "^0.1.18-rc.
|
|
51
|
-
"@owlmeans/router": "^0.1.18-rc.
|
|
47
|
+
"@owlmeans/auth": "^0.1.18-rc.12",
|
|
48
|
+
"@owlmeans/client-auth": "^0.1.18-rc.23",
|
|
49
|
+
"@owlmeans/config": "^0.1.18-rc.15",
|
|
50
|
+
"@owlmeans/i18n": "^0.1.18-rc.11",
|
|
51
|
+
"@owlmeans/router": "^0.1.18-rc.11",
|
|
52
52
|
"ajv": "*",
|
|
53
53
|
"react": "*",
|
|
54
54
|
"react-hook-form": "*"
|
|
@@ -63,8 +63,8 @@
|
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
65
65
|
"@owlmeans/dep-config": "workspace:*",
|
|
66
|
-
"@owlmeans/auth": "^0.1.18-rc.
|
|
67
|
-
"@owlmeans/client-auth": "^0.1.18-rc.
|
|
66
|
+
"@owlmeans/auth": "^0.1.18-rc.12",
|
|
67
|
+
"@owlmeans/client-auth": "^0.1.18-rc.23",
|
|
68
68
|
"@types/react": "^19.2.17",
|
|
69
69
|
"nodemon": "^3.1.14",
|
|
70
70
|
"react-hook-form": "^7.53.0",
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { useMemo } from 'react'
|
|
2
2
|
import type { ClientRoute } from '@owlmeans/client-route'
|
|
3
3
|
import type { ClientEntrypoint } from '@owlmeans/client-entrypoint'
|
|
4
|
-
import { aliasOf } from '@owlmeans/entrypoint'
|
|
5
|
-
import type { EntrypointTarget } from '@owlmeans/client'
|
|
6
4
|
import type { Location } from '@owlmeans/router'
|
|
7
5
|
import { useContext, useNavigate } from '@owlmeans/client'
|
|
8
6
|
|
|
@@ -55,11 +53,11 @@ export const usePanelNav = (config: PanelNavConfig): PanelNavModel => {
|
|
|
55
53
|
.filter(section => section.hidden !== true)
|
|
56
54
|
.map(section => ({ ...section, items: visibleItems(section) }))
|
|
57
55
|
|
|
58
|
-
const pathOf = (
|
|
56
|
+
const pathOf = (alias: string): string | null => {
|
|
59
57
|
try {
|
|
60
|
-
return normalizePath(context.entrypoint<ClientEntrypoint<string>>(
|
|
58
|
+
return normalizePath(context.entrypoint<ClientEntrypoint<string>>(alias).path())
|
|
61
59
|
} catch {
|
|
62
|
-
//
|
|
60
|
+
// A protocol the app never bound addresses nothing — it cannot be the current screen,
|
|
63
61
|
// and it must not take the menu down with it.
|
|
64
62
|
return null
|
|
65
63
|
}
|
|
@@ -72,7 +70,7 @@ export const usePanelNav = (config: PanelNavConfig): PanelNavModel => {
|
|
|
72
70
|
const here = normalizePath(pathname)
|
|
73
71
|
const exact = all.find(item => pathOf(item.alias) === here)
|
|
74
72
|
if (exact != null) {
|
|
75
|
-
current =
|
|
73
|
+
current = exact.alias
|
|
76
74
|
} else {
|
|
77
75
|
// Longest prefix: a detail screen under a listed one still belongs to its section.
|
|
78
76
|
const prefixed = all
|
|
@@ -80,12 +78,12 @@ export const usePanelNav = (config: PanelNavConfig): PanelNavModel => {
|
|
|
80
78
|
.filter((entry): entry is { item: PanelNavItem, path: string } =>
|
|
81
79
|
entry.path != null && entry.path !== '/' && here.startsWith(`${entry.path}/`))
|
|
82
80
|
.sort((a, b) => b.path.length - a.path.length)[0]
|
|
83
|
-
current = prefixed
|
|
81
|
+
current = prefixed?.item.alias ?? null
|
|
84
82
|
}
|
|
85
83
|
}
|
|
86
84
|
|
|
87
85
|
const sectionOf = (alias: string | null): PanelNavSection | null =>
|
|
88
|
-
alias == null ? null : sections.find(section => section.items.some(item =>
|
|
86
|
+
alias == null ? null : sections.find(section => section.items.some(item => item.alias === alias)) ?? null
|
|
89
87
|
|
|
90
88
|
let active = sectionOf(current)
|
|
91
89
|
if (active == null && current != null) {
|
|
@@ -108,7 +106,7 @@ export const usePanelNav = (config: PanelNavConfig): PanelNavModel => {
|
|
|
108
106
|
}
|
|
109
107
|
}
|
|
110
108
|
|
|
111
|
-
const isItemActive = (item: PanelNavItem): boolean =>
|
|
109
|
+
const isItemActive = (item: PanelNavItem): boolean => item.alias === current
|
|
112
110
|
const isSectionActive = (section: PanelNavSection): boolean =>
|
|
113
111
|
active != null && section.name === active.name
|
|
114
112
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { ComponentType } from 'react'
|
|
2
|
-
import type { EntrypointTarget } from '@owlmeans/client'
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
4
|
* One screen in the navigation — the second menu level.
|
|
@@ -8,7 +7,7 @@ import type { EntrypointTarget } from '@owlmeans/client'
|
|
|
8
7
|
* resolves it, and a path that changes shape stays correct everywhere it is rendered.
|
|
9
8
|
*/
|
|
10
9
|
export interface PanelNavItem {
|
|
11
|
-
alias:
|
|
10
|
+
alias: string
|
|
12
11
|
/** Literal label. Absent, the label is resolved through `translate` and falls back to a humanized alias. */
|
|
13
12
|
label?: string
|
|
14
13
|
Icon?: ComponentType<{ className?: string }>
|
|
@@ -34,7 +33,7 @@ export interface PanelNavConfig {
|
|
|
34
33
|
|
|
35
34
|
/** A footer link: exactly one of `alias` (an entrypoint) or `href` (anything else). */
|
|
36
35
|
export interface PanelNavLink {
|
|
37
|
-
alias?:
|
|
36
|
+
alias?: string
|
|
38
37
|
href?: string
|
|
39
38
|
label?: string
|
|
40
39
|
/** Open in a new tab. */
|