@rebasepro/plugin-insights 0.4.0 → 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/README.md +115 -0
- package/dist/{plugin-insights/src/components → components}/CollectionInsightsInline.d.ts +2 -1
- package/dist/{plugin-insights/src/components → components}/HomeCardInsightSlot.d.ts +3 -2
- package/dist/{plugin-insights/src/components → components}/HomeInsightsSlot.d.ts +3 -2
- package/dist/{plugin-insights/src/components → components}/InsightWidget.d.ts +3 -2
- package/dist/{plugin-insights/src/components → components}/InsightWidgetSkeleton.d.ts +3 -2
- package/dist/{plugin-insights/src/components → components}/InsightsScorecardView.d.ts +3 -2
- package/dist/{plugin-insights/src/engine → engine}/InsightsProvider.d.ts +2 -2
- package/dist/{plugin-insights/src/index.d.ts → index.d.ts} +1 -1
- package/dist/index.es.js +583 -1072
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +645 -1096
- package/dist/index.umd.js.map +1 -1
- package/package.json +19 -14
- package/src/components/CollectionInsightsInline.tsx +3 -3
- package/src/components/HomeCardInsightSlot.tsx +1 -1
- package/src/components/HomeInsightsSlot.tsx +1 -1
- package/src/components/InsightWidget.tsx +4 -2
- package/src/components/InsightWidgetSkeleton.tsx +21 -13
- package/src/components/InsightsScorecardView.tsx +2 -2
- package/src/engine/InsightsCache.test.ts +5 -3
- package/src/engine/InsightsCache.ts +3 -2
- package/src/engine/useInsightsData.ts +3 -1
- package/src/index.ts +1 -1
- package/src/useInsightsPlugin.tsx +68 -65
- package/dist/common/src/collections/CollectionRegistry.d.ts +0 -56
- package/dist/common/src/collections/default-collections.d.ts +0 -9
- package/dist/common/src/collections/index.d.ts +0 -2
- package/dist/common/src/data/buildRebaseData.d.ts +0 -14
- package/dist/common/src/data/query_builder.d.ts +0 -55
- package/dist/common/src/index.d.ts +0 -4
- package/dist/common/src/util/builders.d.ts +0 -57
- package/dist/common/src/util/callbacks.d.ts +0 -6
- package/dist/common/src/util/collections.d.ts +0 -11
- package/dist/common/src/util/common.d.ts +0 -2
- package/dist/common/src/util/conditions.d.ts +0 -26
- package/dist/common/src/util/entities.d.ts +0 -58
- package/dist/common/src/util/enums.d.ts +0 -3
- package/dist/common/src/util/index.d.ts +0 -16
- package/dist/common/src/util/navigation_from_path.d.ts +0 -34
- package/dist/common/src/util/navigation_utils.d.ts +0 -20
- package/dist/common/src/util/parent_references_from_path.d.ts +0 -6
- package/dist/common/src/util/paths.d.ts +0 -14
- package/dist/common/src/util/permissions.d.ts +0 -6
- package/dist/common/src/util/references.d.ts +0 -2
- package/dist/common/src/util/relations.d.ts +0 -22
- package/dist/common/src/util/resolutions.d.ts +0 -72
- package/dist/common/src/util/storage.d.ts +0 -24
- package/dist/core/src/components/AIIcon.d.ts +0 -16
- package/dist/core/src/components/BootstrapAdminBanner.d.ts +0 -4
- package/dist/core/src/components/ConfirmationDialog.d.ts +0 -9
- package/dist/core/src/components/Debug/UIReferenceView.d.ts +0 -1
- package/dist/core/src/components/Debug/UIStyleGuide.d.ts +0 -1
- package/dist/core/src/components/ErrorTooltip.d.ts +0 -2
- package/dist/core/src/components/ErrorView.d.ts +0 -21
- package/dist/core/src/components/LanguageToggle.d.ts +0 -1
- package/dist/core/src/components/LoginView/LoginView.d.ts +0 -109
- package/dist/core/src/components/LoginView/index.d.ts +0 -2
- package/dist/core/src/components/NotFoundPage.d.ts +0 -1
- package/dist/core/src/components/RebaseAuth.d.ts +0 -10
- package/dist/core/src/components/RebaseLogo.d.ts +0 -7
- package/dist/core/src/components/UnsavedChangesDialog.d.ts +0 -9
- package/dist/core/src/components/UserDisplay.d.ts +0 -7
- package/dist/core/src/components/UserSelectPopover.d.ts +0 -62
- package/dist/core/src/components/UserSettingsView.d.ts +0 -1
- package/dist/core/src/components/common/index.d.ts +0 -6
- package/dist/core/src/components/common/table_height.d.ts +0 -5
- package/dist/core/src/components/common/types.d.ts +0 -66
- package/dist/core/src/components/common/useColumnsIds.d.ts +0 -9
- package/dist/core/src/components/common/useDataTableController.d.ts +0 -45
- package/dist/core/src/components/common/useDebouncedData.d.ts +0 -9
- package/dist/core/src/components/common/useScrollRestoration.d.ts +0 -14
- package/dist/core/src/components/index.d.ts +0 -17
- package/dist/core/src/contexts/AdminModeController.d.ts +0 -4
- package/dist/core/src/contexts/AnalyticsContext.d.ts +0 -3
- package/dist/core/src/contexts/AuthControllerContext.d.ts +0 -3
- package/dist/core/src/contexts/CustomizationControllerContext.d.ts +0 -3
- package/dist/core/src/contexts/DataDriverContext.d.ts +0 -3
- package/dist/core/src/contexts/DatabaseAdminContext.d.ts +0 -3
- package/dist/core/src/contexts/DialogsProvider.d.ts +0 -4
- package/dist/core/src/contexts/EffectiveRoleController.d.ts +0 -4
- package/dist/core/src/contexts/InternalUserManagementContext.d.ts +0 -3
- package/dist/core/src/contexts/ModeController.d.ts +0 -4
- package/dist/core/src/contexts/RebaseClientInstanceContext.d.ts +0 -6
- package/dist/core/src/contexts/RebaseDataContext.d.ts +0 -3
- package/dist/core/src/contexts/SnackbarProvider.d.ts +0 -2
- package/dist/core/src/contexts/StorageSourceContext.d.ts +0 -3
- package/dist/core/src/contexts/UserConfigurationPersistenceContext.d.ts +0 -3
- package/dist/core/src/contexts/index.d.ts +0 -13
- package/dist/core/src/core/PluginLifecycleManager.d.ts +0 -17
- package/dist/core/src/core/PluginProviderStack.d.ts +0 -21
- package/dist/core/src/core/Rebase.d.ts +0 -14
- package/dist/core/src/core/RebaseProps.d.ts +0 -147
- package/dist/core/src/core/RebaseRouter.d.ts +0 -4
- package/dist/core/src/core/RebaseRoutes.d.ts +0 -17
- package/dist/core/src/core/index.d.ts +0 -4
- package/dist/core/src/hooks/ApiConfigContext.d.ts +0 -24
- package/dist/core/src/hooks/data/delete.d.ts +0 -31
- package/dist/core/src/hooks/data/save.d.ts +0 -34
- package/dist/core/src/hooks/data/useCollectionFetch.d.ts +0 -62
- package/dist/core/src/hooks/data/useData.d.ts +0 -13
- package/dist/core/src/hooks/data/useDataOrder.d.ts +0 -12
- package/dist/core/src/hooks/data/useEntityFetch.d.ts +0 -43
- package/dist/core/src/hooks/data/useRelationSelector.d.ts +0 -52
- package/dist/core/src/hooks/data/useUserSelector.d.ts +0 -31
- package/dist/core/src/hooks/index.d.ts +0 -37
- package/dist/core/src/hooks/useAdminModeController.d.ts +0 -19
- package/dist/core/src/hooks/useAnalyticsController.d.ts +0 -5
- package/dist/core/src/hooks/useAuthController.d.ts +0 -11
- package/dist/core/src/hooks/useAuthSubscription.d.ts +0 -2
- package/dist/core/src/hooks/useBackendStorageSource.d.ts +0 -30
- package/dist/core/src/hooks/useBridgeRegistration.d.ts +0 -18
- package/dist/core/src/hooks/useBrowserTitleAndIcon.d.ts +0 -6
- package/dist/core/src/hooks/useBuildAdminModeController.d.ts +0 -6
- package/dist/core/src/hooks/useBuildEffectiveRoleController.d.ts +0 -8
- package/dist/core/src/hooks/useBuildLocalConfigurationPersistence.d.ts +0 -2
- package/dist/core/src/hooks/useBuildModeController.d.ts +0 -6
- package/dist/core/src/hooks/useClipboard.d.ts +0 -57
- package/dist/core/src/hooks/useCollapsedGroups.d.ts +0 -27
- package/dist/core/src/hooks/useCustomizationController.d.ts +0 -11
- package/dist/core/src/hooks/useDialogsController.d.ts +0 -11
- package/dist/core/src/hooks/useEffectiveRoleController.d.ts +0 -7
- package/dist/core/src/hooks/useInternalUserManagementController.d.ts +0 -12
- package/dist/core/src/hooks/useLargeLayout.d.ts +0 -1
- package/dist/core/src/hooks/useModeController.d.ts +0 -19
- package/dist/core/src/hooks/usePermissions.d.ts +0 -12
- package/dist/core/src/hooks/useRebaseClient.d.ts +0 -5
- package/dist/core/src/hooks/useRebaseContext.d.ts +0 -11
- package/dist/core/src/hooks/useRebaseRegistry.d.ts +0 -34
- package/dist/core/src/hooks/useResolvedComponent.d.ts +0 -47
- package/dist/core/src/hooks/useSlot.d.ts +0 -18
- package/dist/core/src/hooks/useSnackbarController.d.ts +0 -20
- package/dist/core/src/hooks/useStorageSource.d.ts +0 -7
- package/dist/core/src/hooks/useStudioBridge.d.ts +0 -91
- package/dist/core/src/hooks/useTranslation.d.ts +0 -17
- package/dist/core/src/hooks/useUnsavedChangesDialog.d.ts +0 -12
- package/dist/core/src/hooks/useUserConfigurationPersistence.d.ts +0 -8
- package/dist/core/src/i18n/RebaseI18nProvider.d.ts +0 -33
- package/dist/core/src/index.d.ts +0 -15
- package/dist/core/src/internal/common.d.ts +0 -3
- package/dist/core/src/internal/useRestoreScroll.d.ts +0 -6
- package/dist/core/src/locales/de.d.ts +0 -2
- package/dist/core/src/locales/en.d.ts +0 -10
- package/dist/core/src/locales/es.d.ts +0 -10
- package/dist/core/src/locales/fr.d.ts +0 -2
- package/dist/core/src/locales/hi.d.ts +0 -2
- package/dist/core/src/locales/it.d.ts +0 -2
- package/dist/core/src/locales/pt.d.ts +0 -7
- package/dist/core/src/util/constants.d.ts +0 -1
- package/dist/core/src/util/createFormexStub.d.ts +0 -2
- package/dist/core/src/util/entity_cache.d.ts +0 -22
- package/dist/core/src/util/enums.d.ts +0 -5
- package/dist/core/src/util/icon_list.d.ts +0 -5
- package/dist/core/src/util/icons.d.ts +0 -20
- package/dist/core/src/util/index.d.ts +0 -8
- package/dist/core/src/util/previews.d.ts +0 -4
- package/dist/core/src/util/useStorageUploadController.d.ts +0 -38
- package/dist/formex/src/Field.d.ts +0 -52
- package/dist/formex/src/Formex.d.ts +0 -7
- package/dist/formex/src/index.d.ts +0 -5
- package/dist/formex/src/types.d.ts +0 -40
- package/dist/formex/src/useCreateFormex.d.ts +0 -14
- package/dist/formex/src/utils.d.ts +0 -16
- package/dist/types/src/controllers/analytics_controller.d.ts +0 -7
- package/dist/types/src/controllers/auth.d.ts +0 -104
- package/dist/types/src/controllers/client.d.ts +0 -168
- package/dist/types/src/controllers/collection_registry.d.ts +0 -46
- package/dist/types/src/controllers/customization_controller.d.ts +0 -60
- package/dist/types/src/controllers/data.d.ts +0 -207
- package/dist/types/src/controllers/data_driver.d.ts +0 -218
- package/dist/types/src/controllers/database_admin.d.ts +0 -11
- package/dist/types/src/controllers/dialogs_controller.d.ts +0 -36
- package/dist/types/src/controllers/effective_role.d.ts +0 -4
- package/dist/types/src/controllers/email.d.ts +0 -36
- package/dist/types/src/controllers/index.d.ts +0 -18
- package/dist/types/src/controllers/local_config_persistence.d.ts +0 -20
- package/dist/types/src/controllers/navigation.d.ts +0 -225
- package/dist/types/src/controllers/registry.d.ts +0 -63
- package/dist/types/src/controllers/side_dialogs_controller.d.ts +0 -67
- package/dist/types/src/controllers/side_entity_controller.d.ts +0 -97
- package/dist/types/src/controllers/snackbar.d.ts +0 -24
- package/dist/types/src/controllers/storage.d.ts +0 -171
- package/dist/types/src/index.d.ts +0 -4
- package/dist/types/src/rebase_context.d.ts +0 -122
- package/dist/types/src/types/auth_adapter.d.ts +0 -301
- package/dist/types/src/types/backend.d.ts +0 -536
- package/dist/types/src/types/backend_hooks.d.ts +0 -172
- package/dist/types/src/types/builders.d.ts +0 -15
- package/dist/types/src/types/chips.d.ts +0 -5
- package/dist/types/src/types/collections.d.ts +0 -941
- package/dist/types/src/types/component_ref.d.ts +0 -47
- package/dist/types/src/types/cron.d.ts +0 -102
- package/dist/types/src/types/data_source.d.ts +0 -64
- package/dist/types/src/types/database_adapter.d.ts +0 -94
- package/dist/types/src/types/entities.d.ts +0 -145
- package/dist/types/src/types/entity_actions.d.ts +0 -104
- package/dist/types/src/types/entity_callbacks.d.ts +0 -173
- package/dist/types/src/types/entity_link_builder.d.ts +0 -7
- package/dist/types/src/types/entity_overrides.d.ts +0 -10
- package/dist/types/src/types/entity_views.d.ts +0 -87
- package/dist/types/src/types/export_import.d.ts +0 -21
- package/dist/types/src/types/formex.d.ts +0 -40
- package/dist/types/src/types/index.d.ts +0 -28
- package/dist/types/src/types/locales.d.ts +0 -4
- package/dist/types/src/types/modify_collections.d.ts +0 -5
- package/dist/types/src/types/plugins.d.ts +0 -282
- package/dist/types/src/types/properties.d.ts +0 -1181
- package/dist/types/src/types/property_config.d.ts +0 -74
- package/dist/types/src/types/relations.d.ts +0 -336
- package/dist/types/src/types/slots.d.ts +0 -262
- package/dist/types/src/types/translations.d.ts +0 -900
- package/dist/types/src/types/user_management_delegate.d.ts +0 -86
- package/dist/types/src/types/websockets.d.ts +0 -78
- package/dist/types/src/users/index.d.ts +0 -1
- package/dist/types/src/users/user.d.ts +0 -50
- package/dist/ui/src/components/Alert.d.ts +0 -12
- package/dist/ui/src/components/Autocomplete.d.ts +0 -21
- package/dist/ui/src/components/Avatar.d.ts +0 -11
- package/dist/ui/src/components/Badge.d.ts +0 -8
- package/dist/ui/src/components/BooleanSwitch.d.ts +0 -14
- package/dist/ui/src/components/BooleanSwitchWithLabel.d.ts +0 -17
- package/dist/ui/src/components/Button.d.ts +0 -14
- package/dist/ui/src/components/Card.d.ts +0 -8
- package/dist/ui/src/components/CenteredView.d.ts +0 -9
- package/dist/ui/src/components/Checkbox.d.ts +0 -13
- package/dist/ui/src/components/Chip.d.ts +0 -26
- package/dist/ui/src/components/CircularProgress.d.ts +0 -5
- package/dist/ui/src/components/CircularProgressCenter.d.ts +0 -11
- package/dist/ui/src/components/Collapse.d.ts +0 -9
- package/dist/ui/src/components/ColorPicker.d.ts +0 -30
- package/dist/ui/src/components/Container.d.ts +0 -8
- package/dist/ui/src/components/DateTimeField.d.ts +0 -24
- package/dist/ui/src/components/DebouncedTextField.d.ts +0 -2
- package/dist/ui/src/components/Dialog.d.ts +0 -39
- package/dist/ui/src/components/DialogActions.d.ts +0 -7
- package/dist/ui/src/components/DialogContent.d.ts +0 -7
- package/dist/ui/src/components/DialogTitle.d.ts +0 -10
- package/dist/ui/src/components/ErrorBoundary.d.ts +0 -33
- package/dist/ui/src/components/ExpandablePanel.d.ts +0 -12
- package/dist/ui/src/components/FileUpload.d.ts +0 -23
- package/dist/ui/src/components/FilterChip.d.ts +0 -34
- package/dist/ui/src/components/IconButton.d.ts +0 -12
- package/dist/ui/src/components/InfoLabel.d.ts +0 -5
- package/dist/ui/src/components/InputLabel.d.ts +0 -11
- package/dist/ui/src/components/Label.d.ts +0 -7
- package/dist/ui/src/components/LoadingButton.d.ts +0 -7
- package/dist/ui/src/components/Markdown.d.ts +0 -10
- package/dist/ui/src/components/Menu.d.ts +0 -23
- package/dist/ui/src/components/Menubar.d.ts +0 -80
- package/dist/ui/src/components/MultiSelect.d.ts +0 -48
- package/dist/ui/src/components/Paper.d.ts +0 -6
- package/dist/ui/src/components/Popover.d.ts +0 -24
- package/dist/ui/src/components/RadioGroup.d.ts +0 -28
- package/dist/ui/src/components/ResizablePanels.d.ts +0 -18
- package/dist/ui/src/components/SearchBar.d.ts +0 -26
- package/dist/ui/src/components/Select.d.ts +0 -43
- package/dist/ui/src/components/Separator.d.ts +0 -5
- package/dist/ui/src/components/Sheet.d.ts +0 -22
- package/dist/ui/src/components/Skeleton.d.ts +0 -6
- package/dist/ui/src/components/Slider.d.ts +0 -21
- package/dist/ui/src/components/Table.d.ts +0 -34
- package/dist/ui/src/components/Tabs.d.ts +0 -19
- package/dist/ui/src/components/TextField.d.ts +0 -58
- package/dist/ui/src/components/TextareaAutosize.d.ts +0 -43
- package/dist/ui/src/components/ToggleButtonGroup.d.ts +0 -30
- package/dist/ui/src/components/Tooltip.d.ts +0 -19
- package/dist/ui/src/components/Typography.d.ts +0 -36
- package/dist/ui/src/components/VirtualTable/VirtualTable.d.ts +0 -11
- package/dist/ui/src/components/VirtualTable/VirtualTableCell.d.ts +0 -21
- package/dist/ui/src/components/VirtualTable/VirtualTableHeader.d.ts +0 -29
- package/dist/ui/src/components/VirtualTable/VirtualTableHeaderRow.d.ts +0 -2
- package/dist/ui/src/components/VirtualTable/VirtualTableProps.d.ts +0 -249
- package/dist/ui/src/components/VirtualTable/VirtualTableRow.d.ts +0 -3
- package/dist/ui/src/components/VirtualTable/index.d.ts +0 -3
- package/dist/ui/src/components/VirtualTable/types.d.ts +0 -38
- package/dist/ui/src/components/common/SelectInputLabel.d.ts +0 -5
- package/dist/ui/src/components/index.d.ts +0 -58
- package/dist/ui/src/hooks/PortalContainerContext.d.ts +0 -31
- package/dist/ui/src/hooks/index.d.ts +0 -6
- package/dist/ui/src/hooks/useDebounceCallback.d.ts +0 -1
- package/dist/ui/src/hooks/useDebounceValue.d.ts +0 -1
- package/dist/ui/src/hooks/useDebouncedCallback.d.ts +0 -1
- package/dist/ui/src/hooks/useInjectStyles.d.ts +0 -7
- package/dist/ui/src/hooks/useOutsideAlerter.d.ts +0 -5
- package/dist/ui/src/icons/GitHubIcon.d.ts +0 -2
- package/dist/ui/src/icons/HandleIcon.d.ts +0 -1
- package/dist/ui/src/icons/Icon.d.ts +0 -20
- package/dist/ui/src/icons/cool_icon_keys.d.ts +0 -1
- package/dist/ui/src/icons/icon_keys.d.ts +0 -1
- package/dist/ui/src/icons/index.d.ts +0 -8
- package/dist/ui/src/index.d.ts +0 -5
- package/dist/ui/src/styles.d.ts +0 -12
- package/dist/ui/src/util/chip_colors.d.ts +0 -4
- package/dist/ui/src/util/cls.d.ts +0 -2
- package/dist/ui/src/util/debounce.d.ts +0 -10
- package/dist/ui/src/util/hash.d.ts +0 -1
- package/dist/ui/src/util/index.d.ts +0 -4
- package/dist/ui/src/util/key_to_icon_component.d.ts +0 -1
- /package/dist/{plugin-insights/src/engine → engine}/InsightsCache.d.ts +0 -0
- /package/dist/{plugin-insights/src/engine → engine}/useInsightsData.d.ts +0 -0
- /package/dist/{plugin-insights/src/types → types}/engine.d.ts +0 -0
- /package/dist/{plugin-insights/src/types → types}/index.d.ts +0 -0
- /package/dist/{plugin-insights/src/types → types}/widgets.d.ts +0 -0
- /package/dist/{plugin-insights/src/useInsightsPlugin.d.ts → useInsightsPlugin.d.ts} +0 -0
package/dist/index.es.js
CHANGED
|
@@ -1,1098 +1,609 @@
|
|
|
1
|
+
import React, { createContext, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
1
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import React, { createContext, useContext, useState, useEffect, useRef } from "react";
|
|
4
|
-
import { useAuthController, getIcon } from "@rebasepro/core";
|
|
3
|
+
import { getIcon, useAuthController } from "@rebasepro/core";
|
|
5
4
|
import { cls, defaultBorderMixin } from "@rebasepro/ui";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
$[2] = cache;
|
|
70
|
-
$[3] = t4;
|
|
71
|
-
} else {
|
|
72
|
-
t4 = $[3];
|
|
73
|
-
}
|
|
74
|
-
t3 = t4;
|
|
75
|
-
const value = t3;
|
|
76
|
-
let t5;
|
|
77
|
-
if ($[4] !== children || $[5] !== value) {
|
|
78
|
-
t5 = /* @__PURE__ */ jsx(InsightsContext.Provider, { value, children });
|
|
79
|
-
$[4] = children;
|
|
80
|
-
$[5] = value;
|
|
81
|
-
$[6] = t5;
|
|
82
|
-
} else {
|
|
83
|
-
t5 = $[6];
|
|
84
|
-
}
|
|
85
|
-
return t5;
|
|
5
|
+
//#region src/engine/InsightsCache.ts
|
|
6
|
+
/**
|
|
7
|
+
* In-memory cache for insight query results.
|
|
8
|
+
* Supports TTL-based expiry and inflight request deduplication
|
|
9
|
+
* to prevent redundant network requests when multiple widgets
|
|
10
|
+
* share the same query.
|
|
11
|
+
*/
|
|
12
|
+
var InsightsCache = class {
|
|
13
|
+
ttl;
|
|
14
|
+
cache = /* @__PURE__ */ new Map();
|
|
15
|
+
inflight = /* @__PURE__ */ new Map();
|
|
16
|
+
constructor(ttl = 6e4) {
|
|
17
|
+
this.ttl = ttl;
|
|
18
|
+
}
|
|
19
|
+
get(key) {
|
|
20
|
+
const entry = this.cache.get(key);
|
|
21
|
+
if (!entry) return null;
|
|
22
|
+
if (Date.now() - entry.timestamp > this.ttl) {
|
|
23
|
+
this.cache.delete(key);
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
return entry.data;
|
|
27
|
+
}
|
|
28
|
+
set(key, data) {
|
|
29
|
+
this.cache.set(key, {
|
|
30
|
+
data,
|
|
31
|
+
timestamp: Date.now()
|
|
32
|
+
});
|
|
33
|
+
this.inflight.delete(key);
|
|
34
|
+
}
|
|
35
|
+
getInflight(key) {
|
|
36
|
+
return this.inflight.get(key) ?? null;
|
|
37
|
+
}
|
|
38
|
+
setInflight(key, promise) {
|
|
39
|
+
this.inflight.set(key, promise);
|
|
40
|
+
}
|
|
41
|
+
invalidate(key) {
|
|
42
|
+
if (key) {
|
|
43
|
+
this.cache.delete(key);
|
|
44
|
+
this.inflight.delete(key);
|
|
45
|
+
} else {
|
|
46
|
+
this.cache.clear();
|
|
47
|
+
this.inflight.clear();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region src/engine/InsightsProvider.tsx
|
|
53
|
+
var InsightsContext = createContext(null);
|
|
54
|
+
/**
|
|
55
|
+
* Root-level provider for the insights data engine.
|
|
56
|
+
* Injected automatically by the plugin via `providers: [{ scope: "root" }]`.
|
|
57
|
+
*
|
|
58
|
+
* Manages a single `InsightsCache` instance shared by all insight widgets
|
|
59
|
+
* for TTL-based caching and inflight request deduplication.
|
|
60
|
+
*/
|
|
61
|
+
function InsightsProvider({ cacheTTL, children }) {
|
|
62
|
+
const cache = useMemo(() => new InsightsCache(cacheTTL), [cacheTTL]);
|
|
63
|
+
const value = useMemo(() => ({ cache }), [cache]);
|
|
64
|
+
return /* @__PURE__ */ jsx(InsightsContext.Provider, {
|
|
65
|
+
value,
|
|
66
|
+
children
|
|
67
|
+
});
|
|
86
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Access the insights cache (for advanced usage).
|
|
71
|
+
* Returns null when called outside of an `InsightsProvider`
|
|
72
|
+
* (e.g. during auth-loading phase before plugin providers mount).
|
|
73
|
+
*/
|
|
87
74
|
function useInsightsEngine() {
|
|
88
|
-
|
|
75
|
+
return useContext(InsightsContext);
|
|
89
76
|
}
|
|
77
|
+
//#endregion
|
|
78
|
+
//#region src/engine/useInsightsData.ts
|
|
79
|
+
/**
|
|
80
|
+
* Hook that fetches and caches data for a single insight definition.
|
|
81
|
+
*
|
|
82
|
+
* Calls the definition's own `data()` callback and manages:
|
|
83
|
+
* - TTL-based caching via InsightsCache
|
|
84
|
+
* - Inflight request deduplication (multiple mounts of the same widget)
|
|
85
|
+
* - Loading and error state management
|
|
86
|
+
*
|
|
87
|
+
* @param definition - The insight to fetch data for
|
|
88
|
+
* @param collectionSlug - Optional collection context for cache key scoping
|
|
89
|
+
*/
|
|
90
90
|
function useInsightsData(definition, context) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
setError(err_0 instanceof Error ? err_0 : new Error(String(err_0)));
|
|
150
|
-
}
|
|
151
|
-
}).finally(() => {
|
|
152
|
-
if (!cancelled) {
|
|
153
|
-
setLoading(false);
|
|
154
|
-
}
|
|
155
|
-
});
|
|
156
|
-
return () => {
|
|
157
|
-
cancelled = true;
|
|
158
|
-
};
|
|
159
|
-
};
|
|
160
|
-
$[0] = authReady;
|
|
161
|
-
$[1] = cache;
|
|
162
|
-
$[2] = cacheKey;
|
|
163
|
-
$[3] = context;
|
|
164
|
-
$[4] = definition;
|
|
165
|
-
$[5] = t0;
|
|
166
|
-
} else {
|
|
167
|
-
t0 = $[5];
|
|
168
|
-
}
|
|
169
|
-
let t1;
|
|
170
|
-
if ($[6] !== authReady || $[7] !== cache || $[8] !== cacheKey || $[9] !== context.collectionSlug || $[10] !== context.path || $[11] !== definition.data || $[12] !== definition.id) {
|
|
171
|
-
t1 = [definition.id, definition.data, context.path, context.collectionSlug, cacheKey, cache, authReady];
|
|
172
|
-
$[6] = authReady;
|
|
173
|
-
$[7] = cache;
|
|
174
|
-
$[8] = cacheKey;
|
|
175
|
-
$[9] = context.collectionSlug;
|
|
176
|
-
$[10] = context.path;
|
|
177
|
-
$[11] = definition.data;
|
|
178
|
-
$[12] = definition.id;
|
|
179
|
-
$[13] = t1;
|
|
180
|
-
} else {
|
|
181
|
-
t1 = $[13];
|
|
182
|
-
}
|
|
183
|
-
useEffect(t0, t1);
|
|
184
|
-
let t2;
|
|
185
|
-
if ($[14] !== data || $[15] !== error || $[16] !== loading) {
|
|
186
|
-
t2 = {
|
|
187
|
-
data,
|
|
188
|
-
loading,
|
|
189
|
-
error
|
|
190
|
-
};
|
|
191
|
-
$[14] = data;
|
|
192
|
-
$[15] = error;
|
|
193
|
-
$[16] = loading;
|
|
194
|
-
$[17] = t2;
|
|
195
|
-
} else {
|
|
196
|
-
t2 = $[17];
|
|
197
|
-
}
|
|
198
|
-
return t2;
|
|
91
|
+
const cache = useInsightsEngine()?.cache ?? null;
|
|
92
|
+
const { initialLoading, authLoading, user, loginSkipped } = useAuthController();
|
|
93
|
+
const authReady = !initialLoading && !authLoading && (Boolean(user) || loginSkipped);
|
|
94
|
+
const [data, setData] = useState(null);
|
|
95
|
+
const [loading, setLoading] = useState(true);
|
|
96
|
+
const [error, setError] = useState(null);
|
|
97
|
+
const cacheKey = `${definition.id}:${context.path ?? context.collectionSlug ?? "global"}`;
|
|
98
|
+
useEffect(() => {
|
|
99
|
+
if (!authReady || !cache) return;
|
|
100
|
+
let cancelled = false;
|
|
101
|
+
const cached = cache.get(cacheKey);
|
|
102
|
+
if (cached) {
|
|
103
|
+
setData(cached);
|
|
104
|
+
setLoading(false);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const inflight = cache.getInflight(cacheKey);
|
|
108
|
+
if (inflight) {
|
|
109
|
+
setLoading(true);
|
|
110
|
+
inflight.then((result) => {
|
|
111
|
+
if (!cancelled) setData(result);
|
|
112
|
+
}).catch((err) => {
|
|
113
|
+
if (!cancelled) setError(err instanceof Error ? err : new Error(String(err)));
|
|
114
|
+
}).finally(() => {
|
|
115
|
+
if (!cancelled) setLoading(false);
|
|
116
|
+
});
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
setLoading(true);
|
|
120
|
+
setError(null);
|
|
121
|
+
const promise = definition.data(context);
|
|
122
|
+
cache.setInflight(cacheKey, promise);
|
|
123
|
+
promise.then((result) => {
|
|
124
|
+
cache.set(cacheKey, result);
|
|
125
|
+
if (!cancelled) setData(result);
|
|
126
|
+
}).catch((err) => {
|
|
127
|
+
cache.invalidate(cacheKey);
|
|
128
|
+
if (!cancelled) setError(err instanceof Error ? err : new Error(String(err)));
|
|
129
|
+
}).finally(() => {
|
|
130
|
+
if (!cancelled) setLoading(false);
|
|
131
|
+
});
|
|
132
|
+
return () => {
|
|
133
|
+
cancelled = true;
|
|
134
|
+
};
|
|
135
|
+
}, [
|
|
136
|
+
definition.id,
|
|
137
|
+
definition.data,
|
|
138
|
+
context.path,
|
|
139
|
+
context.collectionSlug,
|
|
140
|
+
cacheKey,
|
|
141
|
+
cache,
|
|
142
|
+
authReady
|
|
143
|
+
]);
|
|
144
|
+
return {
|
|
145
|
+
data,
|
|
146
|
+
loading,
|
|
147
|
+
error
|
|
148
|
+
};
|
|
199
149
|
}
|
|
150
|
+
//#endregion
|
|
151
|
+
//#region src/components/InsightsScorecardView.tsx
|
|
200
152
|
function formatNumber(value, format) {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
if (format?.showSign && value > 0) {
|
|
213
|
-
formatted = "+" + formatted;
|
|
214
|
-
}
|
|
215
|
-
return formatted;
|
|
153
|
+
if (value === null || value === void 0) return "N/A";
|
|
154
|
+
const options = {
|
|
155
|
+
style: format?.style ?? "decimal",
|
|
156
|
+
notation: format?.notation ?? "standard",
|
|
157
|
+
maximumFractionDigits: format?.decimals ?? 1,
|
|
158
|
+
minimumFractionDigits: format?.decimals ?? 1
|
|
159
|
+
};
|
|
160
|
+
if (format?.style === "currency") options.currency = format.currency ?? "USD";
|
|
161
|
+
let formatted = new Intl.NumberFormat("en-US", options).format(value);
|
|
162
|
+
if (format?.showSign && value > 0) formatted = "+" + formatted;
|
|
163
|
+
return formatted;
|
|
216
164
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
$[9] = t72;
|
|
306
|
-
$[10] = t82;
|
|
307
|
-
} else {
|
|
308
|
-
t82 = $[10];
|
|
309
|
-
}
|
|
310
|
-
comparisonElement = t82;
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
const isSmall = compact || containerWidth !== null && containerWidth < 200;
|
|
314
|
-
let t6;
|
|
315
|
-
if ($[11] !== config.icon || $[12] !== isSmall) {
|
|
316
|
-
t6 = config.icon ? getIcon(config.icon, "text-surface-400 dark:text-surface-500", void 0, isSmall ? 14 : 18) : null;
|
|
317
|
-
$[11] = config.icon;
|
|
318
|
-
$[12] = isSmall;
|
|
319
|
-
$[13] = t6;
|
|
320
|
-
} else {
|
|
321
|
-
t6 = $[13];
|
|
322
|
-
}
|
|
323
|
-
const iconElement = t6;
|
|
324
|
-
if (compact) {
|
|
325
|
-
let t72;
|
|
326
|
-
if ($[14] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
|
|
327
|
-
t72 = cls("flex flex-col gap-0.5 px-2.5 py-2 rounded-md bg-transparent border min-w-0", defaultBorderMixin);
|
|
328
|
-
$[14] = t72;
|
|
329
|
-
} else {
|
|
330
|
-
t72 = $[14];
|
|
331
|
-
}
|
|
332
|
-
let t82;
|
|
333
|
-
if ($[15] !== title) {
|
|
334
|
-
t82 = /* @__PURE__ */ jsx("span", { className: "text-[10px] uppercase tracking-wider text-surface-400 dark:text-surface-500 truncate", children: title });
|
|
335
|
-
$[15] = title;
|
|
336
|
-
$[16] = t82;
|
|
337
|
-
} else {
|
|
338
|
-
t82 = $[16];
|
|
339
|
-
}
|
|
340
|
-
let t92;
|
|
341
|
-
if ($[17] !== formattedValue) {
|
|
342
|
-
t92 = /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold tabular-nums text-surface-800 dark:text-surface-100", children: formattedValue });
|
|
343
|
-
$[17] = formattedValue;
|
|
344
|
-
$[18] = t92;
|
|
345
|
-
} else {
|
|
346
|
-
t92 = $[18];
|
|
347
|
-
}
|
|
348
|
-
let t102;
|
|
349
|
-
if ($[19] !== comparisonElement || $[20] !== t92) {
|
|
350
|
-
t102 = /* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-1.5", children: [
|
|
351
|
-
t92,
|
|
352
|
-
comparisonElement
|
|
353
|
-
] });
|
|
354
|
-
$[19] = comparisonElement;
|
|
355
|
-
$[20] = t92;
|
|
356
|
-
$[21] = t102;
|
|
357
|
-
} else {
|
|
358
|
-
t102 = $[21];
|
|
359
|
-
}
|
|
360
|
-
let t112;
|
|
361
|
-
if ($[22] !== t102 || $[23] !== t82) {
|
|
362
|
-
t112 = /* @__PURE__ */ jsxs("div", { className: t72, children: [
|
|
363
|
-
t82,
|
|
364
|
-
t102
|
|
365
|
-
] });
|
|
366
|
-
$[22] = t102;
|
|
367
|
-
$[23] = t82;
|
|
368
|
-
$[24] = t112;
|
|
369
|
-
} else {
|
|
370
|
-
t112 = $[24];
|
|
371
|
-
}
|
|
372
|
-
return t112;
|
|
373
|
-
}
|
|
374
|
-
let t7;
|
|
375
|
-
if ($[25] !== embedded || $[26] !== isSmall) {
|
|
376
|
-
t7 = embedded ? `flex flex-col min-w-0 h-full ${isSmall ? "px-3.5 py-3" : "px-5 py-4"}` : cls("rounded-lg flex flex-col min-w-0 bg-transparent border", defaultBorderMixin, isSmall ? "px-3.5 py-3" : "px-5 py-4");
|
|
377
|
-
$[25] = embedded;
|
|
378
|
-
$[26] = isSmall;
|
|
379
|
-
$[27] = t7;
|
|
380
|
-
} else {
|
|
381
|
-
t7 = $[27];
|
|
382
|
-
}
|
|
383
|
-
const baseClass = t7;
|
|
384
|
-
let t8;
|
|
385
|
-
if ($[28] !== embedded || $[29] !== fixedHeight || $[30] !== isSmall) {
|
|
386
|
-
t8 = embedded ? void 0 : fixedHeight ? {
|
|
387
|
-
height: fixedHeight
|
|
388
|
-
} : {
|
|
389
|
-
minHeight: isSmall ? 68 : 92
|
|
390
|
-
};
|
|
391
|
-
$[28] = embedded;
|
|
392
|
-
$[29] = fixedHeight;
|
|
393
|
-
$[30] = isSmall;
|
|
394
|
-
$[31] = t8;
|
|
395
|
-
} else {
|
|
396
|
-
t8 = $[31];
|
|
397
|
-
}
|
|
398
|
-
const t9 = `flex items-center justify-between ${isSmall ? "mb-1" : "mb-2"}`;
|
|
399
|
-
const t10 = `font-medium leading-snug truncate text-surface-500 dark:text-surface-400 ${isSmall ? "text-[11px]" : "text-xs"}`;
|
|
400
|
-
let t11;
|
|
401
|
-
if ($[32] !== t10 || $[33] !== title) {
|
|
402
|
-
t11 = /* @__PURE__ */ jsx("span", { className: t10, children: title });
|
|
403
|
-
$[32] = t10;
|
|
404
|
-
$[33] = title;
|
|
405
|
-
$[34] = t11;
|
|
406
|
-
} else {
|
|
407
|
-
t11 = $[34];
|
|
408
|
-
}
|
|
409
|
-
let t12;
|
|
410
|
-
if ($[35] !== config.dateRange || $[36] !== isSmall) {
|
|
411
|
-
t12 = config.dateRange && !isSmall && /* @__PURE__ */ jsx("span", { className: "text-[10px] text-surface-400 dark:text-surface-500 truncate mt-0.5", children: config.dateRange });
|
|
412
|
-
$[35] = config.dateRange;
|
|
413
|
-
$[36] = isSmall;
|
|
414
|
-
$[37] = t12;
|
|
415
|
-
} else {
|
|
416
|
-
t12 = $[37];
|
|
417
|
-
}
|
|
418
|
-
let t13;
|
|
419
|
-
if ($[38] !== t11 || $[39] !== t12) {
|
|
420
|
-
t13 = /* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0", children: [
|
|
421
|
-
t11,
|
|
422
|
-
t12
|
|
423
|
-
] });
|
|
424
|
-
$[38] = t11;
|
|
425
|
-
$[39] = t12;
|
|
426
|
-
$[40] = t13;
|
|
427
|
-
} else {
|
|
428
|
-
t13 = $[40];
|
|
429
|
-
}
|
|
430
|
-
let t14;
|
|
431
|
-
if ($[41] !== iconElement) {
|
|
432
|
-
t14 = iconElement && /* @__PURE__ */ jsx("span", { className: "ml-2 shrink-0", children: iconElement });
|
|
433
|
-
$[41] = iconElement;
|
|
434
|
-
$[42] = t14;
|
|
435
|
-
} else {
|
|
436
|
-
t14 = $[42];
|
|
437
|
-
}
|
|
438
|
-
let t15;
|
|
439
|
-
if ($[43] !== t13 || $[44] !== t14 || $[45] !== t9) {
|
|
440
|
-
t15 = /* @__PURE__ */ jsxs("div", { className: t9, children: [
|
|
441
|
-
t13,
|
|
442
|
-
t14
|
|
443
|
-
] });
|
|
444
|
-
$[43] = t13;
|
|
445
|
-
$[44] = t14;
|
|
446
|
-
$[45] = t9;
|
|
447
|
-
$[46] = t15;
|
|
448
|
-
} else {
|
|
449
|
-
t15 = $[46];
|
|
450
|
-
}
|
|
451
|
-
const t16 = `font-semibold leading-tight tracking-tight break-all text-surface-800 dark:text-surface-100 ${isSmall ? "text-lg" : containerWidth !== null && containerWidth < 300 ? "text-xl" : "text-2xl"}`;
|
|
452
|
-
let t17;
|
|
453
|
-
if ($[47] !== formattedValue || $[48] !== t16) {
|
|
454
|
-
t17 = /* @__PURE__ */ jsx("div", { className: t16, children: formattedValue });
|
|
455
|
-
$[47] = formattedValue;
|
|
456
|
-
$[48] = t16;
|
|
457
|
-
$[49] = t17;
|
|
458
|
-
} else {
|
|
459
|
-
t17 = $[49];
|
|
460
|
-
}
|
|
461
|
-
let t18;
|
|
462
|
-
if ($[50] !== comparisonElement || $[51] !== isSmall) {
|
|
463
|
-
t18 = comparisonElement && /* @__PURE__ */ jsx("div", { className: isSmall ? "mt-0.5" : "mt-1", children: comparisonElement });
|
|
464
|
-
$[50] = comparisonElement;
|
|
465
|
-
$[51] = isSmall;
|
|
466
|
-
$[52] = t18;
|
|
467
|
-
} else {
|
|
468
|
-
t18 = $[52];
|
|
469
|
-
}
|
|
470
|
-
let t19;
|
|
471
|
-
if ($[53] !== baseClass || $[54] !== t15 || $[55] !== t17 || $[56] !== t18 || $[57] !== t8) {
|
|
472
|
-
t19 = /* @__PURE__ */ jsxs("div", { ref: containerRef, className: baseClass, style: t8, children: [
|
|
473
|
-
t15,
|
|
474
|
-
t17,
|
|
475
|
-
t18
|
|
476
|
-
] });
|
|
477
|
-
$[53] = baseClass;
|
|
478
|
-
$[54] = t15;
|
|
479
|
-
$[55] = t17;
|
|
480
|
-
$[56] = t18;
|
|
481
|
-
$[57] = t8;
|
|
482
|
-
$[58] = t19;
|
|
483
|
-
} else {
|
|
484
|
-
t19 = $[58];
|
|
485
|
-
}
|
|
486
|
-
return t19;
|
|
165
|
+
/**
|
|
166
|
+
* Scorecard widget for the Rebase design system.
|
|
167
|
+
*
|
|
168
|
+
* Renders a single KPI metric with optional comparison value and icon.
|
|
169
|
+
* Uses Tailwind `dark:` classes — no JS dark mode detection.
|
|
170
|
+
* Icons are resolved via `getIcon` from `@rebasepro/core`.
|
|
171
|
+
*/
|
|
172
|
+
function InsightsScorecardView({ config, data, title, compact = false, embedded = false, fixedHeight }) {
|
|
173
|
+
const containerRef = useRef(null);
|
|
174
|
+
const [containerWidth, setContainerWidth] = useState(null);
|
|
175
|
+
React.useLayoutEffect(() => {
|
|
176
|
+
if (!containerRef.current) return;
|
|
177
|
+
setContainerWidth(containerRef.current.offsetWidth);
|
|
178
|
+
const observer = new ResizeObserver((entries) => {
|
|
179
|
+
for (const entry of entries) setContainerWidth(entry.contentRect.width);
|
|
180
|
+
});
|
|
181
|
+
observer.observe(containerRef.current);
|
|
182
|
+
return () => observer.disconnect();
|
|
183
|
+
}, []);
|
|
184
|
+
const mainValue = data[config.value.field];
|
|
185
|
+
const formattedValue = typeof mainValue === "number" ? formatNumber(mainValue, config.value.format) : String(mainValue ?? "N/A");
|
|
186
|
+
let comparisonElement = null;
|
|
187
|
+
if (config.comparison) {
|
|
188
|
+
const comparisonValue = data[config.comparison.field];
|
|
189
|
+
if (typeof comparisonValue === "number") {
|
|
190
|
+
const formattedComparison = formatNumber(comparisonValue, config.comparison.format);
|
|
191
|
+
const isPositive = comparisonValue > 0;
|
|
192
|
+
const isNegative = comparisonValue < 0;
|
|
193
|
+
let colorClass = "text-surface-500 dark:text-surface-400";
|
|
194
|
+
if (config.comparison.intent === "increase_is_good") {
|
|
195
|
+
if (isPositive) colorClass = "text-emerald-500";
|
|
196
|
+
if (isNegative) colorClass = "text-red-500";
|
|
197
|
+
} else if (config.comparison.intent === "decrease_is_good") {
|
|
198
|
+
if (isPositive) colorClass = "text-red-500";
|
|
199
|
+
if (isNegative) colorClass = "text-emerald-500";
|
|
200
|
+
}
|
|
201
|
+
comparisonElement = /* @__PURE__ */ jsx("span", {
|
|
202
|
+
className: `font-medium ${compact ? "text-[10px]" : "text-xs"} ${colorClass}`,
|
|
203
|
+
children: formattedComparison
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
const isSmall = compact || containerWidth !== null && containerWidth < 200;
|
|
208
|
+
const iconElement = config.icon ? getIcon(config.icon, "text-surface-400 dark:text-surface-500", void 0, isSmall ? 14 : 18) : null;
|
|
209
|
+
if (compact) return /* @__PURE__ */ jsxs("div", {
|
|
210
|
+
className: cls("flex flex-col gap-0.5 px-2.5 py-2 rounded-md bg-transparent border min-w-0", defaultBorderMixin),
|
|
211
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
212
|
+
className: "text-[10px] uppercase tracking-wider text-surface-400 dark:text-surface-500 truncate",
|
|
213
|
+
children: title
|
|
214
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
215
|
+
className: "flex items-baseline gap-1.5",
|
|
216
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
217
|
+
className: "text-sm font-semibold tabular-nums text-surface-800 dark:text-surface-100",
|
|
218
|
+
children: formattedValue
|
|
219
|
+
}), comparisonElement]
|
|
220
|
+
})]
|
|
221
|
+
});
|
|
222
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
223
|
+
ref: containerRef,
|
|
224
|
+
className: embedded ? `flex flex-col min-w-0 h-full ${isSmall ? "px-3.5 py-3" : "px-5 py-4"}` : cls("rounded-lg flex flex-col min-w-0 bg-transparent border", defaultBorderMixin, isSmall ? "px-3.5 py-3" : "px-5 py-4"),
|
|
225
|
+
style: embedded ? void 0 : fixedHeight ? { height: fixedHeight } : { minHeight: isSmall ? 68 : 92 },
|
|
226
|
+
children: [
|
|
227
|
+
/* @__PURE__ */ jsxs("div", {
|
|
228
|
+
className: `flex items-center justify-between ${isSmall ? "mb-1" : "mb-2"}`,
|
|
229
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
230
|
+
className: "flex flex-col min-w-0",
|
|
231
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
232
|
+
className: `font-medium leading-snug truncate text-surface-500 dark:text-surface-400 ${isSmall ? "text-[11px]" : "text-xs"}`,
|
|
233
|
+
children: title
|
|
234
|
+
}), config.dateRange && !isSmall && /* @__PURE__ */ jsx("span", {
|
|
235
|
+
className: "text-[10px] text-surface-400 dark:text-surface-500 truncate mt-0.5",
|
|
236
|
+
children: config.dateRange
|
|
237
|
+
})]
|
|
238
|
+
}), iconElement && /* @__PURE__ */ jsx("span", {
|
|
239
|
+
className: "ml-2 shrink-0",
|
|
240
|
+
children: iconElement
|
|
241
|
+
})]
|
|
242
|
+
}),
|
|
243
|
+
/* @__PURE__ */ jsx("div", {
|
|
244
|
+
className: `font-semibold leading-tight tracking-tight break-all text-surface-800 dark:text-surface-100 ${isSmall ? "text-lg" : containerWidth !== null && containerWidth < 300 ? "text-xl" : "text-2xl"}`,
|
|
245
|
+
children: formattedValue
|
|
246
|
+
}),
|
|
247
|
+
comparisonElement && /* @__PURE__ */ jsx("div", {
|
|
248
|
+
className: isSmall ? "mt-0.5" : "mt-1",
|
|
249
|
+
children: comparisonElement
|
|
250
|
+
})
|
|
251
|
+
]
|
|
252
|
+
});
|
|
487
253
|
}
|
|
488
254
|
InsightsScorecardView.displayName = "InsightsScorecardView";
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
} else {
|
|
543
|
-
t8 = $[6];
|
|
544
|
-
}
|
|
545
|
-
let t9;
|
|
546
|
-
if ($[7] !== t8) {
|
|
547
|
-
t9 = /* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-1.5", children: [
|
|
548
|
-
t7,
|
|
549
|
-
t8
|
|
550
|
-
] });
|
|
551
|
-
$[7] = t8;
|
|
552
|
-
$[8] = t9;
|
|
553
|
-
} else {
|
|
554
|
-
t9 = $[8];
|
|
555
|
-
}
|
|
556
|
-
let t10;
|
|
557
|
-
if ($[9] !== t5 || $[10] !== t9) {
|
|
558
|
-
t10 = /* @__PURE__ */ jsxs("div", { className: t5, children: [
|
|
559
|
-
t6,
|
|
560
|
-
t9
|
|
561
|
-
] });
|
|
562
|
-
$[9] = t5;
|
|
563
|
-
$[10] = t9;
|
|
564
|
-
$[11] = t10;
|
|
565
|
-
} else {
|
|
566
|
-
t10 = $[11];
|
|
567
|
-
}
|
|
568
|
-
return t10;
|
|
569
|
-
}
|
|
570
|
-
let t3;
|
|
571
|
-
if ($[12] !== embedded || $[13] !== fixedHeight || $[14] !== hasComparison || $[15] !== hasDateRange || $[16] !== hasIcon) {
|
|
572
|
-
t3 = /* @__PURE__ */ jsx(StandardSkeleton, { hasComparison, hasIcon, hasDateRange, embedded, fixedHeight });
|
|
573
|
-
$[12] = embedded;
|
|
574
|
-
$[13] = fixedHeight;
|
|
575
|
-
$[14] = hasComparison;
|
|
576
|
-
$[15] = hasDateRange;
|
|
577
|
-
$[16] = hasIcon;
|
|
578
|
-
$[17] = t3;
|
|
579
|
-
} else {
|
|
580
|
-
t3 = $[17];
|
|
581
|
-
}
|
|
582
|
-
return t3;
|
|
255
|
+
//#endregion
|
|
256
|
+
//#region src/components/InsightWidgetSkeleton.tsx
|
|
257
|
+
/**
|
|
258
|
+
* Skeleton loader for scorecard insight widgets — displays animated
|
|
259
|
+
* shimmer placeholders that exactly match the final rendered layout
|
|
260
|
+
* of InsightsScorecardView for a given config, preventing layout shift.
|
|
261
|
+
*
|
|
262
|
+
* The skeleton receives the scorecard config so it can conditionally
|
|
263
|
+
* render placeholder lines for comparison, dateRange, and icon —
|
|
264
|
+
* only when the loaded view will also render them.
|
|
265
|
+
*
|
|
266
|
+
* The standard skeleton mirrors InsightsScorecardView's responsive
|
|
267
|
+
* container-width breakpoints (ResizeObserver → isSmall / isMedium)
|
|
268
|
+
* and uses placeholder heights that exactly match the **computed**
|
|
269
|
+
* Tailwind line-heights (accounting for `leading-*` overrides).
|
|
270
|
+
* This guarantees a pixel-perfect skeleton → loaded transition.
|
|
271
|
+
*/
|
|
272
|
+
function InsightWidgetSkeleton({ config, compact = false, embedded = false, fixedHeight }) {
|
|
273
|
+
const hasComparison = Boolean(config.comparison);
|
|
274
|
+
const hasIcon = Boolean(config.icon);
|
|
275
|
+
const hasDateRange = Boolean(config.dateRange);
|
|
276
|
+
if (compact) return /* @__PURE__ */ jsxs("div", {
|
|
277
|
+
className: cls("animate-pulse", embedded ? "h-full px-2.5 py-2" : "flex flex-col gap-0.5 rounded-md bg-transparent border min-w-0 px-2.5 py-2", !embedded && defaultBorderMixin),
|
|
278
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
279
|
+
className: "bg-surface-200 dark:bg-surface-700 rounded-sm",
|
|
280
|
+
style: {
|
|
281
|
+
height: 14,
|
|
282
|
+
width: 48
|
|
283
|
+
}
|
|
284
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
285
|
+
className: "flex items-baseline gap-1.5",
|
|
286
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
287
|
+
className: "bg-surface-200 dark:bg-surface-700 rounded-sm",
|
|
288
|
+
style: {
|
|
289
|
+
height: 20,
|
|
290
|
+
width: 40
|
|
291
|
+
}
|
|
292
|
+
}), hasComparison && /* @__PURE__ */ jsx("div", {
|
|
293
|
+
className: "bg-surface-200/60 dark:bg-surface-700/60 rounded-sm",
|
|
294
|
+
style: {
|
|
295
|
+
height: 14,
|
|
296
|
+
width: 28
|
|
297
|
+
}
|
|
298
|
+
})]
|
|
299
|
+
})]
|
|
300
|
+
});
|
|
301
|
+
return /* @__PURE__ */ jsx(StandardSkeleton, {
|
|
302
|
+
hasComparison,
|
|
303
|
+
hasIcon,
|
|
304
|
+
hasDateRange,
|
|
305
|
+
embedded,
|
|
306
|
+
fixedHeight
|
|
307
|
+
});
|
|
583
308
|
}
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
if ($[12] !== hasDateRange || $[13] !== isSmall) {
|
|
665
|
-
t8 = hasDateRange && !isSmall && /* @__PURE__ */ jsx("div", { className: "bg-surface-200/60 dark:bg-surface-700/60 rounded mt-0.5", style: {
|
|
666
|
-
height: 14,
|
|
667
|
-
width: "40%"
|
|
668
|
-
} });
|
|
669
|
-
$[12] = hasDateRange;
|
|
670
|
-
$[13] = isSmall;
|
|
671
|
-
$[14] = t8;
|
|
672
|
-
} else {
|
|
673
|
-
t8 = $[14];
|
|
674
|
-
}
|
|
675
|
-
let t9;
|
|
676
|
-
if ($[15] !== t7 || $[16] !== t8) {
|
|
677
|
-
t9 = /* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0", children: [
|
|
678
|
-
t7,
|
|
679
|
-
t8
|
|
680
|
-
] });
|
|
681
|
-
$[15] = t7;
|
|
682
|
-
$[16] = t8;
|
|
683
|
-
$[17] = t9;
|
|
684
|
-
} else {
|
|
685
|
-
t9 = $[17];
|
|
686
|
-
}
|
|
687
|
-
let t10;
|
|
688
|
-
if ($[18] !== hasIcon || $[19] !== iconSize) {
|
|
689
|
-
t10 = hasIcon && /* @__PURE__ */ jsx("span", { className: "ml-2 shrink-0", children: /* @__PURE__ */ jsx("div", { className: "bg-surface-200 dark:bg-surface-700 rounded", style: {
|
|
690
|
-
height: iconSize,
|
|
691
|
-
width: iconSize
|
|
692
|
-
} }) });
|
|
693
|
-
$[18] = hasIcon;
|
|
694
|
-
$[19] = iconSize;
|
|
695
|
-
$[20] = t10;
|
|
696
|
-
} else {
|
|
697
|
-
t10 = $[20];
|
|
698
|
-
}
|
|
699
|
-
let t11;
|
|
700
|
-
if ($[21] !== t10 || $[22] !== t6 || $[23] !== t9) {
|
|
701
|
-
t11 = /* @__PURE__ */ jsxs("div", { className: t6, children: [
|
|
702
|
-
t9,
|
|
703
|
-
t10
|
|
704
|
-
] });
|
|
705
|
-
$[21] = t10;
|
|
706
|
-
$[22] = t6;
|
|
707
|
-
$[23] = t9;
|
|
708
|
-
$[24] = t11;
|
|
709
|
-
} else {
|
|
710
|
-
t11 = $[24];
|
|
711
|
-
}
|
|
712
|
-
let t12;
|
|
713
|
-
if ($[25] !== valueHeight) {
|
|
714
|
-
t12 = /* @__PURE__ */ jsx("div", { className: "bg-surface-200 dark:bg-surface-700 rounded", style: {
|
|
715
|
-
height: valueHeight,
|
|
716
|
-
width: "40%"
|
|
717
|
-
} });
|
|
718
|
-
$[25] = valueHeight;
|
|
719
|
-
$[26] = t12;
|
|
720
|
-
} else {
|
|
721
|
-
t12 = $[26];
|
|
722
|
-
}
|
|
723
|
-
let t13;
|
|
724
|
-
if ($[27] !== hasComparison || $[28] !== isSmall) {
|
|
725
|
-
t13 = hasComparison && /* @__PURE__ */ jsx("div", { className: isSmall ? "mt-0.5" : "mt-1", children: /* @__PURE__ */ jsx("div", { className: "bg-surface-200/60 dark:bg-surface-700/60 rounded", style: {
|
|
726
|
-
height: 16,
|
|
727
|
-
width: "25%"
|
|
728
|
-
} }) });
|
|
729
|
-
$[27] = hasComparison;
|
|
730
|
-
$[28] = isSmall;
|
|
731
|
-
$[29] = t13;
|
|
732
|
-
} else {
|
|
733
|
-
t13 = $[29];
|
|
734
|
-
}
|
|
735
|
-
let t14;
|
|
736
|
-
if ($[30] !== t11 || $[31] !== t12 || $[32] !== t13 || $[33] !== t3 || $[34] !== t4 || $[35] !== t5) {
|
|
737
|
-
t14 = /* @__PURE__ */ jsxs("div", { ref: t3, className: t4, style: t5, children: [
|
|
738
|
-
t11,
|
|
739
|
-
t12,
|
|
740
|
-
t13
|
|
741
|
-
] });
|
|
742
|
-
$[30] = t11;
|
|
743
|
-
$[31] = t12;
|
|
744
|
-
$[32] = t13;
|
|
745
|
-
$[33] = t3;
|
|
746
|
-
$[34] = t4;
|
|
747
|
-
$[35] = t5;
|
|
748
|
-
$[36] = t14;
|
|
749
|
-
} else {
|
|
750
|
-
t14 = $[36];
|
|
751
|
-
}
|
|
752
|
-
return t14;
|
|
309
|
+
/**
|
|
310
|
+
* Inner component for the standard scorecard skeleton.
|
|
311
|
+
*
|
|
312
|
+
* Mirrors InsightsScorecardView's layout by:
|
|
313
|
+
* 1. Using the same ResizeObserver + containerWidth pattern for
|
|
314
|
+
* responsive breakpoints (isSmall < 200px, isMedium < 300px).
|
|
315
|
+
* 2. Using placeholder heights derived from the exact computed
|
|
316
|
+
* Tailwind line-heights that InsightsScorecardView renders.
|
|
317
|
+
* 3. Matching all container classes, margins, paddings, and flex
|
|
318
|
+
* layout properties identically.
|
|
319
|
+
*/
|
|
320
|
+
function StandardSkeleton({ hasComparison, hasIcon, hasDateRange, embedded, fixedHeight }) {
|
|
321
|
+
const containerRef = useRef(null);
|
|
322
|
+
const [containerWidth, setContainerWidth] = useState(null);
|
|
323
|
+
React.useLayoutEffect(() => {
|
|
324
|
+
if (!containerRef.current) return;
|
|
325
|
+
setContainerWidth(containerRef.current.offsetWidth);
|
|
326
|
+
const observer = new ResizeObserver((entries) => {
|
|
327
|
+
for (const entry of entries) setContainerWidth(entry.contentRect.width);
|
|
328
|
+
});
|
|
329
|
+
observer.observe(containerRef.current);
|
|
330
|
+
return () => observer.disconnect();
|
|
331
|
+
}, []);
|
|
332
|
+
const isSmall = containerWidth !== null && containerWidth < 200;
|
|
333
|
+
const titleHeight = isSmall ? 15 : 16.5;
|
|
334
|
+
const valueHeight = isSmall ? 22.5 : containerWidth !== null && containerWidth < 300 ? 25 : 30;
|
|
335
|
+
const comparisonHeight = 16;
|
|
336
|
+
const iconSize = isSmall ? 14 : 18;
|
|
337
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
338
|
+
ref: containerRef,
|
|
339
|
+
className: cls("animate-pulse", embedded ? `flex flex-col min-w-0 h-full ${isSmall ? "px-3.5 py-3" : "px-5 py-4"}` : cls("rounded-lg flex flex-col min-w-0 bg-transparent border", defaultBorderMixin, isSmall ? "px-3.5 py-3" : "px-5 py-4")),
|
|
340
|
+
style: embedded ? void 0 : fixedHeight ? { height: fixedHeight } : { minHeight: isSmall ? 68 : 92 },
|
|
341
|
+
children: [
|
|
342
|
+
/* @__PURE__ */ jsxs("div", {
|
|
343
|
+
className: `flex items-center justify-between ${isSmall ? "mb-1" : "mb-2"}`,
|
|
344
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
345
|
+
className: "flex flex-col min-w-0",
|
|
346
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
347
|
+
className: "bg-surface-200 dark:bg-surface-700 rounded",
|
|
348
|
+
style: {
|
|
349
|
+
height: titleHeight,
|
|
350
|
+
width: "60%"
|
|
351
|
+
}
|
|
352
|
+
}), hasDateRange && !isSmall && /* @__PURE__ */ jsx("div", {
|
|
353
|
+
className: "bg-surface-200/60 dark:bg-surface-700/60 rounded mt-0.5",
|
|
354
|
+
style: {
|
|
355
|
+
height: 14,
|
|
356
|
+
width: "40%"
|
|
357
|
+
}
|
|
358
|
+
})]
|
|
359
|
+
}), hasIcon && /* @__PURE__ */ jsx("span", {
|
|
360
|
+
className: "ml-2 shrink-0",
|
|
361
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
362
|
+
className: "bg-surface-200 dark:bg-surface-700 rounded",
|
|
363
|
+
style: {
|
|
364
|
+
height: iconSize,
|
|
365
|
+
width: iconSize
|
|
366
|
+
}
|
|
367
|
+
})
|
|
368
|
+
})]
|
|
369
|
+
}),
|
|
370
|
+
/* @__PURE__ */ jsx("div", {
|
|
371
|
+
className: "bg-surface-200 dark:bg-surface-700 rounded",
|
|
372
|
+
style: {
|
|
373
|
+
height: valueHeight,
|
|
374
|
+
width: "40%"
|
|
375
|
+
}
|
|
376
|
+
}),
|
|
377
|
+
hasComparison && /* @__PURE__ */ jsx("div", {
|
|
378
|
+
className: isSmall ? "mt-0.5" : "mt-1",
|
|
379
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
380
|
+
className: "bg-surface-200/60 dark:bg-surface-700/60 rounded",
|
|
381
|
+
style: {
|
|
382
|
+
height: comparisonHeight,
|
|
383
|
+
width: "25%"
|
|
384
|
+
}
|
|
385
|
+
})
|
|
386
|
+
})
|
|
387
|
+
]
|
|
388
|
+
});
|
|
753
389
|
}
|
|
754
390
|
InsightWidgetSkeleton.displayName = "InsightWidgetSkeleton";
|
|
391
|
+
//#endregion
|
|
392
|
+
//#region src/components/InsightWidget.tsx
|
|
393
|
+
/**
|
|
394
|
+
* Compute a deterministic fixed height for a standard scorecard based
|
|
395
|
+
* on which optional elements the config declares. This eliminates
|
|
396
|
+
* layout shift between skeleton and loaded states.
|
|
397
|
+
*
|
|
398
|
+
* Breakdown (non-compact, non-small):
|
|
399
|
+
* py-4 padding: 16 + 16 = 32
|
|
400
|
+
* title row: 16.5 (text-xs leading-snug)
|
|
401
|
+
* mb-2 margin: 8
|
|
402
|
+
* value: 30 (text-2xl leading-tight)
|
|
403
|
+
* ---
|
|
404
|
+
* base: 86.5
|
|
405
|
+
* + dateRange: +16 (14px text + 2px mt-0.5)
|
|
406
|
+
* + comparison: +20 (16px text + 4px mt-1)
|
|
407
|
+
*/
|
|
755
408
|
function computeFixedHeight(config) {
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
409
|
+
let h = 86.5;
|
|
410
|
+
if (config.dateRange) h += 16;
|
|
411
|
+
if (config.comparison) h += 20;
|
|
412
|
+
return Math.ceil(h);
|
|
760
413
|
}
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
if (loading) {
|
|
804
|
-
let t52;
|
|
805
|
-
if ($[8] !== compact || $[9] !== definition.scorecard || $[10] !== embedded || $[11] !== fixedHeight) {
|
|
806
|
-
t52 = /* @__PURE__ */ jsx(InsightWidgetSkeleton, { config: definition.scorecard, compact, embedded, fixedHeight });
|
|
807
|
-
$[8] = compact;
|
|
808
|
-
$[9] = definition.scorecard;
|
|
809
|
-
$[10] = embedded;
|
|
810
|
-
$[11] = fixedHeight;
|
|
811
|
-
$[12] = t52;
|
|
812
|
-
} else {
|
|
813
|
-
t52 = $[12];
|
|
814
|
-
}
|
|
815
|
-
return t52;
|
|
816
|
-
}
|
|
817
|
-
if (error) {
|
|
818
|
-
const t52 = `text-red-500/70 dark:text-red-400/70 text-[0.8125rem] ${embedded ? "px-5 py-4 h-full" : `rounded-lg bg-red-500/5 dark:bg-red-400/5 border border-red-500/10 dark:border-red-400/10 ${compact ? "px-3.5 py-3" : "px-5 py-4"}`}`;
|
|
819
|
-
let t62;
|
|
820
|
-
if ($[13] !== fixedHeight) {
|
|
821
|
-
t62 = fixedHeight ? {
|
|
822
|
-
height: fixedHeight
|
|
823
|
-
} : void 0;
|
|
824
|
-
$[13] = fixedHeight;
|
|
825
|
-
$[14] = t62;
|
|
826
|
-
} else {
|
|
827
|
-
t62 = $[14];
|
|
828
|
-
}
|
|
829
|
-
let t7;
|
|
830
|
-
if ($[15] !== definition.title) {
|
|
831
|
-
t7 = /* @__PURE__ */ jsx("div", { className: "font-semibold mb-1", children: definition.title });
|
|
832
|
-
$[15] = definition.title;
|
|
833
|
-
$[16] = t7;
|
|
834
|
-
} else {
|
|
835
|
-
t7 = $[16];
|
|
836
|
-
}
|
|
837
|
-
let t8;
|
|
838
|
-
if ($[17] !== error.message) {
|
|
839
|
-
t8 = /* @__PURE__ */ jsx("div", { children: error.message });
|
|
840
|
-
$[17] = error.message;
|
|
841
|
-
$[18] = t8;
|
|
842
|
-
} else {
|
|
843
|
-
t8 = $[18];
|
|
844
|
-
}
|
|
845
|
-
let t9;
|
|
846
|
-
if ($[19] !== t52 || $[20] !== t62 || $[21] !== t7 || $[22] !== t8) {
|
|
847
|
-
t9 = /* @__PURE__ */ jsxs("div", { className: t52, style: t62, children: [
|
|
848
|
-
t7,
|
|
849
|
-
t8
|
|
850
|
-
] });
|
|
851
|
-
$[19] = t52;
|
|
852
|
-
$[20] = t62;
|
|
853
|
-
$[21] = t7;
|
|
854
|
-
$[22] = t8;
|
|
855
|
-
$[23] = t9;
|
|
856
|
-
} else {
|
|
857
|
-
t9 = $[23];
|
|
858
|
-
}
|
|
859
|
-
return t9;
|
|
860
|
-
}
|
|
861
|
-
if (!data || data.rows.length === 0) {
|
|
862
|
-
const t52 = `text-surface-400 dark:text-surface-500 text-[0.8125rem] ${embedded ? "px-5 py-4 h-full" : `rounded-lg bg-surface-100 dark:bg-surface-800 border border-surface-200 dark:border-surface-700 ${compact ? "px-3.5 py-3" : "px-5 py-4"}`}`;
|
|
863
|
-
let t62;
|
|
864
|
-
if ($[24] !== fixedHeight) {
|
|
865
|
-
t62 = fixedHeight ? {
|
|
866
|
-
height: fixedHeight
|
|
867
|
-
} : void 0;
|
|
868
|
-
$[24] = fixedHeight;
|
|
869
|
-
$[25] = t62;
|
|
870
|
-
} else {
|
|
871
|
-
t62 = $[25];
|
|
872
|
-
}
|
|
873
|
-
let t7;
|
|
874
|
-
if ($[26] !== definition.title || $[27] !== t52 || $[28] !== t62) {
|
|
875
|
-
t7 = /* @__PURE__ */ jsxs("div", { className: t52, style: t62, children: [
|
|
876
|
-
definition.title,
|
|
877
|
-
" — No data"
|
|
878
|
-
] });
|
|
879
|
-
$[26] = definition.title;
|
|
880
|
-
$[27] = t52;
|
|
881
|
-
$[28] = t62;
|
|
882
|
-
$[29] = t7;
|
|
883
|
-
} else {
|
|
884
|
-
t7 = $[29];
|
|
885
|
-
}
|
|
886
|
-
return t7;
|
|
887
|
-
}
|
|
888
|
-
const t5 = data.rows[0];
|
|
889
|
-
let t6;
|
|
890
|
-
if ($[30] !== compact || $[31] !== definition.scorecard || $[32] !== definition.title || $[33] !== embedded || $[34] !== fixedHeight || $[35] !== t5) {
|
|
891
|
-
t6 = /* @__PURE__ */ jsx(InsightsScorecardView, { config: definition.scorecard, data: t5, title: definition.title, compact, embedded, fixedHeight });
|
|
892
|
-
$[30] = compact;
|
|
893
|
-
$[31] = definition.scorecard;
|
|
894
|
-
$[32] = definition.title;
|
|
895
|
-
$[33] = embedded;
|
|
896
|
-
$[34] = fixedHeight;
|
|
897
|
-
$[35] = t5;
|
|
898
|
-
$[36] = t6;
|
|
899
|
-
} else {
|
|
900
|
-
t6 = $[36];
|
|
901
|
-
}
|
|
902
|
-
return t6;
|
|
414
|
+
/**
|
|
415
|
+
* Single insight widget orchestrator.
|
|
416
|
+
*
|
|
417
|
+
* Wraps skeleton and loaded states in a fixed-height container
|
|
418
|
+
* (computed from the scorecard config) to prevent layout shift.
|
|
419
|
+
*
|
|
420
|
+
* All theme-awareness is handled via Tailwind `dark:` classes.
|
|
421
|
+
*/
|
|
422
|
+
function InsightWidget({ definition, collectionSlug, path, parentCollectionSlugs, parentEntityIds, compact = false, embedded = false }) {
|
|
423
|
+
const { data, loading, error } = useInsightsData(definition, {
|
|
424
|
+
path,
|
|
425
|
+
collectionSlug,
|
|
426
|
+
parentCollectionSlugs
|
|
427
|
+
});
|
|
428
|
+
const fixedHeight = !compact && !embedded ? computeFixedHeight(definition.scorecard) : void 0;
|
|
429
|
+
if (loading) return /* @__PURE__ */ jsx(InsightWidgetSkeleton, {
|
|
430
|
+
config: definition.scorecard,
|
|
431
|
+
compact,
|
|
432
|
+
embedded,
|
|
433
|
+
fixedHeight
|
|
434
|
+
});
|
|
435
|
+
if (error) return /* @__PURE__ */ jsxs("div", {
|
|
436
|
+
className: `text-red-500/70 dark:text-red-400/70 text-[0.8125rem] ${embedded ? "px-5 py-4 h-full" : `rounded-lg bg-red-500/5 dark:bg-red-400/5 border border-red-500/10 dark:border-red-400/10 ${compact ? "px-3.5 py-3" : "px-5 py-4"}`}`,
|
|
437
|
+
style: fixedHeight ? { height: fixedHeight } : void 0,
|
|
438
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
439
|
+
className: "font-semibold mb-1",
|
|
440
|
+
children: definition.title
|
|
441
|
+
}), /* @__PURE__ */ jsx("div", { children: error.message })]
|
|
442
|
+
});
|
|
443
|
+
if (!data || data.rows.length === 0) return /* @__PURE__ */ jsxs("div", {
|
|
444
|
+
className: `text-surface-400 dark:text-surface-500 text-[0.8125rem] ${embedded ? "px-5 py-4 h-full" : `rounded-lg bg-surface-100 dark:bg-surface-800 border border-surface-200 dark:border-surface-700 ${compact ? "px-3.5 py-3" : "px-5 py-4"}`}`,
|
|
445
|
+
style: fixedHeight ? { height: fixedHeight } : void 0,
|
|
446
|
+
children: [definition.title, " — No data"]
|
|
447
|
+
});
|
|
448
|
+
return /* @__PURE__ */ jsx(InsightsScorecardView, {
|
|
449
|
+
config: definition.scorecard,
|
|
450
|
+
data: data.rows[0],
|
|
451
|
+
title: definition.title,
|
|
452
|
+
compact,
|
|
453
|
+
embedded,
|
|
454
|
+
fixedHeight
|
|
455
|
+
});
|
|
903
456
|
}
|
|
904
457
|
InsightWidget.displayName = "InsightWidget";
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
}
|
|
926
|
-
let t2;
|
|
927
|
-
if ($[2] !== insights || $[3] !== slug) {
|
|
928
|
-
let t32;
|
|
929
|
-
if ($[5] !== slug) {
|
|
930
|
-
t32 = (def) => /* @__PURE__ */ jsx(InsightWidget, { definition: def, collectionSlug: slug, compact: true }, def.id);
|
|
931
|
-
$[5] = slug;
|
|
932
|
-
$[6] = t32;
|
|
933
|
-
} else {
|
|
934
|
-
t32 = $[6];
|
|
935
|
-
}
|
|
936
|
-
t2 = insights.map(t32);
|
|
937
|
-
$[2] = insights;
|
|
938
|
-
$[3] = slug;
|
|
939
|
-
$[4] = t2;
|
|
940
|
-
} else {
|
|
941
|
-
t2 = $[4];
|
|
942
|
-
}
|
|
943
|
-
let t3;
|
|
944
|
-
if ($[7] !== t1 || $[8] !== t2) {
|
|
945
|
-
t3 = /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-1.5 mt-2", style: t1, children: t2 });
|
|
946
|
-
$[7] = t1;
|
|
947
|
-
$[8] = t2;
|
|
948
|
-
$[9] = t3;
|
|
949
|
-
} else {
|
|
950
|
-
t3 = $[9];
|
|
951
|
-
}
|
|
952
|
-
return t3;
|
|
458
|
+
//#endregion
|
|
459
|
+
//#region src/components/HomeCardInsightSlot.tsx
|
|
460
|
+
/**
|
|
461
|
+
* Renders compact insight widgets inline within a home page collection card.
|
|
462
|
+
* Injected via the `home.card.insight` slot.
|
|
463
|
+
*
|
|
464
|
+
* Uses a horizontal flex layout so multiple cards sit side by side.
|
|
465
|
+
*/
|
|
466
|
+
function HomeCardInsightSlot({ slug, insights }) {
|
|
467
|
+
if (!insights || insights.length === 0) return null;
|
|
468
|
+
const estimatedRows = Math.ceil(insights.length / 2);
|
|
469
|
+
return /* @__PURE__ */ jsx("div", {
|
|
470
|
+
className: "flex flex-wrap items-center gap-1.5 mt-2",
|
|
471
|
+
style: { minHeight: estimatedRows * 42 + (estimatedRows - 1) * 6 },
|
|
472
|
+
children: insights.map((def) => /* @__PURE__ */ jsx(InsightWidget, {
|
|
473
|
+
definition: def,
|
|
474
|
+
collectionSlug: slug,
|
|
475
|
+
compact: true
|
|
476
|
+
}, def.id))
|
|
477
|
+
});
|
|
953
478
|
}
|
|
954
479
|
HomeCardInsightSlot.displayName = "HomeCardInsightSlot";
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
t1 = $[0];
|
|
971
|
-
}
|
|
972
|
-
let t2;
|
|
973
|
-
if ($[1] !== insights) {
|
|
974
|
-
t2 = insights.map(_temp);
|
|
975
|
-
$[1] = insights;
|
|
976
|
-
$[2] = t2;
|
|
977
|
-
} else {
|
|
978
|
-
t2 = $[2];
|
|
979
|
-
}
|
|
980
|
-
let t3;
|
|
981
|
-
if ($[3] !== t2) {
|
|
982
|
-
t3 = /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-3 pb-6", style: t1, children: t2 });
|
|
983
|
-
$[3] = t2;
|
|
984
|
-
$[4] = t3;
|
|
985
|
-
} else {
|
|
986
|
-
t3 = $[4];
|
|
987
|
-
}
|
|
988
|
-
return t3;
|
|
989
|
-
}
|
|
990
|
-
function _temp(def) {
|
|
991
|
-
return /* @__PURE__ */ jsx(InsightWidget, { definition: def }, def.id);
|
|
480
|
+
//#endregion
|
|
481
|
+
//#region src/components/HomeInsightsSlot.tsx
|
|
482
|
+
/**
|
|
483
|
+
* Scorecard insights panel rendered at the top of the home page.
|
|
484
|
+
* Injected via the `home.children.start` slot.
|
|
485
|
+
*
|
|
486
|
+
* Renders scorecards in a responsive grid (up to 4 columns).
|
|
487
|
+
*/
|
|
488
|
+
function HomeInsightsSlot({ insights }) {
|
|
489
|
+
if (!insights || insights.length === 0) return null;
|
|
490
|
+
return /* @__PURE__ */ jsx("div", {
|
|
491
|
+
className: "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-3 pb-6",
|
|
492
|
+
style: { minHeight: 92 },
|
|
493
|
+
children: insights.map((def) => /* @__PURE__ */ jsx(InsightWidget, { definition: def }, def.id))
|
|
494
|
+
});
|
|
992
495
|
}
|
|
993
496
|
HomeInsightsSlot.displayName = "HomeInsightsSlot";
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
$[8] = t22;
|
|
1014
|
-
} else {
|
|
1015
|
-
t22 = $[8];
|
|
1016
|
-
}
|
|
1017
|
-
t1 = insights.map(t22);
|
|
1018
|
-
$[0] = insights;
|
|
1019
|
-
$[1] = parentCollectionSlugs;
|
|
1020
|
-
$[2] = parentEntityIds;
|
|
1021
|
-
$[3] = path;
|
|
1022
|
-
$[4] = t1;
|
|
1023
|
-
} else {
|
|
1024
|
-
t1 = $[4];
|
|
1025
|
-
}
|
|
1026
|
-
let t2;
|
|
1027
|
-
if ($[9] !== t1) {
|
|
1028
|
-
t2 = /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-3 pb-4", children: t1 });
|
|
1029
|
-
$[9] = t1;
|
|
1030
|
-
$[10] = t2;
|
|
1031
|
-
} else {
|
|
1032
|
-
t2 = $[10];
|
|
1033
|
-
}
|
|
1034
|
-
return t2;
|
|
497
|
+
//#endregion
|
|
498
|
+
//#region src/components/CollectionInsightsInline.tsx
|
|
499
|
+
/**
|
|
500
|
+
* Renders scorecard insight widgets inline within a collection's list view,
|
|
501
|
+
* positioned below the title and above the main data list.
|
|
502
|
+
*
|
|
503
|
+
* Injected via the `collection.insights` slot.
|
|
504
|
+
*/
|
|
505
|
+
function CollectionInsightsInline({ insights, path, parentCollectionSlugs, parentEntityIds }) {
|
|
506
|
+
if (!insights || insights.length === 0) return null;
|
|
507
|
+
return /* @__PURE__ */ jsx("div", {
|
|
508
|
+
className: "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-3 pb-4",
|
|
509
|
+
children: insights.map((def) => /* @__PURE__ */ jsx(InsightWidget, {
|
|
510
|
+
definition: def,
|
|
511
|
+
path,
|
|
512
|
+
parentCollectionSlugs,
|
|
513
|
+
parentEntityIds
|
|
514
|
+
}, def.id))
|
|
515
|
+
});
|
|
1035
516
|
}
|
|
1036
517
|
CollectionInsightsInline.displayName = "CollectionInsightsInline";
|
|
518
|
+
//#endregion
|
|
519
|
+
//#region src/useInsightsPlugin.tsx
|
|
520
|
+
/**
|
|
521
|
+
* Creates the Insights plugin for Rebase.
|
|
522
|
+
*
|
|
523
|
+
* This plugin injects scorecard widgets into key UI locations:
|
|
524
|
+
* - **Home page header**: KPI overview via `home.children.start` slot
|
|
525
|
+
* - **Collection list view**: Scorecards inline (below title, above list) via `collection.insights` slot
|
|
526
|
+
* - **Home page cards**: Compact scorecard metrics auto-extracted from collection insights via `home.card.insight` slot
|
|
527
|
+
*
|
|
528
|
+
* Collection-level insights (`collections.<slug>`) are the single source of truth:
|
|
529
|
+
* scorecards render in the collection list view and are automatically extracted
|
|
530
|
+
* to show as compact widgets on the corresponding home page card.
|
|
531
|
+
*
|
|
532
|
+
* Each insight owns its own `data()` callback — use the Rebase client SDK,
|
|
533
|
+
* call a custom function, or hit any external API. Full flexibility, zero new endpoints.
|
|
534
|
+
*
|
|
535
|
+
* @example
|
|
536
|
+
* ```typescript
|
|
537
|
+
* import { useInsightsPlugin } from "@rebasepro/plugin-insights";
|
|
538
|
+
*
|
|
539
|
+
* const insightsPlugin = useInsightsPlugin({
|
|
540
|
+
* cacheTTL: 120_000,
|
|
541
|
+
* insights: {
|
|
542
|
+
* home: [
|
|
543
|
+
* { id: "revenue", title: "Revenue", data: async () => ..., scorecard: { ... } },
|
|
544
|
+
* ],
|
|
545
|
+
* collections: {
|
|
546
|
+
* orders: [
|
|
547
|
+
* { id: "total", title: "Total Orders", data: async () => ..., scorecard: { ... } },
|
|
548
|
+
* ],
|
|
549
|
+
* },
|
|
550
|
+
* },
|
|
551
|
+
* });
|
|
552
|
+
* ```
|
|
553
|
+
*/
|
|
1037
554
|
function useInsightsPlugin(config) {
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
555
|
+
const { insights, cacheTTL } = config;
|
|
556
|
+
return React.useMemo(() => {
|
|
557
|
+
const slots = [];
|
|
558
|
+
if (insights.home && insights.home.length > 0) {
|
|
559
|
+
const homeInsights = insights.home;
|
|
560
|
+
slots.push({
|
|
561
|
+
slot: "home.children.start",
|
|
562
|
+
Component: (props) => /* @__PURE__ */ jsx(HomeInsightsSlot, {
|
|
563
|
+
...props,
|
|
564
|
+
insights: homeInsights
|
|
565
|
+
}),
|
|
566
|
+
order: 10
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
if (insights.collections) for (const [slug, defs] of Object.entries(insights.collections)) {
|
|
570
|
+
if (defs.length === 0) continue;
|
|
571
|
+
const collectionInsights = defs;
|
|
572
|
+
slots.push({
|
|
573
|
+
slot: "collection.insights",
|
|
574
|
+
Component: (props) => {
|
|
575
|
+
if ((props.path?.split("/").filter(Boolean).pop() ?? "") !== slug) return null;
|
|
576
|
+
return /* @__PURE__ */ jsx(CollectionInsightsInline, {
|
|
577
|
+
...props,
|
|
578
|
+
insights: collectionInsights
|
|
579
|
+
});
|
|
580
|
+
},
|
|
581
|
+
order: 10
|
|
582
|
+
});
|
|
583
|
+
slots.push({
|
|
584
|
+
slot: "home.card.insight",
|
|
585
|
+
Component: (props) => {
|
|
586
|
+
if (props.slug !== slug) return null;
|
|
587
|
+
return /* @__PURE__ */ jsx(HomeCardInsightSlot, {
|
|
588
|
+
...props,
|
|
589
|
+
insights: collectionInsights
|
|
590
|
+
});
|
|
591
|
+
},
|
|
592
|
+
order: 10
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
return {
|
|
596
|
+
key: "plugin-insights",
|
|
597
|
+
slots,
|
|
598
|
+
providers: [{
|
|
599
|
+
scope: "root",
|
|
600
|
+
Component: InsightsProvider,
|
|
601
|
+
props: { cacheTTL }
|
|
602
|
+
}]
|
|
603
|
+
};
|
|
604
|
+
}, [insights, cacheTTL]);
|
|
1087
605
|
}
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
InsightsProvider,
|
|
1093
|
-
InsightsScorecardView,
|
|
1094
|
-
useInsightsData,
|
|
1095
|
-
useInsightsEngine,
|
|
1096
|
-
useInsightsPlugin
|
|
1097
|
-
};
|
|
1098
|
-
//# sourceMappingURL=index.es.js.map
|
|
606
|
+
//#endregion
|
|
607
|
+
export { InsightWidget, InsightWidgetSkeleton, InsightsCache, InsightsProvider, InsightsScorecardView, useInsightsData, useInsightsEngine, useInsightsPlugin };
|
|
608
|
+
|
|
609
|
+
//# sourceMappingURL=index.es.js.map
|