@rebasepro/plugin-insights 0.0.1-canary.4f204c2
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/LICENSE +6 -0
- package/dist/common/src/collections/CollectionRegistry.d.ts +56 -0
- package/dist/common/src/collections/index.d.ts +1 -0
- package/dist/common/src/data/buildRebaseData.d.ts +14 -0
- package/dist/common/src/index.d.ts +3 -0
- package/dist/common/src/util/builders.d.ts +57 -0
- package/dist/common/src/util/callbacks.d.ts +6 -0
- package/dist/common/src/util/collections.d.ts +11 -0
- package/dist/common/src/util/common.d.ts +2 -0
- package/dist/common/src/util/conditions.d.ts +26 -0
- package/dist/common/src/util/entities.d.ts +58 -0
- package/dist/common/src/util/enums.d.ts +3 -0
- package/dist/common/src/util/index.d.ts +16 -0
- package/dist/common/src/util/navigation_from_path.d.ts +34 -0
- package/dist/common/src/util/navigation_utils.d.ts +20 -0
- package/dist/common/src/util/parent_references_from_path.d.ts +6 -0
- package/dist/common/src/util/paths.d.ts +14 -0
- package/dist/common/src/util/permissions.d.ts +5 -0
- package/dist/common/src/util/references.d.ts +2 -0
- package/dist/common/src/util/relations.d.ts +22 -0
- package/dist/common/src/util/resolutions.d.ts +72 -0
- package/dist/common/src/util/storage.d.ts +24 -0
- package/dist/core/src/components/AIIcon.d.ts +16 -0
- package/dist/core/src/components/ConfirmationDialog.d.ts +9 -0
- package/dist/core/src/components/Debug/UIReferenceView.d.ts +1 -0
- package/dist/core/src/components/Debug/UIStyleGuide.d.ts +1 -0
- package/dist/core/src/components/ErrorTooltip.d.ts +2 -0
- package/dist/core/src/components/ErrorView.d.ts +21 -0
- package/dist/core/src/components/LanguageToggle.d.ts +1 -0
- package/dist/core/src/components/LoginView/LoginView.d.ts +68 -0
- package/dist/core/src/components/LoginView/index.d.ts +2 -0
- package/dist/core/src/components/NotFoundPage.d.ts +1 -0
- package/dist/core/src/components/RebaseAuth.d.ts +10 -0
- package/dist/core/src/components/RebaseLogo.d.ts +7 -0
- package/dist/core/src/components/UnsavedChangesDialog.d.ts +9 -0
- package/dist/core/src/components/UserDisplay.d.ts +7 -0
- package/dist/core/src/components/UserSelectPopover.d.ts +62 -0
- package/dist/core/src/components/UserSettingsView.d.ts +1 -0
- package/dist/core/src/components/common/index.d.ts +6 -0
- package/dist/core/src/components/common/table_height.d.ts +5 -0
- package/dist/core/src/components/common/types.d.ts +63 -0
- package/dist/core/src/components/common/useColumnsIds.d.ts +9 -0
- package/dist/core/src/components/common/useDataTableController.d.ts +45 -0
- package/dist/core/src/components/common/useDebouncedData.d.ts +9 -0
- package/dist/core/src/components/common/useScrollRestoration.d.ts +14 -0
- package/dist/core/src/components/index.d.ts +16 -0
- package/dist/core/src/contexts/AdminModeController.d.ts +4 -0
- package/dist/core/src/contexts/AnalyticsContext.d.ts +3 -0
- package/dist/core/src/contexts/AuthControllerContext.d.ts +3 -0
- package/dist/core/src/contexts/CustomizationControllerContext.d.ts +3 -0
- package/dist/core/src/contexts/DataDriverContext.d.ts +3 -0
- package/dist/core/src/contexts/DatabaseAdminContext.d.ts +3 -0
- package/dist/core/src/contexts/DialogsProvider.d.ts +4 -0
- package/dist/core/src/contexts/EffectiveRoleController.d.ts +4 -0
- package/dist/core/src/contexts/InternalUserManagementContext.d.ts +3 -0
- package/dist/core/src/contexts/ModeController.d.ts +4 -0
- package/dist/core/src/contexts/RebaseClientInstanceContext.d.ts +6 -0
- package/dist/core/src/contexts/RebaseDataContext.d.ts +3 -0
- package/dist/core/src/contexts/SnackbarProvider.d.ts +2 -0
- package/dist/core/src/contexts/StorageSourceContext.d.ts +3 -0
- package/dist/core/src/contexts/UserConfigurationPersistenceContext.d.ts +3 -0
- package/dist/core/src/contexts/index.d.ts +13 -0
- package/dist/core/src/core/PluginLifecycleManager.d.ts +17 -0
- package/dist/core/src/core/PluginProviderStack.d.ts +21 -0
- package/dist/core/src/core/Rebase.d.ts +14 -0
- package/dist/core/src/core/RebaseProps.d.ts +136 -0
- package/dist/core/src/core/RebaseRouter.d.ts +4 -0
- package/dist/core/src/core/RebaseRoutes.d.ts +17 -0
- package/dist/core/src/core/index.d.ts +4 -0
- package/dist/core/src/hooks/ApiConfigContext.d.ts +24 -0
- package/dist/core/src/hooks/data/delete.d.ts +31 -0
- package/dist/core/src/hooks/data/save.d.ts +34 -0
- package/dist/core/src/hooks/data/useCollectionFetch.d.ts +51 -0
- package/dist/core/src/hooks/data/useData.d.ts +13 -0
- package/dist/core/src/hooks/data/useDataOrder.d.ts +12 -0
- package/dist/core/src/hooks/data/useEntityFetch.d.ts +38 -0
- package/dist/core/src/hooks/data/useRelationSelector.d.ts +52 -0
- package/dist/core/src/hooks/data/useUserSelector.d.ts +31 -0
- package/dist/core/src/hooks/index.d.ts +37 -0
- package/dist/core/src/hooks/useAdminModeController.d.ts +19 -0
- package/dist/core/src/hooks/useAnalyticsController.d.ts +5 -0
- package/dist/core/src/hooks/useAuthController.d.ts +11 -0
- package/dist/core/src/hooks/useAuthSubscription.d.ts +2 -0
- package/dist/core/src/hooks/useBackendStorageSource.d.ts +30 -0
- package/dist/core/src/hooks/useBridgeRegistration.d.ts +18 -0
- package/dist/core/src/hooks/useBrowserTitleAndIcon.d.ts +6 -0
- package/dist/core/src/hooks/useBuildAdminModeController.d.ts +6 -0
- package/dist/core/src/hooks/useBuildEffectiveRoleController.d.ts +8 -0
- package/dist/core/src/hooks/useBuildLocalConfigurationPersistence.d.ts +2 -0
- package/dist/core/src/hooks/useBuildModeController.d.ts +6 -0
- package/dist/core/src/hooks/useClipboard.d.ts +57 -0
- package/dist/core/src/hooks/useCollapsedGroups.d.ts +12 -0
- package/dist/core/src/hooks/useCustomizationController.d.ts +11 -0
- package/dist/core/src/hooks/useDialogsController.d.ts +11 -0
- package/dist/core/src/hooks/useEffectiveRoleController.d.ts +7 -0
- package/dist/core/src/hooks/useInternalUserManagementController.d.ts +12 -0
- package/dist/core/src/hooks/useLargeLayout.d.ts +1 -0
- package/dist/core/src/hooks/useModeController.d.ts +19 -0
- package/dist/core/src/hooks/usePermissions.d.ts +12 -0
- package/dist/core/src/hooks/useRebaseClient.d.ts +5 -0
- package/dist/core/src/hooks/useRebaseContext.d.ts +11 -0
- package/dist/core/src/hooks/useRebaseRegistry.d.ts +34 -0
- package/dist/core/src/hooks/useSlot.d.ts +18 -0
- package/dist/core/src/hooks/useSnackbarController.d.ts +20 -0
- package/dist/core/src/hooks/useStorageSource.d.ts +7 -0
- package/dist/core/src/hooks/useStudioBridge.d.ts +91 -0
- package/dist/core/src/hooks/useTranslation.d.ts +17 -0
- package/dist/core/src/hooks/useUnsavedChangesDialog.d.ts +12 -0
- package/dist/core/src/hooks/useUserConfigurationPersistence.d.ts +8 -0
- package/dist/core/src/hooks/useValidateAuthenticator.d.ts +21 -0
- package/dist/core/src/i18n/RebaseI18nProvider.d.ts +33 -0
- package/dist/core/src/index.d.ts +15 -0
- package/dist/core/src/internal/common.d.ts +3 -0
- package/dist/core/src/internal/useRestoreScroll.d.ts +6 -0
- package/dist/core/src/locales/de.d.ts +2 -0
- package/dist/core/src/locales/en.d.ts +10 -0
- package/dist/core/src/locales/es.d.ts +10 -0
- package/dist/core/src/locales/fr.d.ts +2 -0
- package/dist/core/src/locales/hi.d.ts +2 -0
- package/dist/core/src/locales/it.d.ts +2 -0
- package/dist/core/src/locales/pt.d.ts +7 -0
- package/dist/core/src/util/constants.d.ts +1 -0
- package/dist/core/src/util/createFormexStub.d.ts +2 -0
- package/dist/core/src/util/entity_cache.d.ts +27 -0
- package/dist/core/src/util/enums.d.ts +5 -0
- package/dist/core/src/util/icon_list.d.ts +5 -0
- package/dist/core/src/util/icon_synonyms.d.ts +1 -0
- package/dist/core/src/util/icons.d.ts +20 -0
- package/dist/core/src/util/index.d.ts +10 -0
- package/dist/core/src/util/previews.d.ts +4 -0
- package/dist/core/src/util/useStorageUploadController.d.ts +38 -0
- package/dist/core/src/util/useTraceUpdate.d.ts +2 -0
- package/dist/formex/src/Field.d.ts +52 -0
- package/dist/formex/src/Formex.d.ts +7 -0
- package/dist/formex/src/index.d.ts +5 -0
- package/dist/formex/src/types.d.ts +40 -0
- package/dist/formex/src/useCreateFormex.d.ts +14 -0
- package/dist/formex/src/utils.d.ts +16 -0
- package/dist/index.es.js +945 -0
- package/dist/index.es.js.map +1 -0
- package/dist/index.umd.js +944 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/plugin-insights/src/components/CollectionInsightsInline.d.ts +16 -0
- package/dist/plugin-insights/src/components/HomeCardInsightSlot.d.ts +16 -0
- package/dist/plugin-insights/src/components/HomeInsightsSlot.d.ts +13 -0
- package/dist/plugin-insights/src/components/InsightWidget.d.ts +19 -0
- package/dist/plugin-insights/src/components/InsightWidgetSkeleton.d.ts +20 -0
- package/dist/plugin-insights/src/components/InsightsScorecardView.d.ts +19 -0
- package/dist/plugin-insights/src/engine/InsightsCache.d.ts +18 -0
- package/dist/plugin-insights/src/engine/InsightsProvider.d.ts +22 -0
- package/dist/plugin-insights/src/engine/useInsightsData.d.ts +17 -0
- package/dist/plugin-insights/src/index.d.ts +8 -0
- package/dist/plugin-insights/src/types/engine.d.ts +79 -0
- package/dist/plugin-insights/src/types/index.d.ts +2 -0
- package/dist/plugin-insights/src/types/widgets.d.ts +59 -0
- package/dist/plugin-insights/src/useInsightsPlugin.d.ts +37 -0
- package/dist/types/src/controllers/analytics_controller.d.ts +7 -0
- package/dist/types/src/controllers/auth.d.ts +119 -0
- package/dist/types/src/controllers/client.d.ts +170 -0
- package/dist/types/src/controllers/collection_registry.d.ts +45 -0
- package/dist/types/src/controllers/customization_controller.d.ts +60 -0
- package/dist/types/src/controllers/data.d.ts +168 -0
- package/dist/types/src/controllers/data_driver.d.ts +160 -0
- package/dist/types/src/controllers/database_admin.d.ts +11 -0
- package/dist/types/src/controllers/dialogs_controller.d.ts +36 -0
- package/dist/types/src/controllers/effective_role.d.ts +4 -0
- package/dist/types/src/controllers/email.d.ts +34 -0
- package/dist/types/src/controllers/index.d.ts +18 -0
- package/dist/types/src/controllers/local_config_persistence.d.ts +20 -0
- package/dist/types/src/controllers/navigation.d.ts +213 -0
- package/dist/types/src/controllers/registry.d.ts +54 -0
- package/dist/types/src/controllers/side_dialogs_controller.d.ts +67 -0
- package/dist/types/src/controllers/side_entity_controller.d.ts +90 -0
- package/dist/types/src/controllers/snackbar.d.ts +24 -0
- package/dist/types/src/controllers/storage.d.ts +171 -0
- package/dist/types/src/index.d.ts +4 -0
- package/dist/types/src/rebase_context.d.ts +105 -0
- package/dist/types/src/types/backend.d.ts +536 -0
- package/dist/types/src/types/builders.d.ts +15 -0
- package/dist/types/src/types/chips.d.ts +5 -0
- package/dist/types/src/types/collections.d.ts +856 -0
- package/dist/types/src/types/cron.d.ts +102 -0
- package/dist/types/src/types/data_source.d.ts +64 -0
- package/dist/types/src/types/entities.d.ts +145 -0
- package/dist/types/src/types/entity_actions.d.ts +98 -0
- package/dist/types/src/types/entity_callbacks.d.ts +173 -0
- package/dist/types/src/types/entity_link_builder.d.ts +7 -0
- package/dist/types/src/types/entity_overrides.d.ts +10 -0
- package/dist/types/src/types/entity_views.d.ts +61 -0
- package/dist/types/src/types/export_import.d.ts +21 -0
- package/dist/types/src/types/index.d.ts +23 -0
- package/dist/types/src/types/locales.d.ts +4 -0
- package/dist/types/src/types/modify_collections.d.ts +5 -0
- package/dist/types/src/types/plugins.d.ts +279 -0
- package/dist/types/src/types/properties.d.ts +1176 -0
- package/dist/types/src/types/property_config.d.ts +70 -0
- package/dist/types/src/types/relations.d.ts +336 -0
- package/dist/types/src/types/slots.d.ts +252 -0
- package/dist/types/src/types/translations.d.ts +870 -0
- package/dist/types/src/types/user_management_delegate.d.ts +121 -0
- package/dist/types/src/types/websockets.d.ts +78 -0
- package/dist/types/src/users/index.d.ts +2 -0
- package/dist/types/src/users/roles.d.ts +22 -0
- package/dist/types/src/users/user.d.ts +46 -0
- package/dist/ui/src/components/Alert.d.ts +12 -0
- package/dist/ui/src/components/Autocomplete.d.ts +21 -0
- package/dist/ui/src/components/Avatar.d.ts +11 -0
- package/dist/ui/src/components/Badge.d.ts +8 -0
- package/dist/ui/src/components/BooleanSwitch.d.ts +14 -0
- package/dist/ui/src/components/BooleanSwitchWithLabel.d.ts +17 -0
- package/dist/ui/src/components/Button.d.ts +14 -0
- package/dist/ui/src/components/Card.d.ts +9 -0
- package/dist/ui/src/components/CenteredView.d.ts +9 -0
- package/dist/ui/src/components/Checkbox.d.ts +13 -0
- package/dist/ui/src/components/Chip.d.ts +26 -0
- package/dist/ui/src/components/CircularProgress.d.ts +5 -0
- package/dist/ui/src/components/CircularProgressCenter.d.ts +11 -0
- package/dist/ui/src/components/Collapse.d.ts +9 -0
- package/dist/ui/src/components/ColorPicker.d.ts +30 -0
- package/dist/ui/src/components/Container.d.ts +8 -0
- package/dist/ui/src/components/DateTimeField.d.ts +24 -0
- package/dist/ui/src/components/DebouncedTextField.d.ts +2 -0
- package/dist/ui/src/components/Dialog.d.ts +39 -0
- package/dist/ui/src/components/DialogActions.d.ts +7 -0
- package/dist/ui/src/components/DialogContent.d.ts +7 -0
- package/dist/ui/src/components/DialogTitle.d.ts +10 -0
- package/dist/ui/src/components/ErrorBoundary.d.ts +11 -0
- package/dist/ui/src/components/ExpandablePanel.d.ts +12 -0
- package/dist/ui/src/components/FileUpload.d.ts +23 -0
- package/dist/ui/src/components/IconButton.d.ts +12 -0
- package/dist/ui/src/components/InfoLabel.d.ts +5 -0
- package/dist/ui/src/components/InputLabel.d.ts +11 -0
- package/dist/ui/src/components/Label.d.ts +7 -0
- package/dist/ui/src/components/LoadingButton.d.ts +7 -0
- package/dist/ui/src/components/Markdown.d.ts +10 -0
- package/dist/ui/src/components/Menu.d.ts +23 -0
- package/dist/ui/src/components/Menubar.d.ts +80 -0
- package/dist/ui/src/components/MultiSelect.d.ts +48 -0
- package/dist/ui/src/components/Paper.d.ts +6 -0
- package/dist/ui/src/components/Popover.d.ts +24 -0
- package/dist/ui/src/components/RadioGroup.d.ts +28 -0
- package/dist/ui/src/components/ResizablePanels.d.ts +18 -0
- package/dist/ui/src/components/SearchBar.d.ts +22 -0
- package/dist/ui/src/components/Select.d.ts +43 -0
- package/dist/ui/src/components/Separator.d.ts +5 -0
- package/dist/ui/src/components/Sheet.d.ts +22 -0
- package/dist/ui/src/components/Skeleton.d.ts +6 -0
- package/dist/ui/src/components/Slider.d.ts +21 -0
- package/dist/ui/src/components/Table.d.ts +34 -0
- package/dist/ui/src/components/Tabs.d.ts +19 -0
- package/dist/ui/src/components/TextField.d.ts +58 -0
- package/dist/ui/src/components/TextareaAutosize.d.ts +43 -0
- package/dist/ui/src/components/ToggleButtonGroup.d.ts +30 -0
- package/dist/ui/src/components/Tooltip.d.ts +19 -0
- package/dist/ui/src/components/Typography.d.ts +36 -0
- package/dist/ui/src/components/VirtualTable/VirtualTable.d.ts +11 -0
- package/dist/ui/src/components/VirtualTable/VirtualTableCell.d.ts +21 -0
- package/dist/ui/src/components/VirtualTable/VirtualTableHeader.d.ts +29 -0
- package/dist/ui/src/components/VirtualTable/VirtualTableHeaderRow.d.ts +2 -0
- package/dist/ui/src/components/VirtualTable/VirtualTableProps.d.ts +243 -0
- package/dist/ui/src/components/VirtualTable/VirtualTableRow.d.ts +3 -0
- package/dist/ui/src/components/VirtualTable/index.d.ts +3 -0
- package/dist/ui/src/components/VirtualTable/types.d.ts +38 -0
- package/dist/ui/src/components/common/SelectInputLabel.d.ts +5 -0
- package/dist/ui/src/components/index.d.ts +53 -0
- package/dist/ui/src/hooks/PortalContainerContext.d.ts +31 -0
- package/dist/ui/src/hooks/index.d.ts +6 -0
- package/dist/ui/src/hooks/useDebounceCallback.d.ts +1 -0
- package/dist/ui/src/hooks/useDebounceValue.d.ts +1 -0
- package/dist/ui/src/hooks/useDebouncedCallback.d.ts +1 -0
- package/dist/ui/src/hooks/useInjectStyles.d.ts +7 -0
- package/dist/ui/src/hooks/useOutsideAlerter.d.ts +5 -0
- package/dist/ui/src/icons/GitHubIcon.d.ts +2 -0
- package/dist/ui/src/icons/HandleIcon.d.ts +1 -0
- package/dist/ui/src/icons/Icon.d.ts +20 -0
- package/dist/ui/src/icons/cool_icon_keys.d.ts +1 -0
- package/dist/ui/src/icons/icon_keys.d.ts +1 -0
- package/dist/ui/src/icons/index.d.ts +6 -0
- package/dist/ui/src/index.d.ts +5 -0
- package/dist/ui/src/styles.d.ts +12 -0
- package/dist/ui/src/util/chip_colors.d.ts +4 -0
- package/dist/ui/src/util/cls.d.ts +2 -0
- package/dist/ui/src/util/debounce.d.ts +10 -0
- package/dist/ui/src/util/hash.d.ts +1 -0
- package/dist/ui/src/util/index.d.ts +4 -0
- package/dist/ui/src/util/key_to_icon_component.d.ts +1 -0
- package/package.json +80 -0
- package/src/components/CollectionInsightsInline.tsx +30 -0
- package/src/components/HomeCardInsightSlot.tsx +36 -0
- package/src/components/HomeInsightsSlot.tsx +30 -0
- package/src/components/InsightWidget.tsx +65 -0
- package/src/components/InsightWidgetSkeleton.tsx +122 -0
- package/src/components/InsightsScorecardView.tsx +160 -0
- package/src/engine/InsightsCache.ts +52 -0
- package/src/engine/InsightsProvider.tsx +38 -0
- package/src/engine/useInsightsData.ts +100 -0
- package/src/index.ts +22 -0
- package/src/types/engine.ts +85 -0
- package/src/types/index.ts +5 -0
- package/src/types/widgets.ts +66 -0
- package/src/useInsightsPlugin.tsx +117 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import type { InsightDefinition, InsightDataResult } from "../types";
|
|
3
|
+
import { useInsightsEngine } from "./InsightsProvider";
|
|
4
|
+
import { useAuthController } from "@rebasepro/core";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Hook that fetches and caches data for a single insight definition.
|
|
8
|
+
*
|
|
9
|
+
* Calls the definition's own `data()` callback and manages:
|
|
10
|
+
* - TTL-based caching via InsightsCache
|
|
11
|
+
* - Inflight request deduplication (multiple mounts of the same widget)
|
|
12
|
+
* - Loading and error state management
|
|
13
|
+
*
|
|
14
|
+
* @param definition - The insight to fetch data for
|
|
15
|
+
* @param collectionSlug - Optional collection context for cache key scoping
|
|
16
|
+
*/
|
|
17
|
+
export function useInsightsData(
|
|
18
|
+
definition: InsightDefinition,
|
|
19
|
+
collectionSlug?: string
|
|
20
|
+
): {
|
|
21
|
+
data: InsightDataResult | null;
|
|
22
|
+
loading: boolean;
|
|
23
|
+
error: Error | null;
|
|
24
|
+
} {
|
|
25
|
+
const engine = useInsightsEngine();
|
|
26
|
+
const cache = engine?.cache ?? null;
|
|
27
|
+
const { initialLoading, authLoading, user, loginSkipped } = useAuthController();
|
|
28
|
+
const authReady = !initialLoading && !authLoading && (Boolean(user) || loginSkipped);
|
|
29
|
+
const [data, setData] = useState<InsightDataResult | null>(null);
|
|
30
|
+
const [loading, setLoading] = useState(true);
|
|
31
|
+
const [error, setError] = useState<Error | null>(null);
|
|
32
|
+
|
|
33
|
+
const cacheKey = `${definition.id}:${collectionSlug ?? "global"}`;
|
|
34
|
+
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
// Keep showing skeleton until both auth and engine are ready
|
|
37
|
+
if (!authReady || !cache) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let cancelled = false;
|
|
42
|
+
|
|
43
|
+
// 1. Check cache
|
|
44
|
+
const cached = cache.get(cacheKey);
|
|
45
|
+
if (cached) {
|
|
46
|
+
setData(cached);
|
|
47
|
+
setLoading(false);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// 2. Check inflight — deduplicate concurrent requests for the same widget
|
|
52
|
+
const inflight = cache.getInflight(cacheKey);
|
|
53
|
+
if (inflight) {
|
|
54
|
+
setLoading(true);
|
|
55
|
+
inflight
|
|
56
|
+
.then((result) => {
|
|
57
|
+
if (!cancelled) {
|
|
58
|
+
setData(result);
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
.catch((err) => {
|
|
62
|
+
if (!cancelled) setError(err instanceof Error ? err : new Error(String(err)));
|
|
63
|
+
})
|
|
64
|
+
.finally(() => {
|
|
65
|
+
if (!cancelled) setLoading(false);
|
|
66
|
+
});
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// 3. Fresh fetch — invoke the definition's own data callback
|
|
71
|
+
setLoading(true);
|
|
72
|
+
setError(null);
|
|
73
|
+
|
|
74
|
+
const promise = definition.data();
|
|
75
|
+
|
|
76
|
+
cache.setInflight(cacheKey, promise);
|
|
77
|
+
|
|
78
|
+
promise
|
|
79
|
+
.then((result) => {
|
|
80
|
+
cache.set(cacheKey, result);
|
|
81
|
+
if (!cancelled) {
|
|
82
|
+
setData(result);
|
|
83
|
+
}
|
|
84
|
+
})
|
|
85
|
+
.catch((err) => {
|
|
86
|
+
if (!cancelled) {
|
|
87
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
.finally(() => {
|
|
91
|
+
if (!cancelled) setLoading(false);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
return () => {
|
|
95
|
+
cancelled = true;
|
|
96
|
+
};
|
|
97
|
+
}, [definition.id, definition.data, collectionSlug, cacheKey, cache, authReady]);
|
|
98
|
+
|
|
99
|
+
return { data, loading, error };
|
|
100
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// ── Types ─────────────────────────────────────────────────────────────
|
|
2
|
+
export type {
|
|
3
|
+
DataRow,
|
|
4
|
+
ScorecardFormat,
|
|
5
|
+
ScorecardConfig,
|
|
6
|
+
InsightDataResult,
|
|
7
|
+
InsightDefinition,
|
|
8
|
+
InsightsPluginConfig,
|
|
9
|
+
} from "./types";
|
|
10
|
+
|
|
11
|
+
// ── Plugin ────────────────────────────────────────────────────────────
|
|
12
|
+
export { useInsightsPlugin } from "./useInsightsPlugin";
|
|
13
|
+
|
|
14
|
+
// ── Engine (for advanced usage) ───────────────────────────────────────
|
|
15
|
+
export { InsightsProvider, useInsightsEngine } from "./engine/InsightsProvider";
|
|
16
|
+
export { InsightsCache } from "./engine/InsightsCache";
|
|
17
|
+
export { useInsightsData } from "./engine/useInsightsData";
|
|
18
|
+
|
|
19
|
+
// ── Widget components (for custom layouts) ────────────────────────────
|
|
20
|
+
export { InsightsScorecardView } from "./components/InsightsScorecardView";
|
|
21
|
+
export { InsightWidget } from "./components/InsightWidget";
|
|
22
|
+
export { InsightWidgetSkeleton } from "./components/InsightWidgetSkeleton";
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { DataRow, ScorecardConfig } from "./widgets";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Result returned by an insight's data callback.
|
|
5
|
+
*/
|
|
6
|
+
export interface InsightDataResult {
|
|
7
|
+
rows: DataRow[];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A single insight definition — the "dry" configuration that describes
|
|
12
|
+
* what data to fetch and how to render it.
|
|
13
|
+
*
|
|
14
|
+
* Each insight owns its own `data()` callback, giving the developer
|
|
15
|
+
* full flexibility: use the Rebase client SDK, call a custom function,
|
|
16
|
+
* hit an external API — whatever makes sense for that widget.
|
|
17
|
+
*/
|
|
18
|
+
export interface InsightDefinition {
|
|
19
|
+
/** Unique identifier for this insight */
|
|
20
|
+
id: string;
|
|
21
|
+
/** Display title */
|
|
22
|
+
title: string;
|
|
23
|
+
/** Optional description */
|
|
24
|
+
description?: string;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Async callback that fetches data for this insight.
|
|
28
|
+
*
|
|
29
|
+
* The developer has full control — they can use any data source:
|
|
30
|
+
* - `rebaseClient.data.orders.find({ limit: 100 })`
|
|
31
|
+
* - `rebaseClient.call("functions/my-analytics", { ... })`
|
|
32
|
+
* - A plain `fetch()` to any external API
|
|
33
|
+
* - Static data for prototyping
|
|
34
|
+
*
|
|
35
|
+
* @returns Tabular data as `{ rows: DataRow[] }`.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* data: async () => {
|
|
40
|
+
* const res = await rebaseClient.data.orders.find({
|
|
41
|
+
* limit: 1000,
|
|
42
|
+
* orderBy: "created_at",
|
|
43
|
+
* });
|
|
44
|
+
* return { rows: res.data };
|
|
45
|
+
* }
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
data: () => Promise<InsightDataResult>;
|
|
49
|
+
|
|
50
|
+
/** Scorecard field mapping + formatting. */
|
|
51
|
+
scorecard: ScorecardConfig;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Full plugin configuration passed to `useInsightsPlugin`.
|
|
56
|
+
*
|
|
57
|
+
* The developer defines scorecard widgets by placement and provides
|
|
58
|
+
* their own data callbacks. No global fetch function needed — each
|
|
59
|
+
* widget is self-contained.
|
|
60
|
+
*
|
|
61
|
+
* Collection-level insights (`collections.<slug>`) are rendered in two places
|
|
62
|
+
* automatically:
|
|
63
|
+
* - **Collection list view**: Scorecards appear inline below the title and
|
|
64
|
+
* above the data list.
|
|
65
|
+
* - **Home page cards**: Scorecards are auto-extracted and rendered as compact
|
|
66
|
+
* widgets inside each collection's card on the home page.
|
|
67
|
+
*
|
|
68
|
+
* This eliminates the need to duplicate definitions across different locations.
|
|
69
|
+
*/
|
|
70
|
+
export interface InsightsPluginConfig {
|
|
71
|
+
/**
|
|
72
|
+
* Insight definitions keyed by placement.
|
|
73
|
+
*
|
|
74
|
+
* - `home`: Rendered at the top of the home page via `home.children.start`.
|
|
75
|
+
* - `collections.<slug>`: Rendered inline in that collection's list view
|
|
76
|
+
* and auto-extracted as compact scorecards on the home card.
|
|
77
|
+
*/
|
|
78
|
+
insights: {
|
|
79
|
+
home?: InsightDefinition[];
|
|
80
|
+
collections?: Record<string, InsightDefinition[]>;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/** Optional cache TTL in milliseconds (default: 60_000) */
|
|
84
|
+
cacheTTL?: number;
|
|
85
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tabular data types used by insight widgets.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/** A single row of data as key-value pairs. */
|
|
6
|
+
export type DataRow = Record<string, string | number | boolean | null>;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Formatting options for scorecard numbers.
|
|
10
|
+
* Uses Intl.NumberFormat standard.
|
|
11
|
+
*/
|
|
12
|
+
export interface ScorecardFormat {
|
|
13
|
+
/**
|
|
14
|
+
* The style of formatting.
|
|
15
|
+
* - `decimal`: 1,234.5
|
|
16
|
+
* - `currency`: $1,234.50
|
|
17
|
+
* - `percent`: 12.5%
|
|
18
|
+
*/
|
|
19
|
+
style: "decimal" | "currency" | "percent";
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* How to display the number.
|
|
23
|
+
* - `standard`: 1,234,567 (default)
|
|
24
|
+
* - `compact`: 1.2M
|
|
25
|
+
*/
|
|
26
|
+
notation?: "standard" | "compact";
|
|
27
|
+
|
|
28
|
+
/** Required if style is 'currency' (e.g., "USD", "EUR") */
|
|
29
|
+
currency?: string;
|
|
30
|
+
|
|
31
|
+
/** Number of decimal places to show */
|
|
32
|
+
decimals?: number;
|
|
33
|
+
|
|
34
|
+
/** If true, adds a '+' sign for positive numbers (e.g., +12.5%) */
|
|
35
|
+
showSign?: boolean;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Scorecard widget configuration — field mapping + formatting.
|
|
40
|
+
*/
|
|
41
|
+
export interface ScorecardConfig {
|
|
42
|
+
/** Main value configuration */
|
|
43
|
+
value: {
|
|
44
|
+
/** The column name from the query result for the main value */
|
|
45
|
+
field: string;
|
|
46
|
+
/** How to format this number */
|
|
47
|
+
format?: ScorecardFormat;
|
|
48
|
+
};
|
|
49
|
+
/** Comparison value configuration (optional) */
|
|
50
|
+
comparison?: {
|
|
51
|
+
/** The column name from the query result for the comparison value */
|
|
52
|
+
field: string;
|
|
53
|
+
/** How to format this number */
|
|
54
|
+
format?: ScorecardFormat;
|
|
55
|
+
/**
|
|
56
|
+
* Determines the color (green/red) based on the value.
|
|
57
|
+
* - `increase_is_good`: Positive = green, negative = red.
|
|
58
|
+
* - `decrease_is_good`: Positive = red, negative = green.
|
|
59
|
+
*/
|
|
60
|
+
intent: "increase_is_good" | "decrease_is_good";
|
|
61
|
+
};
|
|
62
|
+
/** Optional icon key (e.g., "shopping_cart", "users") — resolved via getIcon */
|
|
63
|
+
icon?: string;
|
|
64
|
+
/** Optional date range text (e.g., "Last 30 days") */
|
|
65
|
+
dateRange?: string;
|
|
66
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { RebasePlugin, SlotContribution } from "@rebasepro/types";
|
|
3
|
+
import type { InsightsPluginConfig } from "./types";
|
|
4
|
+
import { InsightsProvider } from "./engine/InsightsProvider";
|
|
5
|
+
import { HomeCardInsightSlot } from "./components/HomeCardInsightSlot";
|
|
6
|
+
import { HomeInsightsSlot } from "./components/HomeInsightsSlot";
|
|
7
|
+
import { CollectionInsightsInline } from "./components/CollectionInsightsInline";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Creates the Insights plugin for Rebase.
|
|
11
|
+
*
|
|
12
|
+
* This plugin injects scorecard widgets into key UI locations:
|
|
13
|
+
* - **Home page header**: KPI overview via `home.children.start` slot
|
|
14
|
+
* - **Collection list view**: Scorecards inline (below title, above list) via `collection.insights` slot
|
|
15
|
+
* - **Home page cards**: Compact scorecard metrics auto-extracted from collection insights via `home.card.insight` slot
|
|
16
|
+
*
|
|
17
|
+
* Collection-level insights (`collections.<slug>`) are the single source of truth:
|
|
18
|
+
* scorecards render in the collection list view and are automatically extracted
|
|
19
|
+
* to show as compact widgets on the corresponding home page card.
|
|
20
|
+
*
|
|
21
|
+
* Each insight owns its own `data()` callback — use the Rebase client SDK,
|
|
22
|
+
* call a custom function, or hit any external API. Full flexibility, zero new endpoints.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* import { useInsightsPlugin } from "@rebasepro/plugin-insights";
|
|
27
|
+
*
|
|
28
|
+
* const insightsPlugin = useInsightsPlugin({
|
|
29
|
+
* cacheTTL: 120_000,
|
|
30
|
+
* insights: {
|
|
31
|
+
* home: [
|
|
32
|
+
* { id: "revenue", title: "Revenue", data: async () => ..., scorecard: { ... } },
|
|
33
|
+
* ],
|
|
34
|
+
* collections: {
|
|
35
|
+
* orders: [
|
|
36
|
+
* { id: "total", title: "Total Orders", data: async () => ..., scorecard: { ... } },
|
|
37
|
+
* ],
|
|
38
|
+
* },
|
|
39
|
+
* },
|
|
40
|
+
* });
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export function useInsightsPlugin(config: InsightsPluginConfig): RebasePlugin {
|
|
44
|
+
const { insights, cacheTTL } = config;
|
|
45
|
+
const slots: SlotContribution[] = [];
|
|
46
|
+
|
|
47
|
+
// ── Home page insights ────────────────────────────────────────────
|
|
48
|
+
if (insights.home && insights.home.length > 0) {
|
|
49
|
+
const homeInsights = insights.home;
|
|
50
|
+
slots.push({
|
|
51
|
+
slot: "home.children.start" as const,
|
|
52
|
+
Component: (props: Record<string, unknown>) => (
|
|
53
|
+
<HomeInsightsSlot
|
|
54
|
+
{...props}
|
|
55
|
+
insights={homeInsights}
|
|
56
|
+
/>
|
|
57
|
+
),
|
|
58
|
+
order: 10,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ── Per-collection insights ───────────────────────────────────────
|
|
63
|
+
// A single `collections.<slug>` definition serves two slots:
|
|
64
|
+
// 1. collection.insights → inline scorecards in the list view
|
|
65
|
+
// 2. home.card.insight → compact scorecards on the home card
|
|
66
|
+
if (insights.collections) {
|
|
67
|
+
for (const [slug, defs] of Object.entries(insights.collections)) {
|
|
68
|
+
if (defs.length === 0) continue;
|
|
69
|
+
const collectionInsights = defs;
|
|
70
|
+
|
|
71
|
+
// 1. Inline in collection list view
|
|
72
|
+
slots.push({
|
|
73
|
+
slot: "collection.insights" as const,
|
|
74
|
+
Component: (props: Record<string, unknown>) => {
|
|
75
|
+
const path = props.path as string;
|
|
76
|
+
const collectionSlug = path?.split("/").filter(Boolean).pop() ?? "";
|
|
77
|
+
if (collectionSlug !== slug) return null;
|
|
78
|
+
return (
|
|
79
|
+
<CollectionInsightsInline
|
|
80
|
+
{...props as { path: string; collection: unknown; parentCollectionIds: string[] }}
|
|
81
|
+
insights={collectionInsights}
|
|
82
|
+
/>
|
|
83
|
+
);
|
|
84
|
+
},
|
|
85
|
+
order: 10,
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// 2. Auto-extract scorecards for home page card
|
|
89
|
+
slots.push({
|
|
90
|
+
slot: "home.card.insight" as const,
|
|
91
|
+
Component: (props: Record<string, unknown>) => {
|
|
92
|
+
const cardSlug = props.slug as string;
|
|
93
|
+
if (cardSlug !== slug) return null;
|
|
94
|
+
return (
|
|
95
|
+
<HomeCardInsightSlot
|
|
96
|
+
{...props as { slug: string; collection: unknown; context: unknown }}
|
|
97
|
+
insights={collectionInsights}
|
|
98
|
+
/>
|
|
99
|
+
);
|
|
100
|
+
},
|
|
101
|
+
order: 10,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
key: "plugin-insights",
|
|
108
|
+
slots,
|
|
109
|
+
providers: [
|
|
110
|
+
{
|
|
111
|
+
scope: "root" as const,
|
|
112
|
+
Component: InsightsProvider as React.ComponentType<React.PropsWithChildren<Record<string, unknown>>>,
|
|
113
|
+
props: { cacheTTL },
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
};
|
|
117
|
+
}
|