@checkstack/auth-frontend 0.5.32 → 0.6.0
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 +55 -0
- package/package.json +10 -9
- package/src/components/LoginPage.tsx +72 -2
- package/src/index.tsx +2 -0
- package/tsconfig.json +18 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,60 @@
|
|
|
1
1
|
# @checkstack/auth-frontend
|
|
2
2
|
|
|
3
|
+
## 0.6.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 950d6ec: Fix mobile UserMenu items rendering at zero height, group menu items by
|
|
8
|
+
section, and unstack cramped card headers on small viewports.
|
|
9
|
+
|
|
10
|
+
- **UserMenu mobile bug**: On mobile, the user-menu Sheet rendered every
|
|
11
|
+
menu item as a grid row, which combined with `flex-shrink: 1` on each
|
|
12
|
+
item collapsed the buttons whose internal layout uses `display: flex`
|
|
13
|
+
(the items registered with `useNavigate` rather than `<Link>`) to zero
|
|
14
|
+
content height. Switched the mobile container to a flex column with
|
|
15
|
+
`[&>*]:shrink-0` and added `min-h-0` so the sheet scrolls correctly
|
|
16
|
+
when the list overflows.
|
|
17
|
+
|
|
18
|
+
- **UserMenu grouping**: Slot extensions now accept an optional `group`
|
|
19
|
+
field. The user menu buckets `UserMenuItemsSlot` extensions by `group`
|
|
20
|
+
and renders each group under a labeled header (`Workspace`,
|
|
21
|
+
`Reliability`, `Configuration`, `Documentation`, `Account`). Existing
|
|
22
|
+
core plugins are tagged with the appropriate group; third-party plugins
|
|
23
|
+
can pick any of these or supply their own label. Untagged extensions
|
|
24
|
+
render last with no header. `UserMenuItemsBottomSlot` is unaffected.
|
|
25
|
+
|
|
26
|
+
- **Card header responsiveness**: `CardHeaderRow` (the primitive shared by
|
|
27
|
+
Incident, Maintenance, Auth, Catalog, GitOps and other config cards) now
|
|
28
|
+
stacks vertically on narrow viewports and only switches to a single row
|
|
29
|
+
at the `sm` breakpoint, so titles and adjacent filter controls (e.g.
|
|
30
|
+
status `Select`, "Show resolved" checkbox) no longer cram together on
|
|
31
|
+
mobile. Refactored the Incident and Maintenance config pages to use the
|
|
32
|
+
primitive instead of a hand-rolled `flex items-center justify-between`
|
|
33
|
+
row, and made their `Select` triggers full-width on mobile.
|
|
34
|
+
|
|
35
|
+
### Patch Changes
|
|
36
|
+
|
|
37
|
+
- Updated dependencies [42abfff]
|
|
38
|
+
- Updated dependencies [3547670]
|
|
39
|
+
- Updated dependencies [1ef2e79]
|
|
40
|
+
- Updated dependencies [aa89bc5]
|
|
41
|
+
- Updated dependencies [950d6ec]
|
|
42
|
+
- Updated dependencies [3547670]
|
|
43
|
+
- @checkstack/common@0.9.0
|
|
44
|
+
- @checkstack/ui@1.8.0
|
|
45
|
+
- @checkstack/frontend-api@0.5.0
|
|
46
|
+
- @checkstack/auth-common@0.6.6
|
|
47
|
+
|
|
48
|
+
## 0.5.33
|
|
49
|
+
|
|
50
|
+
### Patch Changes
|
|
51
|
+
|
|
52
|
+
- Updated dependencies [50e5f5f]
|
|
53
|
+
- @checkstack/auth-common@0.6.5
|
|
54
|
+
- @checkstack/common@0.8.0
|
|
55
|
+
- @checkstack/ui@1.7.1
|
|
56
|
+
- @checkstack/frontend-api@0.4.2
|
|
57
|
+
|
|
3
58
|
## 0.5.32
|
|
4
59
|
|
|
5
60
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@checkstack/auth-frontend",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"license": "Elastic-2.0",
|
|
4
5
|
"type": "module",
|
|
5
6
|
"main": "src/index.tsx",
|
|
6
7
|
"checkstack": {
|
|
@@ -11,27 +12,27 @@
|
|
|
11
12
|
"./api": "./src/api.ts"
|
|
12
13
|
},
|
|
13
14
|
"scripts": {
|
|
14
|
-
"typecheck": "
|
|
15
|
+
"typecheck": "tsgo -b",
|
|
15
16
|
"lint": "bun run lint:code",
|
|
16
17
|
"lint:code": "eslint . --max-warnings 0",
|
|
17
18
|
"test:e2e": "bunx playwright test"
|
|
18
19
|
},
|
|
19
20
|
"dependencies": {
|
|
20
|
-
"@checkstack/frontend-api": "0.4.
|
|
21
|
-
"@checkstack/common": "0.
|
|
22
|
-
"@checkstack/ui": "1.
|
|
21
|
+
"@checkstack/frontend-api": "0.4.2",
|
|
22
|
+
"@checkstack/common": "0.8.0",
|
|
23
|
+
"@checkstack/ui": "1.7.1",
|
|
23
24
|
"react": "^18.2.0",
|
|
24
25
|
"react-router-dom": "^6.22.0",
|
|
25
26
|
"lucide-react": "^0.344.0",
|
|
26
27
|
"better-auth": "^1.1.8",
|
|
27
|
-
"@checkstack/auth-common": "0.6.
|
|
28
|
+
"@checkstack/auth-common": "0.6.5"
|
|
28
29
|
},
|
|
29
30
|
"devDependencies": {
|
|
30
31
|
"typescript": "^5.0.0",
|
|
31
32
|
"@types/react": "^18.2.0",
|
|
32
33
|
"@playwright/test": "^1.49.0",
|
|
33
|
-
"@checkstack/test-utils-frontend": "0.0.
|
|
34
|
-
"@checkstack/tsconfig": "0.0.
|
|
35
|
-
"@checkstack/scripts": "0.
|
|
34
|
+
"@checkstack/test-utils-frontend": "0.0.5",
|
|
35
|
+
"@checkstack/tsconfig": "0.0.7",
|
|
36
|
+
"@checkstack/scripts": "0.3.0"
|
|
36
37
|
}
|
|
37
38
|
}
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
UserMenuItemsSlot,
|
|
10
10
|
UserMenuItemsBottomSlot,
|
|
11
11
|
UserMenuItemsContext,
|
|
12
|
+
Extension,
|
|
12
13
|
} from "@checkstack/frontend-api";
|
|
13
14
|
import { AuthApi, authRoutes } from "@checkstack/auth-common";
|
|
14
15
|
import { resolveRoute } from "@checkstack/common";
|
|
@@ -24,6 +25,7 @@ import {
|
|
|
24
25
|
CardFooter,
|
|
25
26
|
UserMenu,
|
|
26
27
|
DropdownMenuItem,
|
|
28
|
+
DropdownMenuLabel,
|
|
27
29
|
DropdownMenuSeparator,
|
|
28
30
|
Alert,
|
|
29
31
|
AlertIcon,
|
|
@@ -416,6 +418,62 @@ export const LogoutMenuItem = (_props: UserMenuItemsContext) => {
|
|
|
416
418
|
);
|
|
417
419
|
};
|
|
418
420
|
|
|
421
|
+
/**
|
|
422
|
+
* Canonical user-menu group labels and their display order. Extensions tag
|
|
423
|
+
* themselves via `group` on their slot registration; anything that doesn't
|
|
424
|
+
* match a known group falls into a trailing label-less bucket.
|
|
425
|
+
*/
|
|
426
|
+
const USER_MENU_GROUP_ORDER: readonly string[] = [
|
|
427
|
+
"Workspace",
|
|
428
|
+
"Reliability",
|
|
429
|
+
"Configuration",
|
|
430
|
+
"Documentation",
|
|
431
|
+
"Account",
|
|
432
|
+
];
|
|
433
|
+
|
|
434
|
+
type UserMenuExtension = Extension<typeof UserMenuItemsSlot>;
|
|
435
|
+
|
|
436
|
+
function groupTopExtensions(
|
|
437
|
+
extensions: UserMenuExtension[],
|
|
438
|
+
): Array<{ label: string | undefined; items: UserMenuExtension[] }> {
|
|
439
|
+
const buckets = new Map<string, UserMenuExtension[]>();
|
|
440
|
+
const ungrouped: UserMenuExtension[] = [];
|
|
441
|
+
|
|
442
|
+
for (const ext of extensions) {
|
|
443
|
+
const groupName = ext.metadata?.group;
|
|
444
|
+
if (!groupName) {
|
|
445
|
+
ungrouped.push(ext);
|
|
446
|
+
continue;
|
|
447
|
+
}
|
|
448
|
+
const list = buckets.get(groupName);
|
|
449
|
+
if (list) {
|
|
450
|
+
list.push(ext);
|
|
451
|
+
} else {
|
|
452
|
+
buckets.set(groupName, [ext]);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
const result: Array<{ label: string | undefined; items: UserMenuExtension[] }> = [];
|
|
457
|
+
// Known groups in canonical order.
|
|
458
|
+
for (const name of USER_MENU_GROUP_ORDER) {
|
|
459
|
+
const items = buckets.get(name);
|
|
460
|
+
if (items) {
|
|
461
|
+
result.push({ label: name, items });
|
|
462
|
+
buckets.delete(name);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
// Any extra groups plugins introduced — render in encounter order, alphabetised.
|
|
466
|
+
const extras = [...buckets.entries()].toSorted(([a], [b]) => a.localeCompare(b));
|
|
467
|
+
for (const [name, items] of extras) {
|
|
468
|
+
result.push({ label: name, items });
|
|
469
|
+
}
|
|
470
|
+
// Untagged extensions go last with no header.
|
|
471
|
+
if (ungrouped.length > 0) {
|
|
472
|
+
result.push({ label: undefined, items: ungrouped });
|
|
473
|
+
}
|
|
474
|
+
return result;
|
|
475
|
+
}
|
|
476
|
+
|
|
419
477
|
export const LoginNavbarAction = () => {
|
|
420
478
|
const authApi = useApi(authApiRef);
|
|
421
479
|
const { data: session, isPending } = authApi.useSession();
|
|
@@ -445,7 +503,9 @@ export const LoginNavbarAction = () => {
|
|
|
445
503
|
}
|
|
446
504
|
|
|
447
505
|
if (session?.user) {
|
|
448
|
-
|
|
506
|
+
const topExtensions = pluginRegistry.getExtensions(
|
|
507
|
+
UserMenuItemsSlot.id,
|
|
508
|
+
) as UserMenuExtension[];
|
|
449
509
|
const bottomExtensions = pluginRegistry.getExtensions(
|
|
450
510
|
UserMenuItemsBottomSlot.id,
|
|
451
511
|
);
|
|
@@ -454,10 +514,20 @@ export const LoginNavbarAction = () => {
|
|
|
454
514
|
accessRules,
|
|
455
515
|
hasCredentialAccount,
|
|
456
516
|
};
|
|
517
|
+
const groups = groupTopExtensions(topExtensions);
|
|
457
518
|
|
|
458
519
|
return (
|
|
459
520
|
<UserMenu user={session.user}>
|
|
460
|
-
|
|
521
|
+
{groups.map(({ label, items }, groupIndex) => (
|
|
522
|
+
<React.Fragment key={label ?? `__group-${groupIndex}`}>
|
|
523
|
+
{groupIndex > 0 && <DropdownMenuSeparator />}
|
|
524
|
+
{label && <DropdownMenuLabel>{label}</DropdownMenuLabel>}
|
|
525
|
+
{items.map((ext) => {
|
|
526
|
+
const Component = ext.component as React.ComponentType<UserMenuItemsContext>;
|
|
527
|
+
return <Component key={ext.id} {...menuContext} />;
|
|
528
|
+
})}
|
|
529
|
+
</React.Fragment>
|
|
530
|
+
))}
|
|
461
531
|
{hasBottomItems && <DropdownMenuSeparator />}
|
|
462
532
|
<ExtensionSlot slot={UserMenuItemsBottomSlot} context={menuContext} />
|
|
463
533
|
</UserMenu>
|
package/src/index.tsx
CHANGED
|
@@ -178,6 +178,7 @@ export const authPlugin = createFrontendPlugin({
|
|
|
178
178
|
},
|
|
179
179
|
createSlotExtension(UserMenuItemsSlot, {
|
|
180
180
|
id: "auth.user-menu.settings",
|
|
181
|
+
metadata: { group: "Configuration" },
|
|
181
182
|
component: ({ accessRules: userPerms }: UserMenuItemsContext) => {
|
|
182
183
|
// eslint-disable-next-line react-hooks/rules-of-hooks -- Inline component used via createSlotExtension
|
|
183
184
|
const navigate = useNavigate();
|
|
@@ -199,6 +200,7 @@ export const authPlugin = createFrontendPlugin({
|
|
|
199
200
|
}),
|
|
200
201
|
createSlotExtension(UserMenuItemsSlot, {
|
|
201
202
|
id: "auth.user-menu.profile",
|
|
203
|
+
metadata: { group: "Account" },
|
|
202
204
|
component: () => {
|
|
203
205
|
// eslint-disable-next-line react-hooks/rules-of-hooks -- Inline component used via createSlotExtension
|
|
204
206
|
const navigate = useNavigate();
|
package/tsconfig.json
CHANGED
|
@@ -2,5 +2,22 @@
|
|
|
2
2
|
"extends": "@checkstack/tsconfig/frontend.json",
|
|
3
3
|
"include": [
|
|
4
4
|
"src"
|
|
5
|
+
],
|
|
6
|
+
"references": [
|
|
7
|
+
{
|
|
8
|
+
"path": "../auth-common"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"path": "../common"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"path": "../frontend-api"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"path": "../test-utils-frontend"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"path": "../ui"
|
|
21
|
+
}
|
|
5
22
|
]
|
|
6
|
-
}
|
|
23
|
+
}
|