@redhat-cloud-services/hcc-storybook-hub 0.1.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/README.md ADDED
@@ -0,0 +1,60 @@
1
+ # hcc-storybooks
2
+
3
+ Composed meta Storybook that aggregates stories from multiple HCC frontend applications into a single browsable interface. By default, it points to each application's latest master build on Chromatic.
4
+
5
+ ## Composed applications
6
+
7
+ | Application | Repository | Env Var Override |
8
+ |---|---|---|
9
+ | Access Requests | `access-requests-frontend` | `SB_ACCESS_REQUESTS_URL` |
10
+ | RBAC | `insights-rbac-ui` | `SB_RBAC_URL` |
11
+ | Notifications | `notifications-frontend` | `SB_NOTIFICATIONS_URL` |
12
+ | Service Accounts | `service-accounts` | `SB_SERVICE_ACCOUNTS_URL` |
13
+ | Sources | `sources-ui` | `SB_SOURCES_URL` |
14
+ | User Preferences | `user-preferences-frontend` | `SB_USER_PREFERENCES_URL` |
15
+
16
+ ## Quick start
17
+
18
+ ```bash
19
+ npm install
20
+ npm run storybook
21
+ ```
22
+
23
+ The meta Storybook starts on port 6006 and loads all external Storybooks from Chromatic automatically.
24
+
25
+ ## Custom URLs
26
+
27
+ Point any ref to a local or alternative Storybook by setting its env var:
28
+
29
+ ```bash
30
+ SB_NOTIFICATIONS_URL=http://localhost:6012 npm run storybook
31
+ ```
32
+
33
+ ## Running Storybooks locally
34
+
35
+ If you want to serve Storybooks from local clones instead of Chromatic, clone the repos as sibling directories and run:
36
+
37
+ ```bash
38
+ npm run serve-all
39
+ ```
40
+
41
+ This expects the following directory layout:
42
+
43
+ ```
44
+ hcc/
45
+ ├── hcc-storybooks/ # this project
46
+ ├── access-requests-frontend/
47
+ ├── insights-rbac-ui/
48
+ ├── notifications-frontend/
49
+ ├── service-accounts/
50
+ ├── sources-ui/
51
+ └── user-preferences-frontend/
52
+ ```
53
+
54
+ The script builds each repo's Storybook, serves it on a local port, and starts this meta Storybook on port 6006.
55
+
56
+ ## What this is (and isn't)
57
+
58
+ This is a **discovery and browsing hub**. It gives you one place to view all HCC component stories without tracking down individual Storybook deployments.
59
+
60
+ It is **not a test runner**. Automated tests (interaction tests, a11y checks) must be run against each individual Storybook — composition only provides a unified sidebar, not centralized test execution.
@@ -0,0 +1,12 @@
1
+ import React, { ReactNode } from 'react';
2
+
3
+ interface FeatureFlagsConfig {
4
+ [flagName: string]: boolean;
5
+ }
6
+ declare const FeatureFlagsContext: React.Context<FeatureFlagsConfig>;
7
+ declare const FeatureFlagsProvider: React.FC<{
8
+ value: FeatureFlagsConfig;
9
+ children: ReactNode;
10
+ }>;
11
+
12
+ export { type FeatureFlagsConfig as F, FeatureFlagsContext as a, FeatureFlagsProvider as b };
@@ -0,0 +1,12 @@
1
+ import React, { ReactNode } from 'react';
2
+
3
+ interface FeatureFlagsConfig {
4
+ [flagName: string]: boolean;
5
+ }
6
+ declare const FeatureFlagsContext: React.Context<FeatureFlagsConfig>;
7
+ declare const FeatureFlagsProvider: React.FC<{
8
+ value: FeatureFlagsConfig;
9
+ children: ReactNode;
10
+ }>;
11
+
12
+ export { type FeatureFlagsConfig as F, FeatureFlagsContext as a, FeatureFlagsProvider as b };
@@ -0,0 +1,101 @@
1
+ import {
2
+ useMockState
3
+ } from "./chunk-UCQY2VRL.mjs";
4
+
5
+ // lib/mocks/useChrome.tsx
6
+ import { useRef } from "react";
7
+ import { fn } from "storybook/test";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ var chromeAppNavClickSpy = fn();
10
+ var defaultTutorials = [
11
+ { id: "getting-started", title: "Getting Started", description: "Learn the basics.", time: "10 min", level: "Beginner" },
12
+ { id: "custom-roles", title: "Creating Custom Roles", description: "Configure custom roles.", time: "15 min", level: "Intermediate" },
13
+ { id: "user-groups", title: "Managing User Groups", description: "Organize users into groups.", time: "12 min", level: "Beginner" },
14
+ { id: "workspaces", title: "Workspace Administration", description: "Master workspace management.", time: "20 min", level: "Advanced" }
15
+ ];
16
+ var DefaultCatalog = () => /* @__PURE__ */ jsxs("div", { style: { padding: "24px" }, children: [
17
+ /* @__PURE__ */ jsx("h2", { style: { margin: "0 0 8px 0", fontSize: "28px", fontWeight: 300 }, children: "Quick starts" }),
18
+ /* @__PURE__ */ jsx("p", { style: { color: "#6a6e73", margin: "0 0 24px", fontSize: "14px" }, children: "Step-by-step instructions and guided tours." }),
19
+ /* @__PURE__ */ jsx("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(300px, 1fr))", gap: "16px" }, children: defaultTutorials.map((t) => /* @__PURE__ */ jsxs("div", { style: { border: "1px solid #d2d2d2", borderRadius: "8px", padding: "16px" }, children: [
20
+ /* @__PURE__ */ jsx("h3", { style: { margin: "0 0 8px", fontSize: "16px", fontWeight: 600 }, children: t.title }),
21
+ /* @__PURE__ */ jsx("p", { style: { margin: "0", fontSize: "14px", color: "#6a6e73" }, children: t.description })
22
+ ] }, t.id)) })
23
+ ] });
24
+ var _config = {};
25
+ function configureChromeMock(config) {
26
+ _config = config;
27
+ }
28
+ function useChrome() {
29
+ const mock = useMockState();
30
+ const mockRef = useRef(mock);
31
+ mockRef.current = mock;
32
+ const chromeRef = useRef(null);
33
+ if (!chromeRef.current) {
34
+ chromeRef.current = {
35
+ getEnvironment: () => mockRef.current.environment === "production" ? "prod" : "stage",
36
+ getEnvironmentDetails: () => ({
37
+ environment: mockRef.current.environment === "production" ? "prod" : "stage",
38
+ sso: mockRef.current.environment === "production" ? "https://sso.redhat.com" : "https://sso.stage.redhat.com",
39
+ portal: "https://console.redhat.com"
40
+ }),
41
+ get isProd() {
42
+ return mockRef.current.environment === "production";
43
+ },
44
+ isBeta: () => false,
45
+ getBundle: () => _config.bundle || "insights",
46
+ getApp: () => _config.app || "unknown",
47
+ auth: {
48
+ getToken: () => Promise.resolve("mock-token-12345"),
49
+ getUser: () => {
50
+ const id = mockRef.current.userIdentity;
51
+ return Promise.resolve({
52
+ identity: {
53
+ account_number: id?.account_number,
54
+ org_id: id?.org_id ?? "mock-org-id",
55
+ organization: id?.organization,
56
+ internal: id?.internal,
57
+ user: {
58
+ is_org_admin: id?.user?.is_org_admin ?? mockRef.current.isOrgAdmin,
59
+ username: id?.user?.username ?? "test-user",
60
+ email: id?.user?.email ?? "test@redhat.com",
61
+ is_internal: id?.user?.is_internal ?? false,
62
+ first_name: id?.user?.first_name,
63
+ last_name: id?.user?.last_name,
64
+ is_active: id?.user?.is_active ?? true,
65
+ locale: id?.user?.locale ?? "en_US"
66
+ }
67
+ },
68
+ entitlements: id?.entitlements ?? {}
69
+ });
70
+ }
71
+ },
72
+ getUserPermissions: (app) => Promise.resolve(
73
+ mockRef.current.permissions.filter((p) => p.startsWith(`${app}:`) || p.startsWith("*:")).map((permission) => ({ permission, resourceDefinitions: [] }))
74
+ ),
75
+ appNavClick: chromeAppNavClickSpy,
76
+ appObjectId: () => {
77
+ },
78
+ appAction: () => {
79
+ },
80
+ updateDocumentTitle: (title) => {
81
+ if (typeof document !== "undefined") {
82
+ document.title = title;
83
+ }
84
+ },
85
+ quickStarts: {
86
+ Catalog: _config.quickStartsCatalog || DefaultCatalog,
87
+ set: () => {
88
+ },
89
+ toggle: () => {
90
+ }
91
+ }
92
+ };
93
+ }
94
+ return chromeRef.current;
95
+ }
96
+
97
+ export {
98
+ chromeAppNavClickSpy,
99
+ configureChromeMock,
100
+ useChrome
101
+ };
@@ -0,0 +1,58 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});// lib/contexts/StorybookMockContext.tsx
2
+ var _react = require('react');
3
+ var _jsxruntime = require('react/jsx-runtime');
4
+ var EMPTY_WORKSPACE_PERMISSIONS = {
5
+ view: [],
6
+ edit: [],
7
+ delete: [],
8
+ create: [],
9
+ move: []
10
+ };
11
+ var EMPTY_TENANT_PERMISSIONS = {
12
+ rbac_roles_read: false,
13
+ rbac_roles_write: false,
14
+ rbac_groups_read: false,
15
+ rbac_groups_write: false,
16
+ rbac_principal_read: false,
17
+ rbac_workspace_view: false,
18
+ rbac_workspace_edit: false,
19
+ rbac_workspace_create: false,
20
+ rbac_workspace_delete: false,
21
+ rbac_workspace_move: false
22
+ };
23
+ var defaultState = {
24
+ environment: "staging",
25
+ isOrgAdmin: false,
26
+ permissions: [],
27
+ workspacePermissions: EMPTY_WORKSPACE_PERMISSIONS,
28
+ tenantPermissions: EMPTY_TENANT_PERMISSIONS
29
+ };
30
+ var StorybookMockContext = _react.createContext.call(void 0, defaultState);
31
+ var StorybookMockProvider = ({
32
+ children,
33
+ environment = "staging",
34
+ isOrgAdmin = false,
35
+ permissions = [],
36
+ workspacePermissions = EMPTY_WORKSPACE_PERMISSIONS,
37
+ tenantPermissions = EMPTY_TENANT_PERMISSIONS,
38
+ userIdentity
39
+ }) => {
40
+ const value = {
41
+ environment,
42
+ isOrgAdmin,
43
+ permissions,
44
+ workspacePermissions: { ...EMPTY_WORKSPACE_PERMISSIONS, ...workspacePermissions },
45
+ tenantPermissions: { ...EMPTY_TENANT_PERMISSIONS, ...tenantPermissions },
46
+ userIdentity
47
+ };
48
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StorybookMockContext.Provider, { value, children });
49
+ };
50
+ var useMockState = () => _react.useContext.call(void 0, StorybookMockContext);
51
+
52
+
53
+
54
+
55
+
56
+
57
+
58
+ exports.EMPTY_WORKSPACE_PERMISSIONS = EMPTY_WORKSPACE_PERMISSIONS; exports.EMPTY_TENANT_PERMISSIONS = EMPTY_TENANT_PERMISSIONS; exports.StorybookMockContext = StorybookMockContext; exports.StorybookMockProvider = StorybookMockProvider; exports.useMockState = useMockState;
@@ -0,0 +1,13 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});// lib/providers/FeatureFlagsProvider.tsx
2
+ var _react = require('react');
3
+ var _jsxruntime = require('react/jsx-runtime');
4
+ var FeatureFlagsContext = _react.createContext.call(void 0, {});
5
+ var FeatureFlagsProvider = ({
6
+ value,
7
+ children
8
+ }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FeatureFlagsContext.Provider, { value, children });
9
+
10
+
11
+
12
+
13
+ exports.FeatureFlagsContext = FeatureFlagsContext; exports.FeatureFlagsProvider = FeatureFlagsProvider;
@@ -0,0 +1,58 @@
1
+ // lib/contexts/StorybookMockContext.tsx
2
+ import { createContext, useContext } from "react";
3
+ import { jsx } from "react/jsx-runtime";
4
+ var EMPTY_WORKSPACE_PERMISSIONS = {
5
+ view: [],
6
+ edit: [],
7
+ delete: [],
8
+ create: [],
9
+ move: []
10
+ };
11
+ var EMPTY_TENANT_PERMISSIONS = {
12
+ rbac_roles_read: false,
13
+ rbac_roles_write: false,
14
+ rbac_groups_read: false,
15
+ rbac_groups_write: false,
16
+ rbac_principal_read: false,
17
+ rbac_workspace_view: false,
18
+ rbac_workspace_edit: false,
19
+ rbac_workspace_create: false,
20
+ rbac_workspace_delete: false,
21
+ rbac_workspace_move: false
22
+ };
23
+ var defaultState = {
24
+ environment: "staging",
25
+ isOrgAdmin: false,
26
+ permissions: [],
27
+ workspacePermissions: EMPTY_WORKSPACE_PERMISSIONS,
28
+ tenantPermissions: EMPTY_TENANT_PERMISSIONS
29
+ };
30
+ var StorybookMockContext = createContext(defaultState);
31
+ var StorybookMockProvider = ({
32
+ children,
33
+ environment = "staging",
34
+ isOrgAdmin = false,
35
+ permissions = [],
36
+ workspacePermissions = EMPTY_WORKSPACE_PERMISSIONS,
37
+ tenantPermissions = EMPTY_TENANT_PERMISSIONS,
38
+ userIdentity
39
+ }) => {
40
+ const value = {
41
+ environment,
42
+ isOrgAdmin,
43
+ permissions,
44
+ workspacePermissions: { ...EMPTY_WORKSPACE_PERMISSIONS, ...workspacePermissions },
45
+ tenantPermissions: { ...EMPTY_TENANT_PERMISSIONS, ...tenantPermissions },
46
+ userIdentity
47
+ };
48
+ return /* @__PURE__ */ jsx(StorybookMockContext.Provider, { value, children });
49
+ };
50
+ var useMockState = () => useContext(StorybookMockContext);
51
+
52
+ export {
53
+ EMPTY_WORKSPACE_PERMISSIONS,
54
+ EMPTY_TENANT_PERMISSIONS,
55
+ StorybookMockContext,
56
+ StorybookMockProvider,
57
+ useMockState
58
+ };
@@ -0,0 +1,13 @@
1
+ // lib/providers/FeatureFlagsProvider.tsx
2
+ import { createContext } from "react";
3
+ import { jsx } from "react/jsx-runtime";
4
+ var FeatureFlagsContext = createContext({});
5
+ var FeatureFlagsProvider = ({
6
+ value,
7
+ children
8
+ }) => /* @__PURE__ */ jsx(FeatureFlagsContext.Provider, { value, children });
9
+
10
+ export {
11
+ FeatureFlagsContext,
12
+ FeatureFlagsProvider
13
+ };
@@ -0,0 +1,101 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
+
3
+ var _chunkKVKMLDB5js = require('./chunk-KVKMLDB5.js');
4
+
5
+ // lib/mocks/useChrome.tsx
6
+ var _react = require('react');
7
+ var _test = require('storybook/test');
8
+ var _jsxruntime = require('react/jsx-runtime');
9
+ var chromeAppNavClickSpy = _test.fn.call(void 0, );
10
+ var defaultTutorials = [
11
+ { id: "getting-started", title: "Getting Started", description: "Learn the basics.", time: "10 min", level: "Beginner" },
12
+ { id: "custom-roles", title: "Creating Custom Roles", description: "Configure custom roles.", time: "15 min", level: "Intermediate" },
13
+ { id: "user-groups", title: "Managing User Groups", description: "Organize users into groups.", time: "12 min", level: "Beginner" },
14
+ { id: "workspaces", title: "Workspace Administration", description: "Master workspace management.", time: "20 min", level: "Advanced" }
15
+ ];
16
+ var DefaultCatalog = () => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { padding: "24px" }, children: [
17
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { style: { margin: "0 0 8px 0", fontSize: "28px", fontWeight: 300 }, children: "Quick starts" }),
18
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { style: { color: "#6a6e73", margin: "0 0 24px", fontSize: "14px" }, children: "Step-by-step instructions and guided tours." }),
19
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(300px, 1fr))", gap: "16px" }, children: defaultTutorials.map((t) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { border: "1px solid #d2d2d2", borderRadius: "8px", padding: "16px" }, children: [
20
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { style: { margin: "0 0 8px", fontSize: "16px", fontWeight: 600 }, children: t.title }),
21
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { style: { margin: "0", fontSize: "14px", color: "#6a6e73" }, children: t.description })
22
+ ] }, t.id)) })
23
+ ] });
24
+ var _config = {};
25
+ function configureChromeMock(config) {
26
+ _config = config;
27
+ }
28
+ function useChrome() {
29
+ const mock = _chunkKVKMLDB5js.useMockState.call(void 0, );
30
+ const mockRef = _react.useRef.call(void 0, mock);
31
+ mockRef.current = mock;
32
+ const chromeRef = _react.useRef.call(void 0, null);
33
+ if (!chromeRef.current) {
34
+ chromeRef.current = {
35
+ getEnvironment: () => mockRef.current.environment === "production" ? "prod" : "stage",
36
+ getEnvironmentDetails: () => ({
37
+ environment: mockRef.current.environment === "production" ? "prod" : "stage",
38
+ sso: mockRef.current.environment === "production" ? "https://sso.redhat.com" : "https://sso.stage.redhat.com",
39
+ portal: "https://console.redhat.com"
40
+ }),
41
+ get isProd() {
42
+ return mockRef.current.environment === "production";
43
+ },
44
+ isBeta: () => false,
45
+ getBundle: () => _config.bundle || "insights",
46
+ getApp: () => _config.app || "unknown",
47
+ auth: {
48
+ getToken: () => Promise.resolve("mock-token-12345"),
49
+ getUser: () => {
50
+ const id = mockRef.current.userIdentity;
51
+ return Promise.resolve({
52
+ identity: {
53
+ account_number: _optionalChain([id, 'optionalAccess', _ => _.account_number]),
54
+ org_id: _nullishCoalesce(_optionalChain([id, 'optionalAccess', _2 => _2.org_id]), () => ( "mock-org-id")),
55
+ organization: _optionalChain([id, 'optionalAccess', _3 => _3.organization]),
56
+ internal: _optionalChain([id, 'optionalAccess', _4 => _4.internal]),
57
+ user: {
58
+ is_org_admin: _nullishCoalesce(_optionalChain([id, 'optionalAccess', _5 => _5.user, 'optionalAccess', _6 => _6.is_org_admin]), () => ( mockRef.current.isOrgAdmin)),
59
+ username: _nullishCoalesce(_optionalChain([id, 'optionalAccess', _7 => _7.user, 'optionalAccess', _8 => _8.username]), () => ( "test-user")),
60
+ email: _nullishCoalesce(_optionalChain([id, 'optionalAccess', _9 => _9.user, 'optionalAccess', _10 => _10.email]), () => ( "test@redhat.com")),
61
+ is_internal: _nullishCoalesce(_optionalChain([id, 'optionalAccess', _11 => _11.user, 'optionalAccess', _12 => _12.is_internal]), () => ( false)),
62
+ first_name: _optionalChain([id, 'optionalAccess', _13 => _13.user, 'optionalAccess', _14 => _14.first_name]),
63
+ last_name: _optionalChain([id, 'optionalAccess', _15 => _15.user, 'optionalAccess', _16 => _16.last_name]),
64
+ is_active: _nullishCoalesce(_optionalChain([id, 'optionalAccess', _17 => _17.user, 'optionalAccess', _18 => _18.is_active]), () => ( true)),
65
+ locale: _nullishCoalesce(_optionalChain([id, 'optionalAccess', _19 => _19.user, 'optionalAccess', _20 => _20.locale]), () => ( "en_US"))
66
+ }
67
+ },
68
+ entitlements: _nullishCoalesce(_optionalChain([id, 'optionalAccess', _21 => _21.entitlements]), () => ( {}))
69
+ });
70
+ }
71
+ },
72
+ getUserPermissions: (app) => Promise.resolve(
73
+ mockRef.current.permissions.filter((p) => p.startsWith(`${app}:`) || p.startsWith("*:")).map((permission) => ({ permission, resourceDefinitions: [] }))
74
+ ),
75
+ appNavClick: chromeAppNavClickSpy,
76
+ appObjectId: () => {
77
+ },
78
+ appAction: () => {
79
+ },
80
+ updateDocumentTitle: (title) => {
81
+ if (typeof document !== "undefined") {
82
+ document.title = title;
83
+ }
84
+ },
85
+ quickStarts: {
86
+ Catalog: _config.quickStartsCatalog || DefaultCatalog,
87
+ set: () => {
88
+ },
89
+ toggle: () => {
90
+ }
91
+ }
92
+ };
93
+ }
94
+ return chromeRef.current;
95
+ }
96
+
97
+
98
+
99
+
100
+
101
+ exports.chromeAppNavClickSpy = chromeAppNavClickSpy; exports.configureChromeMock = configureChromeMock; exports.useChrome = useChrome;
@@ -0,0 +1,149 @@
1
+ export { chromeAppNavClickSpy, configureChromeMock } from './mocks/useChrome.mjs';
2
+ import React, { ReactNode } from 'react';
3
+ export { F as FeatureFlagsConfig, a as FeatureFlagsContext, b as FeatureFlagsProvider } from './FeatureFlagsProvider-C_Xxe83Z.mjs';
4
+ import '@vitest/spy';
5
+
6
+ type Environment = 'production' | 'staging';
7
+ interface MockUserIdentity {
8
+ account_number?: string;
9
+ org_id?: string;
10
+ user?: {
11
+ is_org_admin?: boolean;
12
+ username?: string;
13
+ email?: string;
14
+ is_internal?: boolean;
15
+ first_name?: string;
16
+ last_name?: string;
17
+ is_active?: boolean;
18
+ locale?: string;
19
+ };
20
+ organization?: {
21
+ name?: string;
22
+ };
23
+ internal?: {
24
+ account_id?: string;
25
+ cross_access?: boolean;
26
+ };
27
+ entitlements?: Record<string, {
28
+ is_entitled?: boolean;
29
+ is_trial?: boolean;
30
+ }>;
31
+ }
32
+ interface WorkspacePermissionsMap {
33
+ view: string[];
34
+ edit: string[];
35
+ delete: string[];
36
+ create: string[];
37
+ move: string[];
38
+ }
39
+ declare const EMPTY_WORKSPACE_PERMISSIONS: WorkspacePermissionsMap;
40
+ interface TenantPermissionsMap {
41
+ rbac_roles_read: boolean;
42
+ rbac_roles_write: boolean;
43
+ rbac_groups_read: boolean;
44
+ rbac_groups_write: boolean;
45
+ rbac_principal_read: boolean;
46
+ rbac_workspace_view: boolean;
47
+ rbac_workspace_edit: boolean;
48
+ rbac_workspace_create: boolean;
49
+ rbac_workspace_delete: boolean;
50
+ rbac_workspace_move: boolean;
51
+ }
52
+ declare const EMPTY_TENANT_PERMISSIONS: TenantPermissionsMap;
53
+ interface MockState {
54
+ environment: Environment;
55
+ isOrgAdmin: boolean;
56
+ permissions: string[];
57
+ workspacePermissions: WorkspacePermissionsMap;
58
+ tenantPermissions: TenantPermissionsMap;
59
+ userIdentity?: MockUserIdentity;
60
+ }
61
+ interface StoryParameters {
62
+ noWrapping?: boolean;
63
+ permissions?: readonly string[];
64
+ orgAdmin?: boolean;
65
+ environment?: 'staging' | 'production';
66
+ workspacePermissions?: Partial<WorkspacePermissionsMap>;
67
+ tenantPermissions?: Partial<TenantPermissionsMap>;
68
+ userIdentity?: MockUserIdentity;
69
+ featureFlags?: Record<string, boolean>;
70
+ msw?: {
71
+ handlers: unknown[];
72
+ };
73
+ }
74
+ declare const StorybookMockContext: React.Context<MockState>;
75
+ interface ProviderProps extends Partial<MockState> {
76
+ children: ReactNode;
77
+ }
78
+ declare const StorybookMockProvider: React.FC<ProviderProps>;
79
+ declare const useMockState: () => MockState;
80
+
81
+ interface ChromeConfig {
82
+ environment: string;
83
+ [key: string]: any;
84
+ }
85
+ declare const ChromeContext: React.Context<ChromeConfig>;
86
+ declare const ChromeProvider: React.FC<{
87
+ value: ChromeConfig;
88
+ children: ReactNode;
89
+ }>;
90
+
91
+ /**
92
+ * Derives Kessel tenant permissions from Chrome-style permission strings.
93
+ *
94
+ * V2 domain hooks (useRolesAccess, useGroupsAccess, etc.) consume tenantPermissions
95
+ * from the Kessel mock. Stories typically set Chrome-style `permissions` (e.g.
96
+ * ['rbac:group:read', 'rbac:role:write']). This helper converts those to the
97
+ * tenant relation format expected by useSelfAccessCheck.
98
+ */
99
+
100
+ /**
101
+ * Converts Chrome-style permissions to Kessel tenant permissions.
102
+ * When a story sets `permissions` but not `tenantPermissions`, this is used
103
+ * to auto-derive tenant relations so V2 domain hooks work correctly.
104
+ */
105
+ declare function deriveTenantPermissions(permissions: string[]): Partial<TenantPermissionsMap>;
106
+
107
+ interface PermissionsArgs {
108
+ orgAdmin?: boolean;
109
+ userAccessAdministrator?: boolean;
110
+ }
111
+ interface ChromeArgs {
112
+ environment?: 'prod' | 'stage' | 'ci-beta' | 'ci-stable' | 'qa-beta' | 'qa-stable';
113
+ }
114
+ interface FeatureFlagsArgs {
115
+ [key: string]: boolean | undefined;
116
+ }
117
+ type DecoratorArgs = PermissionsArgs & ChromeArgs & FeatureFlagsArgs;
118
+ type StoryArgs<T = {}> = T & DecoratorArgs;
119
+ declare const DEFAULT_DECORATOR_ARGS: {
120
+ orgAdmin: boolean;
121
+ userAccessAdministrator: boolean;
122
+ environment: string;
123
+ };
124
+ declare const DECORATOR_ARG_TYPES: {
125
+ readonly orgAdmin: {
126
+ readonly control: "boolean";
127
+ readonly description: "Organization admin permissions";
128
+ readonly table: {
129
+ readonly category: "Permissions";
130
+ };
131
+ };
132
+ readonly userAccessAdministrator: {
133
+ readonly control: "boolean";
134
+ readonly description: "User access administrator permissions";
135
+ readonly table: {
136
+ readonly category: "Permissions";
137
+ };
138
+ };
139
+ readonly environment: {
140
+ readonly control: "select";
141
+ readonly options: readonly ["prod", "stage", "ci-beta", "ci-stable", "qa-beta", "qa-stable"];
142
+ readonly description: "Environment for Chrome API";
143
+ readonly table: {
144
+ readonly category: "Chrome";
145
+ };
146
+ };
147
+ };
148
+
149
+ export { type ChromeConfig, ChromeContext, ChromeProvider, DECORATOR_ARG_TYPES, DEFAULT_DECORATOR_ARGS, type DecoratorArgs, EMPTY_TENANT_PERMISSIONS, EMPTY_WORKSPACE_PERMISSIONS, type Environment, type MockState, type MockUserIdentity, type StoryArgs, type StoryParameters, StorybookMockContext, StorybookMockProvider, type TenantPermissionsMap, type WorkspacePermissionsMap, deriveTenantPermissions, useMockState };