@rebasepro/plugin-insights 0.3.0 → 0.5.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 +115 -0
- package/dist/common/src/collections/default-collections.d.ts +5 -8
- package/dist/common/src/data/query_builder.d.ts +6 -2
- package/dist/common/src/util/permissions.d.ts +14 -6
- package/dist/core/src/components/LoginView/LoginView.d.ts +9 -1
- package/dist/core/src/components/common/types.d.ts +3 -3
- package/dist/core/src/hooks/data/useCollectionFetch.d.ts +12 -1
- package/dist/index.es.js +215 -164
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +215 -164
- package/dist/index.umd.js.map +1 -1
- package/dist/plugin-insights/src/components/InsightWidget.d.ts +2 -2
- package/dist/plugin-insights/src/components/InsightWidgetSkeleton.d.ts +3 -1
- package/dist/plugin-insights/src/components/InsightsScorecardView.d.ts +3 -1
- package/dist/types/src/controllers/auth.d.ts +2 -2
- package/dist/types/src/controllers/client.d.ts +25 -40
- package/dist/types/src/controllers/data.d.ts +21 -3
- package/dist/types/src/controllers/data_driver.d.ts +5 -0
- package/dist/types/src/controllers/email.d.ts +2 -0
- package/dist/types/src/types/auth_adapter.d.ts +3 -56
- package/dist/types/src/types/backend.d.ts +38 -3
- package/dist/types/src/types/backend_hooks.d.ts +2 -17
- package/dist/types/src/types/collections.d.ts +30 -6
- package/dist/types/src/types/entity_views.d.ts +19 -28
- package/dist/types/src/types/properties.d.ts +9 -15
- package/dist/types/src/types/user_management_delegate.d.ts +16 -53
- package/dist/types/src/users/index.d.ts +0 -1
- package/dist/types/src/users/user.d.ts +0 -1
- package/dist/ui/src/components/Card.d.ts +2 -3
- package/dist/ui/src/components/FilterChip.d.ts +2 -10
- package/dist/ui/src/components/VirtualTable/VirtualTableProps.d.ts +8 -2
- package/package.json +4 -4
- package/src/components/InsightWidget.tsx +33 -4
- package/src/components/InsightWidgetSkeleton.tsx +7 -1
- package/src/components/InsightsScorecardView.tsx +4 -1
- package/dist/types/src/users/roles.d.ts +0 -14
package/README.md
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# @rebasepro/plugin-insights
|
|
2
|
+
|
|
3
|
+
Scorecard and KPI widget plugin for the Rebase admin panel.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @rebasepro/plugin-insights
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Peer dependencies:** `react >= 19.0.0`, `react-dom >= 19.0.0`
|
|
12
|
+
|
|
13
|
+
## What This Package Does
|
|
14
|
+
|
|
15
|
+
This plugin injects data-driven scorecard widgets into the Rebase admin UI. You define insight definitions with custom `data()` callbacks — use the Rebase SDK, call a custom function, or hit any external API. The plugin handles caching, rendering, and slot injection.
|
|
16
|
+
|
|
17
|
+
Widgets appear in three locations automatically:
|
|
18
|
+
|
|
19
|
+
- **Home page header** — KPI overview cards via the `home.children.start` slot
|
|
20
|
+
- **Collection list view** — Inline scorecards below the title, above the data list via `collection.insights`
|
|
21
|
+
- **Home page cards** — Compact metrics auto-extracted from collection insights via `home.card.insight`
|
|
22
|
+
|
|
23
|
+
Collection-level insights are the single source of truth: define once under `collections.<slug>`, and they render both in the collection view and on the home card.
|
|
24
|
+
|
|
25
|
+
## Key Exports
|
|
26
|
+
|
|
27
|
+
| Export | Type | Description |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| `useInsightsPlugin` | Hook | Creates the plugin from an `InsightsPluginConfig`. Returns a `RebasePlugin` |
|
|
30
|
+
| `InsightsPluginConfig` | Type | Top-level config: `insights` (home + collections) and optional `cacheTTL` |
|
|
31
|
+
| `InsightDefinition` | Type | Single insight: `id`, `title`, `data()` callback, `scorecard` config |
|
|
32
|
+
| `InsightDataResult` | Type | Return type of `data()`: `{ rows: DataRow[] }` |
|
|
33
|
+
| `DataRow` | Type | `Record<string, string \| number \| boolean \| null>` |
|
|
34
|
+
| `ScorecardConfig` | Type | Field mapping for value, comparison, icon, dateRange |
|
|
35
|
+
| `ScorecardFormat` | Type | Number formatting: style (decimal/currency/percent), notation, currency, decimals, showSign |
|
|
36
|
+
| `InsightsProvider` | Component | React context provider (injected automatically by the plugin) |
|
|
37
|
+
| `useInsightsEngine` | Hook | Access the insights engine from context (advanced) |
|
|
38
|
+
| `InsightsCache` | Class | TTL-based cache for insight data (advanced) |
|
|
39
|
+
| `useInsightsData` | Hook | Fetch and cache data for a specific insight (advanced) |
|
|
40
|
+
| `InsightsScorecardView` | Component | Renders a scorecard from data + config (custom layouts) |
|
|
41
|
+
| `InsightWidget` | Component | Single insight widget container (custom layouts) |
|
|
42
|
+
| `InsightWidgetSkeleton` | Component | Loading placeholder for insight widgets |
|
|
43
|
+
|
|
44
|
+
### `InsightsPluginConfig`
|
|
45
|
+
|
|
46
|
+
| Prop | Type | Default | Description |
|
|
47
|
+
|---|---|---|---|
|
|
48
|
+
| `insights.home` | `InsightDefinition[]` | — | Insights shown at the top of the home page |
|
|
49
|
+
| `insights.collections` | `Record<string, InsightDefinition[]>` | — | Insights per collection slug |
|
|
50
|
+
| `cacheTTL` | `number` | `60_000` | Cache TTL in milliseconds |
|
|
51
|
+
|
|
52
|
+
### `ScorecardConfig`
|
|
53
|
+
|
|
54
|
+
| Prop | Type | Description |
|
|
55
|
+
|---|---|---|
|
|
56
|
+
| `value.field` | `string` | Column name from data rows for the main value |
|
|
57
|
+
| `value.format` | `ScorecardFormat` | Number formatting options |
|
|
58
|
+
| `comparison.field` | `string` | Column name for comparison/delta value |
|
|
59
|
+
| `comparison.format` | `ScorecardFormat` | Formatting for comparison |
|
|
60
|
+
| `comparison.intent` | `"increase_is_good" \| "decrease_is_good"` | Controls green/red coloring |
|
|
61
|
+
| `icon` | `string` | Icon key (e.g., `"shopping_cart"`) |
|
|
62
|
+
| `dateRange` | `string` | Label text (e.g., `"Last 30 days"`) |
|
|
63
|
+
|
|
64
|
+
## Quick Start
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
import { useInsightsPlugin } from "@rebasepro/plugin-insights";
|
|
68
|
+
|
|
69
|
+
const insightsPlugin = useInsightsPlugin({
|
|
70
|
+
cacheTTL: 120_000,
|
|
71
|
+
insights: {
|
|
72
|
+
home: [
|
|
73
|
+
{
|
|
74
|
+
id: "revenue",
|
|
75
|
+
title: "Revenue",
|
|
76
|
+
data: async () => {
|
|
77
|
+
const res = await fetch("/api/analytics/revenue");
|
|
78
|
+
return { rows: [await res.json()] };
|
|
79
|
+
},
|
|
80
|
+
scorecard: {
|
|
81
|
+
value: { field: "total", format: { style: "currency", currency: "USD", notation: "compact" } },
|
|
82
|
+
comparison: { field: "delta_pct", format: { style: "percent", decimals: 1 }, intent: "increase_is_good" },
|
|
83
|
+
icon: "attach_money",
|
|
84
|
+
dateRange: "Last 30 days"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
],
|
|
88
|
+
collections: {
|
|
89
|
+
orders: [
|
|
90
|
+
{
|
|
91
|
+
id: "total_orders",
|
|
92
|
+
title: "Total Orders",
|
|
93
|
+
data: async () => {
|
|
94
|
+
const count = await rebaseClient.data.orders.count();
|
|
95
|
+
return { rows: [{ total: count }] };
|
|
96
|
+
},
|
|
97
|
+
scorecard: {
|
|
98
|
+
value: { field: "total", format: { style: "decimal", notation: "compact" } },
|
|
99
|
+
icon: "shopping_cart"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Pass to your Rebase app:
|
|
108
|
+
<RebaseFirebaseApp plugins={[insightsPlugin]} />
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Related Packages
|
|
112
|
+
|
|
113
|
+
- `@rebasepro/core` — Core framework providing the plugin system
|
|
114
|
+
- `@rebasepro/types` — Shared types (`RebasePlugin`, `SlotContribution`)
|
|
115
|
+
- `@rebasepro/ui` — UI components used by insight widgets
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import { PostgresCollection } from "@rebasepro/types";
|
|
1
|
+
import type { PostgresCollection } from "@rebasepro/types";
|
|
2
2
|
/**
|
|
3
|
-
* Default users collection
|
|
3
|
+
* Default users collection.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* (Map keyed by slug, last-write-wins) so that developer-defined
|
|
9
|
-
* collections with the same slug override this default — no hardcoded
|
|
10
|
-
* string checks required.
|
|
5
|
+
* Prepended to the developer's collections array by the admin and server.
|
|
6
|
+
* Slug-based dedup (Map keyed by slug, last-write-wins) lets developers
|
|
7
|
+
* override by defining their own collection with `slug: "users"`.
|
|
11
8
|
*/
|
|
12
9
|
export declare const defaultUsersCollection: PostgresCollection;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import { FindResponse, CollectionAccessor, QueryBuilderInterface, FilterOperator } from "@rebasepro/types";
|
|
1
|
+
import { FindResponse, CollectionAccessor, QueryBuilderInterface, FilterOperator, LogicalCondition, WhereValue, FilterCondition } from "@rebasepro/types";
|
|
2
|
+
export declare function or(...conditions: (FilterCondition | LogicalCondition)[]): LogicalCondition;
|
|
3
|
+
export declare function and(...conditions: (FilterCondition | LogicalCondition)[]): LogicalCondition;
|
|
4
|
+
export declare function cond(column: string, operator: FilterOperator, value: unknown): FilterCondition;
|
|
2
5
|
export declare class QueryBuilder<M extends Record<string, unknown> = Record<string, unknown>> implements QueryBuilderInterface<M> {
|
|
3
6
|
private collection;
|
|
4
7
|
private params;
|
|
@@ -8,7 +11,8 @@ export declare class QueryBuilder<M extends Record<string, unknown> = Record<str
|
|
|
8
11
|
* @example
|
|
9
12
|
* client.collection('users').where('age', '>=', 18).find()
|
|
10
13
|
*/
|
|
11
|
-
where
|
|
14
|
+
where<K extends keyof M & string>(column: K, operator: FilterOperator, value: WhereValue<M[K]>): this;
|
|
15
|
+
where(logicalCondition: LogicalCondition): this;
|
|
12
16
|
/**
|
|
13
17
|
* Order the results by a specific column.
|
|
14
18
|
* @example
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { Entity, EntityCollection, User } from "@rebasepro/types";
|
|
2
|
+
/**
|
|
3
|
+
* Minimal auth context for permission checking.
|
|
4
|
+
* Only requires the user object — avoids forcing callers to construct
|
|
5
|
+
* a full AuthController just to check permissions.
|
|
6
|
+
*/
|
|
7
|
+
export interface AuthContext<USER extends User = User> {
|
|
8
|
+
user: USER | null;
|
|
9
|
+
}
|
|
10
|
+
export declare function checkOperation<M extends Record<string, unknown>, USER extends User>(collection: EntityCollection<M>, authContext: AuthContext<USER>, entity: Entity<M> | null, targetOperation: "select" | "insert" | "update" | "delete"): boolean;
|
|
11
|
+
export declare function canReadCollection<M extends Record<string, unknown>, USER extends User>(collection: EntityCollection<M>, authContext: AuthContext<USER>): boolean;
|
|
12
|
+
export declare function canEditEntity<M extends Record<string, unknown>, USER extends User>(collection: EntityCollection<M>, authContext: AuthContext<USER>, path: string, entity: Entity<M> | null): boolean;
|
|
13
|
+
export declare function canCreateEntity<M extends Record<string, unknown>, USER extends User>(collection: EntityCollection<M>, authContext: AuthContext<USER>, path: string, entity: Entity<M> | null): boolean;
|
|
14
|
+
export declare function canDeleteEntity<M extends Record<string, unknown>, USER extends User>(collection: EntityCollection<M>, authContext: AuthContext<USER>, path: string, entity: Entity<M> | null): boolean;
|
|
@@ -92,10 +92,18 @@ export interface LoginViewProps {
|
|
|
92
92
|
* If not set, derived from `authController.capabilities.registration`.
|
|
93
93
|
*/
|
|
94
94
|
registrationEnabled?: boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Pre-fill the email field (e.g. for demo or testing environments).
|
|
97
|
+
*/
|
|
98
|
+
defaultEmail?: string;
|
|
99
|
+
/**
|
|
100
|
+
* Pre-fill the password field (e.g. for demo or testing environments).
|
|
101
|
+
*/
|
|
102
|
+
defaultPassword?: string;
|
|
95
103
|
}
|
|
96
104
|
/**
|
|
97
105
|
* Generic login view component that works with any AuthControllerExtended.
|
|
98
106
|
* Feature-detects capabilities to show/hide login methods.
|
|
99
107
|
* @group Core
|
|
100
108
|
*/
|
|
101
|
-
export declare function LoginView({ logo, authController, noUserComponent, disableSignupScreen, disabled, notAllowedError, googleClientId, githubClientId, linkedinClientId, title, subtitle, needsSetup, registrationEnabled, additionalComponent }: LoginViewProps): import("react/jsx-runtime").JSX.Element;
|
|
109
|
+
export declare function LoginView({ logo, authController, noUserComponent, disableSignupScreen, disabled, notAllowedError, googleClientId, githubClientId, linkedinClientId, title, subtitle, needsSetup, registrationEnabled, additionalComponent, defaultEmail, defaultPassword }: LoginViewProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Property } from "@rebasepro/types";
|
|
1
|
+
import type { Property, Entity } from "@rebasepro/types";
|
|
2
2
|
import { CollectionSize, SelectedCellProps } from "@rebasepro/types";
|
|
3
3
|
export type EntityCollectionTableController<M extends Record<string, unknown>> = {
|
|
4
4
|
/**
|
|
@@ -26,7 +26,7 @@ export type EntityCollectionTableController<M extends Record<string, unknown>> =
|
|
|
26
26
|
* Callback used when the value of a cell has changed.
|
|
27
27
|
* @param params
|
|
28
28
|
*/
|
|
29
|
-
onValueChange?: (params: OnCellValueChangeParams<unknown, M
|
|
29
|
+
onValueChange?: (params: OnCellValueChangeParams<unknown, Entity<M>>) => void;
|
|
30
30
|
/**
|
|
31
31
|
* Size of the elements in the collection
|
|
32
32
|
*/
|
|
@@ -56,7 +56,7 @@ export type UniqueFieldValidator = (props: {
|
|
|
56
56
|
* Callback when a cell has changed in a table
|
|
57
57
|
* @group Collection components
|
|
58
58
|
*/
|
|
59
|
-
export type OnCellValueChange<T, M extends Record<string, unknown>> = (params: OnCellValueChangeParams<T, M
|
|
59
|
+
export type OnCellValueChange<T, M extends Record<string, unknown>> = (params: OnCellValueChangeParams<T, Entity<M>>) => Promise<void> | void;
|
|
60
60
|
/**
|
|
61
61
|
* @group Collection components
|
|
62
62
|
*/
|
|
@@ -16,6 +16,14 @@ export interface CollectionFetchProps<M extends Record<string, any>> {
|
|
|
16
16
|
* Number of entities to fetch
|
|
17
17
|
*/
|
|
18
18
|
itemCount?: number;
|
|
19
|
+
/**
|
|
20
|
+
* Number of items to skip
|
|
21
|
+
*/
|
|
22
|
+
offset?: number;
|
|
23
|
+
/**
|
|
24
|
+
* Page number (1-indexed), alternative to offset
|
|
25
|
+
*/
|
|
26
|
+
page?: number;
|
|
19
27
|
/**
|
|
20
28
|
* Filter the fetched data by the property
|
|
21
29
|
*/
|
|
@@ -37,6 +45,7 @@ export interface CollectionFetchResult<M extends Record<string, any>> {
|
|
|
37
45
|
dataLoading: boolean;
|
|
38
46
|
noMoreToLoad: boolean;
|
|
39
47
|
dataLoadingError?: Error;
|
|
48
|
+
totalCount?: number;
|
|
40
49
|
}
|
|
41
50
|
/**
|
|
42
51
|
* This hook is used to fetch collections using a given collection
|
|
@@ -45,7 +54,9 @@ export interface CollectionFetchResult<M extends Record<string, any>> {
|
|
|
45
54
|
* @param filterValues
|
|
46
55
|
* @param sortBy
|
|
47
56
|
* @param itemCount
|
|
57
|
+
* @param offset
|
|
58
|
+
* @param page
|
|
48
59
|
* @param searchString
|
|
49
60
|
* @group Hooks and utilities
|
|
50
61
|
*/
|
|
51
|
-
export declare function useCollectionFetch<M extends Record<string, any>, USER extends User>({ path, collection, filterValues, sortBy, itemCount, searchString }: CollectionFetchProps<M>): CollectionFetchResult<M>;
|
|
62
|
+
export declare function useCollectionFetch<M extends Record<string, any>, USER extends User>({ path, collection, filterValues, sortBy, itemCount, offset, page, searchString }: CollectionFetchProps<M>): CollectionFetchResult<M>;
|