@pablo2410/shared-ui 0.3.2
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 +93 -0
- package/dist/chunk-JT3XLKKD.js +11 -0
- package/dist/chunk-JT3XLKKD.js.map +1 -0
- package/dist/components/index.d.ts +152 -0
- package/dist/components/index.js +575 -0
- package/dist/components/index.js.map +1 -0
- package/dist/hierarchy/index.d.ts +179 -0
- package/dist/hierarchy/index.js +475 -0
- package/dist/hierarchy/index.js.map +1 -0
- package/dist/hooks/index.d.ts +32 -0
- package/dist/hooks/index.js +41 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/layout/index.d.ts +336 -0
- package/dist/layout/index.js +788 -0
- package/dist/layout/index.js.map +1 -0
- package/dist/primitives/index.d.ts +570 -0
- package/dist/primitives/index.js +5648 -0
- package/dist/primitives/index.js.map +1 -0
- package/dist/rbac/index.d.ts +64 -0
- package/dist/rbac/index.js +87 -0
- package/dist/rbac/index.js.map +1 -0
- package/dist/reporting/index.d.ts +116 -0
- package/dist/reporting/index.js +258 -0
- package/dist/reporting/index.js.map +1 -0
- package/dist/theme/index.d.ts +94 -0
- package/dist/theme/index.js +82 -0
- package/dist/theme/index.js.map +1 -0
- package/package.json +119 -0
package/README.md
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# @oplytics/shared-ui
|
|
2
|
+
|
|
3
|
+
Shared UI component library for all **Oplytics.digital** subdomains. Provides standardised layouts, hierarchy management, RBAC, reporting, hooks, and design tokens as reusable building blocks.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @oplytics/shared-ui
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
> Requires `.npmrc` with `@oplytics:registry=https://npm.pkg.github.com`
|
|
12
|
+
|
|
13
|
+
## Modules
|
|
14
|
+
|
|
15
|
+
| Module | Import | Description |
|
|
16
|
+
|--------|--------|-------------|
|
|
17
|
+
| **Layout** | `@oplytics/shared-ui/layout` | Config-driven sidebar, page header, footer, layout factory |
|
|
18
|
+
| **Hierarchy** | `@oplytics/shared-ui/hierarchy` | Org hierarchy types, selection state, enterprise override |
|
|
19
|
+
| **RBAC** | `@oplytics/shared-ui/rbac` | 7-role model, permission checks, error constants |
|
|
20
|
+
| **Reporting** | `@oplytics/shared-ui/reporting` | Incident reporting and feedback toolbar types/config |
|
|
21
|
+
| **Components** | `@oplytics/shared-ui/components` | SharedFooter, NotFound, ErrorBoundary, ViewOnlyBadge types |
|
|
22
|
+
| **Hooks** | `@oplytics/shared-ui/hooks` | useMobile, useComposition, usePersistFn |
|
|
23
|
+
| **Theme** | `@oplytics/shared-ui/theme` | Design tokens, color palette, typography, CSS variables |
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
// RBAC — check permissions
|
|
29
|
+
import { hasMinimumRole, ALL_ROLES } from '@oplytics/shared-ui/rbac';
|
|
30
|
+
|
|
31
|
+
if (hasMinimumRole(user.role, 'enterprise_admin')) {
|
|
32
|
+
// show admin features
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Hierarchy — enterprise override
|
|
36
|
+
import { applyEnterpriseOverride } from '@oplytics/shared-ui/hierarchy';
|
|
37
|
+
|
|
38
|
+
const resolvedUser = applyEnterpriseOverride(user, req.headers.cookie);
|
|
39
|
+
|
|
40
|
+
// Layout — service config
|
|
41
|
+
import { SERVICE_CONFIGS, defineServiceLayout } from '@oplytics/shared-ui/layout';
|
|
42
|
+
|
|
43
|
+
const myConfig = SERVICE_CONFIGS.sqdcp;
|
|
44
|
+
|
|
45
|
+
// Theme — design tokens
|
|
46
|
+
import { OPLYTICS_COLORS, OPLYTICS_FONTS } from '@oplytics/shared-ui/theme';
|
|
47
|
+
|
|
48
|
+
// Hooks
|
|
49
|
+
import { useMobile, usePersistFn } from '@oplytics/shared-ui/hooks';
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Theme CSS
|
|
53
|
+
|
|
54
|
+
Import the canonical Oplytics theme variables:
|
|
55
|
+
|
|
56
|
+
```css
|
|
57
|
+
@import '@oplytics/shared-ui/theme/oplytics-theme.css';
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
This provides all `--oplytics-*` CSS custom properties for backgrounds, text, accents, borders, spacing, radius, and shadows.
|
|
61
|
+
|
|
62
|
+
## Development
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pnpm install
|
|
66
|
+
pnpm build # Build with tsup
|
|
67
|
+
pnpm test # Run vitest
|
|
68
|
+
pnpm typecheck # TypeScript check
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Architecture
|
|
72
|
+
|
|
73
|
+
The package is tree-shakeable with separate entry points per module. Each subdomain only imports what it needs:
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
src/
|
|
77
|
+
layout/ # SharedSidebar, createServiceLayout, serviceConfigs
|
|
78
|
+
hierarchy/ # orgHierarchy types, enterpriseOverride
|
|
79
|
+
rbac/ # Roles, permissions, error constants
|
|
80
|
+
reporting/ # ReportingToolbar types and config
|
|
81
|
+
components/ # SharedFooter, NotFound, ErrorBoundary types
|
|
82
|
+
hooks/ # useMobile, useComposition, usePersistFn
|
|
83
|
+
theme/ # Design tokens, CSS variables
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Versioning
|
|
87
|
+
|
|
88
|
+
- **v0.x** — Types, configs, and pure utilities (no React component rendering)
|
|
89
|
+
- **v1.0** — Full React components with shadcn/ui primitives bundled
|
|
90
|
+
|
|
91
|
+
## License
|
|
92
|
+
|
|
93
|
+
UNLICENSED — Internal Oplytics.digital use only.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/cn.ts"],"sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n"],"mappings":";AAAA,SAAS,YAA6B;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;","names":[]}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { Component, ReactNode, ErrorInfo } from 'react';
|
|
4
|
+
|
|
5
|
+
interface ErrorBoundaryProps {
|
|
6
|
+
/** Fallback UI to show when an error is caught. If not provided, uses the default Oplytics error UI. */
|
|
7
|
+
fallback?: ReactNode;
|
|
8
|
+
/** Error handler callback — use for logging/reporting */
|
|
9
|
+
onError?: (error: Error, errorInfo: ErrorInfo) => void;
|
|
10
|
+
/** Children to wrap */
|
|
11
|
+
children: ReactNode;
|
|
12
|
+
/** CSS class for the fallback container */
|
|
13
|
+
className?: string;
|
|
14
|
+
}
|
|
15
|
+
interface ErrorBoundaryState {
|
|
16
|
+
hasError: boolean;
|
|
17
|
+
error: Error | null;
|
|
18
|
+
}
|
|
19
|
+
declare class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
|
20
|
+
constructor(props: ErrorBoundaryProps);
|
|
21
|
+
static getDerivedStateFromError(error: Error): ErrorBoundaryState;
|
|
22
|
+
componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
|
|
23
|
+
handleRetry: () => void;
|
|
24
|
+
render(): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | react_jsx_runtime.JSX.Element | null | undefined;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface NotFoundPageProps {
|
|
28
|
+
/** Title text (default: "Page Not Found") */
|
|
29
|
+
title?: string;
|
|
30
|
+
/** Description text */
|
|
31
|
+
description?: string;
|
|
32
|
+
/** Home path to navigate to (default: "/") */
|
|
33
|
+
homePath?: string;
|
|
34
|
+
/** Back button handler (default: window.history.back) */
|
|
35
|
+
onBack?: () => void;
|
|
36
|
+
/** Home button handler — if provided, overrides the <a> link */
|
|
37
|
+
onHome?: () => void;
|
|
38
|
+
/** CSS class for the container */
|
|
39
|
+
className?: string;
|
|
40
|
+
}
|
|
41
|
+
declare function NotFoundPage({ title, description, homePath, onBack, onHome, className, }: NotFoundPageProps): react_jsx_runtime.JSX.Element;
|
|
42
|
+
|
|
43
|
+
interface ManusDialogProps {
|
|
44
|
+
/** Whether the dialog is open */
|
|
45
|
+
open: boolean;
|
|
46
|
+
/** Close handler */
|
|
47
|
+
onClose: () => void;
|
|
48
|
+
/** Dialog title */
|
|
49
|
+
title: string;
|
|
50
|
+
/** Optional subtitle */
|
|
51
|
+
subtitle?: string;
|
|
52
|
+
/** Optional logo/icon to show in the header */
|
|
53
|
+
logo?: string | ReactNode;
|
|
54
|
+
/** Dialog content */
|
|
55
|
+
children: ReactNode;
|
|
56
|
+
/** Footer content (e.g. action buttons) */
|
|
57
|
+
footer?: ReactNode;
|
|
58
|
+
/** Max width class (default: "max-w-md") */
|
|
59
|
+
maxWidth?: string;
|
|
60
|
+
/** CSS class for the dialog panel */
|
|
61
|
+
className?: string;
|
|
62
|
+
/** Whether clicking the overlay closes the dialog (default: true) */
|
|
63
|
+
closeOnOverlay?: boolean;
|
|
64
|
+
}
|
|
65
|
+
declare function ManusDialog({ open, onClose, title, subtitle, logo, children, footer, maxWidth, className, closeOnOverlay, }: ManusDialogProps): react_jsx_runtime.JSX.Element;
|
|
66
|
+
|
|
67
|
+
interface ChatMessage {
|
|
68
|
+
id: string;
|
|
69
|
+
role: "user" | "assistant" | "system";
|
|
70
|
+
content: string;
|
|
71
|
+
timestamp: number;
|
|
72
|
+
/** Whether the message is still streaming */
|
|
73
|
+
isStreaming?: boolean;
|
|
74
|
+
}
|
|
75
|
+
interface AIChatBoxProps {
|
|
76
|
+
/** Chat messages to display */
|
|
77
|
+
messages: ChatMessage[];
|
|
78
|
+
/** Handler when user sends a message */
|
|
79
|
+
onSend: (message: string) => void;
|
|
80
|
+
/** Whether the assistant is currently generating a response */
|
|
81
|
+
isLoading?: boolean;
|
|
82
|
+
/** Placeholder text for the input */
|
|
83
|
+
placeholder?: string;
|
|
84
|
+
/** Title for the chat header */
|
|
85
|
+
title?: string;
|
|
86
|
+
/** Whether to show the chat in a floating panel (default: false — inline) */
|
|
87
|
+
floating?: boolean;
|
|
88
|
+
/** Whether the floating panel is open */
|
|
89
|
+
isOpen?: boolean;
|
|
90
|
+
/** Toggle floating panel open/closed */
|
|
91
|
+
onToggle?: () => void;
|
|
92
|
+
/** Render prop for message content (e.g. to use Streamdown for markdown) */
|
|
93
|
+
renderContent?: (content: string, isStreaming?: boolean) => ReactNode;
|
|
94
|
+
/** Max height for the messages area (default: "400px") */
|
|
95
|
+
maxHeight?: string;
|
|
96
|
+
/** CSS class for the container */
|
|
97
|
+
className?: string;
|
|
98
|
+
/** Whether to show the header (default: true) */
|
|
99
|
+
showHeader?: boolean;
|
|
100
|
+
}
|
|
101
|
+
declare function AIChatBox({ messages, onSend, isLoading, placeholder, title, floating, isOpen, onToggle, renderContent, maxHeight, className, showHeader, }: AIChatBoxProps): react_jsx_runtime.JSX.Element;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* MapView — Google Maps integration with Manus proxy authentication.
|
|
105
|
+
*
|
|
106
|
+
* Provides a MapView component with onMapReady callback for initialising
|
|
107
|
+
* Google Maps services (Places, Geocoder, Directions, Drawing, etc.).
|
|
108
|
+
* All map functionality works directly in the browser via the Manus proxy.
|
|
109
|
+
*
|
|
110
|
+
* Usage:
|
|
111
|
+
* <MapView
|
|
112
|
+
* apiKey={import.meta.env.VITE_FRONTEND_FORGE_API_KEY}
|
|
113
|
+
* forgeBaseUrl={import.meta.env.VITE_FRONTEND_FORGE_API_URL}
|
|
114
|
+
* initialCenter={{ lat: 40.7128, lng: -74.0060 }}
|
|
115
|
+
* initialZoom={15}
|
|
116
|
+
* onMapReady={(map) => { mapRef.current = map; }}
|
|
117
|
+
* />
|
|
118
|
+
*/
|
|
119
|
+
declare global {
|
|
120
|
+
interface Window {
|
|
121
|
+
google?: typeof google;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
interface MapViewProps {
|
|
125
|
+
/** Manus Forge API key (VITE_FRONTEND_FORGE_API_KEY) */
|
|
126
|
+
apiKey: string;
|
|
127
|
+
/** Manus Forge base URL (VITE_FRONTEND_FORGE_API_URL) */
|
|
128
|
+
forgeBaseUrl?: string;
|
|
129
|
+
/** Initial map center */
|
|
130
|
+
initialCenter?: google.maps.LatLngLiteral;
|
|
131
|
+
/** Initial zoom level */
|
|
132
|
+
initialZoom?: number;
|
|
133
|
+
/** Callback when the map is ready — use to store ref and initialise services */
|
|
134
|
+
onMapReady?: (map: google.maps.Map) => void;
|
|
135
|
+
/** Map ID for cloud-based map styling */
|
|
136
|
+
mapId?: string;
|
|
137
|
+
/** CSS class for the map container */
|
|
138
|
+
className?: string;
|
|
139
|
+
}
|
|
140
|
+
declare function MapView({ apiKey, forgeBaseUrl, initialCenter, initialZoom, onMapReady, mapId, className, }: MapViewProps): react_jsx_runtime.JSX.Element;
|
|
141
|
+
|
|
142
|
+
interface ViewOnlyBadgeProps {
|
|
143
|
+
/** Custom label (default: "View Only") */
|
|
144
|
+
label?: string;
|
|
145
|
+
/** Size variant */
|
|
146
|
+
size?: "sm" | "md";
|
|
147
|
+
/** CSS class */
|
|
148
|
+
className?: string;
|
|
149
|
+
}
|
|
150
|
+
declare function ViewOnlyBadge({ label, size, className, }: ViewOnlyBadgeProps): react_jsx_runtime.JSX.Element;
|
|
151
|
+
|
|
152
|
+
export { AIChatBox, type AIChatBoxProps, type ChatMessage, ErrorBoundary, type ErrorBoundaryProps, ManusDialog, type ManusDialogProps, MapView, type MapViewProps, NotFoundPage, type NotFoundPageProps, ViewOnlyBadge, type ViewOnlyBadgeProps };
|