react-semaphor 0.1.524 → 0.1.525

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.
Files changed (42) hide show
  1. package/dist/briefings/index.js +38 -33
  2. package/dist/chunks/{dashboard-briefing-launcher-CTEyh3FQ.js → dashboard-briefing-launcher-BilVIEyw.js} +3 -3
  3. package/dist/chunks/{dashboard-controls-C3KbYzz-.js → dashboard-controls-DyLPcvCK.js} +4 -4
  4. package/dist/chunks/{dashboard-json-Kc_M7nLP.js → dashboard-json-QEoU-mx4.js} +2 -2
  5. package/dist/chunks/{edit-dashboard-visual-DqRmfRqN.js → edit-dashboard-visual-DtmKNNdE.js} +2113 -2107
  6. package/dist/chunks/{editor-action-buttons-s-ByVR9x.js → editor-action-buttons-B9VRW3Bh.js} +2 -2
  7. package/dist/chunks/{index-D7GVxl4a.js → index-DYOaHuLS.js} +31052 -30097
  8. package/dist/chunks/{index-D9HDUSye.js → index-ON7Gpvcv.js} +1186 -1017
  9. package/dist/chunks/{report-preferences-dialog-RAp0DAuw.js → report-preferences-dialog-BLaFmlE2.js} +1 -1
  10. package/dist/dashboard/index.js +1 -1
  11. package/dist/data-app-builder/index.js +1 -1
  12. package/dist/index.js +5 -5
  13. package/dist/style.css +1 -1
  14. package/dist/surfboard/index.js +2 -2
  15. package/dist/types/briefings/index.d.ts +1 -1
  16. package/dist/types/briefings/schedule.d.ts +49 -2
  17. package/dist/types/components/briefings/briefing-author/form-primitives.d.ts +1 -1
  18. package/dist/types/components/briefings/briefing-author/schedule-model.d.ts +12 -2
  19. package/dist/types/components/sharing-and-management/hooks/use-groups.d.ts +5 -1
  20. package/dist/types/components/sharing-and-management/hooks/use-unified-users.d.ts +9 -1
  21. package/dist/types/components/sharing-and-management/resource-share-dialog/index.d.ts +1 -1
  22. package/dist/types/components/sharing-and-management/resource-share-dialog/unified/adapter.d.ts +21 -1
  23. package/dist/types/components/sharing-and-management/resource-share-dialog/unified/configs.d.ts +12 -0
  24. package/dist/types/components/sharing-and-management/resource-share-dialog/unified/invite-combobox.d.ts +5 -0
  25. package/dist/types/components/sharing-and-management/resource-share-dialog/unified/share-shape.d.ts +7 -0
  26. package/dist/types/components/sharing-and-management/resource-share-dialog/unified/types.d.ts +2 -0
  27. package/dist/types/components/sharing-and-management/utils/shares-types.d.ts +8 -0
  28. package/dist/types/components/sharing-and-management/utils/types.d.ts +2 -0
  29. package/dist/types/components/ui/resizable.d.ts +1 -1
  30. package/dist/types/lib/charts/area-chart.d.ts +1 -1
  31. package/dist/types/lib/charts/bar-chart.d.ts +1 -1
  32. package/dist/types/lib/charts/cartesian-data.d.ts +72 -0
  33. package/dist/types/lib/charts/cartesian-fields.d.ts +60 -0
  34. package/dist/types/lib/charts/chart-utils.d.ts +3 -0
  35. package/dist/types/lib/charts/combo-chart.d.ts +1 -1
  36. package/dist/types/lib/charts/create-chart.d.ts +1 -1
  37. package/dist/types/lib/charts/line-chart.d.ts +1 -1
  38. package/dist/types/lib/charts/shared/category-group-axis-plugin.d.ts +23 -0
  39. package/dist/types/lib/charts/stacked-line-chart.d.ts +2 -0
  40. package/dist/types/lib/charts/types.d.ts +1 -7
  41. package/dist/types/lib/formatters/cartesian-temporal-presentation.d.ts +6 -1
  42. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
- import { b as a, a as o } from "../chunks/index-D7GVxl4a.js";
1
+ import { b as a, a as o } from "../chunks/index-DYOaHuLS.js";
2
2
  import { C as f, E } from "../chunks/common-types-C6cAQgyh.js";
3
- import { R as t } from "../chunks/report-preferences-dialog-RAp0DAuw.js";
3
+ import { R as t } from "../chunks/report-preferences-dialog-BLaFmlE2.js";
4
4
  export {
5
5
  f as CONTROL_CARD_DEFAULT_VALUE,
6
6
  a as DisplayFormatPreferencesFields,
@@ -3,7 +3,7 @@ import { BriefingAppearanceSpec, BriefingFragments, BriefingThemeOverrides } fro
3
3
  import { MatrixConfig } from '../shared/analytics-protocol/index.js';
4
4
  export { captureMatrixExport, buildMatrixDeliveryEnvelope, matrixDeliveryPayloadSchema, matrixDeliveryQuerySchema, type MatrixLayoutReadResult } from '../shared/dashboard-authoring/matrix-delivery.js';
5
5
  export declare const BRIEFING_KIND: "BRIEFING";
6
- export { DEFAULT_BRIEFING_SCHEDULE, buildBriefingScheduleExpr, describeBriefingSchedule, isValidBriefingTimezone, parseBriefingScheduleExpr, type BriefingScheduleCadence, type BriefingScheduleViewModel, } from './schedule.js';
6
+ export { DEFAULT_BRIEFING_SCHEDULE, briefingScheduleMonths, briefingScheduleDayOccurs, briefingScheduleShortMonths, buildBriefingScheduleExpr, canonicalBriefingMonthDays, describeBriefingSchedule, isValidBriefingTimezone, nextBriefingScheduleDates, parseBriefingScheduleExpr, type BriefingScheduleFrequency, type BriefingScheduleMonthDay, type BriefingScheduleMonthInterval, type BriefingScheduleMonthlyOn, type BriefingScheduleOrdinal, type BriefingScheduleViewModel, } from './schedule.js';
7
7
  export { getBriefingCardAttachmentCapability, getBriefingCardAttachmentFormats, getDefaultBriefingCardAttachmentFormat, type BriefingCardAttachmentCapability, } from './attachments.js';
8
8
  export { canCreateBriefingForUser, type BriefingUiUser } from './capabilities.js';
9
9
  export { getBriefingCreationIntents, type BriefingAuthorIntent, } from './creation.js';
@@ -1,12 +1,44 @@
1
- export type BriefingScheduleCadence = 'daily' | 'weekly' | 'twice_monthly' | 'monthly';
1
+ export type BriefingScheduleFrequency = 'daily' | 'weekly' | 'monthly';
2
+ /** 1 to 4 count from the start of the month; -1 is the last one. */
3
+ export type BriefingScheduleOrdinal = 1 | 2 | 3 | 4 | -1;
4
+ /** Day of the month, or the last day whatever its number. */
5
+ export type BriefingScheduleMonthDay = number | 'last';
6
+ /** Months between runs. Divisors of 12, so a month list states them exactly. */
7
+ export type BriefingScheduleMonthInterval = 1 | 2 | 3 | 6 | 12;
8
+ export type BriefingScheduleMonthlyOn = {
9
+ type: 'days';
10
+ days: BriefingScheduleMonthDay[];
11
+ } | {
12
+ type: 'weekday';
13
+ ordinal: BriefingScheduleOrdinal;
14
+ weekday: number;
15
+ };
2
16
  export type BriefingScheduleViewModel = {
3
- cadence: BriefingScheduleCadence;
17
+ frequency: 'daily';
18
+ hour: number;
19
+ minute: number;
20
+ weekdaysOnly: boolean;
21
+ } | {
22
+ frequency: 'weekly';
4
23
  hour: number;
5
24
  minute: number;
6
25
  weekdays: number[];
26
+ } | {
27
+ frequency: 'monthly';
28
+ hour: number;
29
+ minute: number;
30
+ /** Every N months. */
31
+ interval: BriefingScheduleMonthInterval;
32
+ /** First month (0 = January) of the cycle; 0 when interval is 1. */
33
+ startMonth: number;
34
+ on: BriefingScheduleMonthlyOn;
7
35
  };
8
36
  export declare const DEFAULT_BRIEFING_SCHEDULE: BriefingScheduleViewModel;
9
37
  export declare function isValidBriefingTimezone(value: unknown): value is string;
38
+ /** Ascending unique day numbers, then 'last' if present; null when invalid. */
39
+ export declare function canonicalBriefingMonthDays(days: BriefingScheduleMonthDay[]): BriefingScheduleMonthDay[] | null;
40
+ /** Months (0 = January) a monthly rule runs in, ascending. */
41
+ export declare function briefingScheduleMonths(interval: BriefingScheduleMonthInterval, startMonth: number): number[];
10
42
  export declare function buildBriefingScheduleExpr(view: BriefingScheduleViewModel): string;
11
43
  export declare function parseBriefingScheduleExpr(expression: string): {
12
44
  ok: true;
@@ -16,3 +48,18 @@ export declare function parseBriefingScheduleExpr(expression: string): {
16
48
  issue: string;
17
49
  };
18
50
  export declare function describeBriefingSchedule(expression: string, timezone: string, locale?: string): string | null;
51
+ /** Whether a day of the month ever occurs in any of these months. */
52
+ export declare function briefingScheduleDayOccurs(day: BriefingScheduleMonthDay, months: number[]): boolean;
53
+ /**
54
+ * The latest chosen day that some months lack, and those months (a 31st has
55
+ * no run in April). Cron skips those months rather than moving the run.
56
+ */
57
+ export declare function briefingScheduleShortMonths(view: BriefingScheduleViewModel): {
58
+ day: number;
59
+ months: number[];
60
+ } | null;
61
+ /**
62
+ * The next `count` dates (YYYY-MM-DD in the schedule's timezone) a schedule
63
+ * runs on after `from`, or [] for an unsupported rule.
64
+ */
65
+ export declare function nextBriefingScheduleDates(expression: string, timezone: string, from: Date, count: number): string[];
@@ -1,6 +1,6 @@
1
1
  export declare function RadioRow({ label, description, checked, onSelect, name, }: {
2
2
  label: string;
3
- description: string;
3
+ description?: string;
4
4
  checked: boolean;
5
5
  onSelect: () => void;
6
6
  name: string;
@@ -1,3 +1,13 @@
1
- export { DEFAULT_BRIEFING_SCHEDULE as DEFAULT_SCHEDULE_VM, buildBriefingScheduleExpr as buildScheduleExpr, describeBriefingSchedule as describeScheduleExpr, parseBriefingScheduleExpr, type BriefingScheduleCadence as ScheduleRepeats, type BriefingScheduleViewModel as ScheduleViewModel, } from '../../../briefings/schedule.js';
1
+ import { BriefingScheduleViewModel } from '../../../briefings/schedule.js';
2
+ export { DEFAULT_BRIEFING_SCHEDULE as DEFAULT_SCHEDULE_VM, briefingScheduleDayOccurs, briefingScheduleMonths, briefingScheduleShortMonths, buildBriefingScheduleExpr as buildScheduleExpr, canonicalBriefingMonthDays, describeBriefingSchedule as describeScheduleExpr, nextBriefingScheduleDates, parseBriefingScheduleExpr, type BriefingScheduleFrequency as ScheduleFrequency, type BriefingScheduleMonthDay as ScheduleMonthDay, type BriefingScheduleMonthInterval as ScheduleMonthInterval, type BriefingScheduleOrdinal as ScheduleOrdinal, type BriefingScheduleViewModel as ScheduleViewModel, } from '../../../briefings/schedule.js';
2
3
  export declare function formatTimeLabel(hour: number, minute: number): string;
3
- export declare const COMMON_TIMEZONES: string[];
4
+ /**
5
+ * Moves a schedule to another frequency, preserving the time and weekday
6
+ * choices where they carry over.
7
+ */
8
+ export declare function withFrequency(view: BriefingScheduleViewModel, frequency: BriefingScheduleViewModel['frequency']): BriefingScheduleViewModel;
9
+ export declare function currentTimezoneId(timezone: string): string;
10
+ /** Every IANA zone the browser knows, current IDs, UTC first. */
11
+ export declare function listTimezones(): string[];
12
+ export declare function timezoneName(timezone: string, style: 'longGeneric' | 'shortOffset', at?: Date): string;
13
+ export declare function timezoneMatches(timezone: string, query: string): boolean;
@@ -1,5 +1,9 @@
1
1
  import { Group, GroupListResponse, GroupSearchParams, GroupWithMembers } from '../utils/group-types.js';
2
- export declare function useGroups(params?: GroupSearchParams): {
2
+ /** Groups the caller may see; `keepPrevious` as in `useUnifiedUsers`. */
3
+ export declare function useGroups(params?: GroupSearchParams, options?: {
4
+ enabled?: boolean;
5
+ keepPrevious?: boolean;
6
+ }): {
3
7
  groups: Group[];
4
8
  total: number;
5
9
  hasMore: boolean;
@@ -41,7 +41,15 @@ export interface UnifiedUsersResponse {
41
41
  total: number;
42
42
  userContext: UserContext;
43
43
  }
44
- export declare function useUnifiedUsers(params?: UserSearchParams): {
44
+ /**
45
+ * Users the caller may see, searched and filtered on the server.
46
+ * `keepPrevious` keeps the last results on screen while a new search loads,
47
+ * for search-as-you-type pickers.
48
+ */
49
+ export declare function useUnifiedUsers(params?: UserSearchParams, options?: {
50
+ enabled?: boolean;
51
+ keepPrevious?: boolean;
52
+ }): {
45
53
  users: UnifiedUser[];
46
54
  userContext: UserContext | undefined;
47
55
  total: number;
@@ -1,4 +1,4 @@
1
- import { MinimalResourceForSharing, ResourceType } from '../utils/types.js';
1
+ import { ResourceType, MinimalResourceForSharing } from '../utils/types.js';
2
2
  interface ShareDialogProps {
3
3
  resource: MinimalResourceForSharing;
4
4
  resourceType: ResourceType;
@@ -24,10 +24,30 @@ export declare function buildTenantDirectory(input: {
24
24
  groups: Group[];
25
25
  currentUser: CurrentUser | null;
26
26
  }): Entity[];
27
- export declare function buildShares({ existingShares, userDirectory, groupDirectory, tenantDirectory, currentUser, }: {
27
+ /**
28
+ * Directory for a tenant-created dashboard: organization users and groups,
29
+ * the owning tenant's users and groups, "Everyone in the organization" and
30
+ * "Everyone in <tenant>". Anything from another tenant is left out, even if
31
+ * a search returned it.
32
+ */
33
+ export declare function buildTenantCreatedDirectory(input: {
34
+ users: UnifiedUser[];
35
+ groups: Group[];
36
+ ownerTenant: {
37
+ id: string;
38
+ name: string;
39
+ };
40
+ }): Entity[];
41
+ export declare function buildShares({ existingShares, userDirectory, groupDirectory, tenantDirectory, currentUser, ownerTenant, }: {
28
42
  existingShares: SharesResponse | undefined;
29
43
  userDirectory: UnifiedUser[];
30
44
  groupDirectory: Group[];
31
45
  tenantDirectory: ProductionTenant[];
32
46
  currentUser: CurrentUser | null;
47
+ /** A tenant-created dashboard's tenant: its whole-tenant grant reads as
48
+ * "Everyone in <tenant>", as the picker offers it. */
49
+ ownerTenant?: {
50
+ id: string;
51
+ name: string;
52
+ };
33
53
  }): Share[];
@@ -23,6 +23,18 @@ export type ShareShapeConfig = {
23
23
  unifiedUsersType: 'tenant' | 'organization' | 'all';
24
24
  /** which group types `useGroups` should fetch */
25
25
  groupsType: 'ORG_GROUP' | 'TENANT_GROUP' | 'all';
26
+ /**
27
+ * A dashboard created in this tenant: it can be shared only within the
28
+ * tenant and with the organization, so only those are loaded and offered.
29
+ */
30
+ ownerTenant?: {
31
+ id: string;
32
+ name: string;
33
+ };
26
34
  };
27
35
  export declare const ORG_USER_SHARE_CONFIG: ShareShapeConfig;
28
36
  export declare function buildTenantShareConfig(_currentUser: CurrentUser | null): ShareShapeConfig;
37
+ export declare function buildTenantCreatedShareConfig(ownerTenant: {
38
+ id: string;
39
+ name: string;
40
+ }): ShareShapeConfig;
@@ -13,5 +13,10 @@ export type InviteComboboxProps = {
13
13
  onSubmit: () => void;
14
14
  isSubmitting?: boolean;
15
15
  viewerType: 'organization' | 'tenant' | null | undefined;
16
+ /** The typed text (trimmed), so the caller can search the server. */
17
+ onSearchChange?: (query: string) => void;
18
+ /** The tenant being browsed (null when none), so the caller can load
19
+ * that tenant's users. */
20
+ onDrilledTenantChange?: (tenantId: string | null) => void;
16
21
  };
17
22
  export declare function InviteCombobox(props: InviteComboboxProps): import("react").JSX.Element;
@@ -1,6 +1,13 @@
1
1
  import { MinimalResourceForSharing, ResourceType } from '../../utils/types.js';
2
2
  import { CurrentUser } from '../../hooks/use-current-user-info.js';
3
3
  import { ShareShapeConfig } from './configs.js';
4
+ /** Pause after typing before searching the server. */
5
+ export declare const SHARE_SEARCH_DELAY_MS = 250;
6
+ /** Matches per search, and groups per search. */
7
+ export declare const SHARE_SEARCH_PAGE_SIZE = 50;
8
+ /** Users loaded when browsing one tenant: every user of the largest tenant
9
+ * measured (91 on 2026-10-01) fits, with room to grow. */
10
+ export declare const TENANT_BROWSE_PAGE_SIZE = 200;
4
11
  type ShareShapeProps = {
5
12
  open: boolean;
6
13
  resource: MinimalResourceForSharing;
@@ -11,6 +11,8 @@ export type Entity = {
11
11
  * live in */
12
12
  tenantId?: string;
13
13
  tenantName?: string;
14
+ /** for a tenant: every user in it, counted on the server */
15
+ userCount?: number;
14
16
  /** initial used by the avatar primitive when no glyph is appropriate */
15
17
  initial: string;
16
18
  };
@@ -119,4 +119,12 @@ export type Shares = {
119
119
  };
120
120
  export type SharesResponse = {
121
121
  shares: Shares;
122
+ /**
123
+ * Dashboards: the tenant the dashboard was created in, or null for an
124
+ * organization dashboard. The share dialog takes its shape from it.
125
+ */
126
+ ownerTenant?: {
127
+ id: string;
128
+ name: string;
129
+ } | null;
122
130
  };
@@ -17,6 +17,8 @@ export interface User {
17
17
  export interface Tenant {
18
18
  id: string;
19
19
  name: string;
20
+ /** Every user in the tenant, counted on the server (tenants API). */
21
+ userCount?: number;
20
22
  }
21
23
  export interface SelectedUser {
22
24
  id: string;
@@ -1,6 +1,6 @@
1
1
  import * as ResizablePrimitive from "react-resizable-panels";
2
2
  declare const ResizablePanelGroup: ({ className, ...props }: React.ComponentProps<typeof ResizablePrimitive.PanelGroup>) => import("react").JSX.Element;
3
- declare const ResizablePanel: import('react').ForwardRefExoticComponent<Omit<import('react').HTMLAttributes<HTMLElement | HTMLObjectElement | HTMLMapElement | HTMLLabelElement | HTMLSourceElement | HTMLInputElement | HTMLTimeElement | HTMLTableElement | HTMLBodyElement | HTMLStyleElement | HTMLTitleElement | HTMLAreaElement | HTMLOutputElement | HTMLLinkElement | HTMLProgressElement | HTMLHRElement | HTMLAnchorElement | HTMLDataElement | HTMLBaseElement | HTMLCanvasElement | HTMLAudioElement | HTMLQuoteElement | HTMLBRElement | HTMLButtonElement | HTMLTableCaptionElement | HTMLTableColElement | HTMLDataListElement | HTMLModElement | HTMLDetailsElement | HTMLDialogElement | HTMLDivElement | HTMLDListElement | HTMLEmbedElement | HTMLFieldSetElement | HTMLFormElement | HTMLHeadingElement | HTMLHeadElement | HTMLHtmlElement | HTMLIFrameElement | HTMLImageElement | HTMLLegendElement | HTMLLIElement | HTMLMenuElement | HTMLMetaElement | HTMLMeterElement | HTMLOListElement | HTMLOptGroupElement | HTMLOptionElement | HTMLParagraphElement | HTMLPictureElement | HTMLPreElement | HTMLScriptElement | HTMLSelectElement | HTMLSlotElement | HTMLSpanElement | HTMLTableSectionElement | HTMLTableCellElement | HTMLTemplateElement | HTMLTextAreaElement | HTMLTableRowElement | HTMLTrackElement | HTMLUListElement | HTMLVideoElement>, "id" | "onResize"> & {
3
+ declare const ResizablePanel: import('react').ForwardRefExoticComponent<Omit<import('react').HTMLAttributes<HTMLElement | HTMLObjectElement | HTMLMapElement | HTMLLabelElement | HTMLSourceElement | HTMLInputElement | HTMLTimeElement | HTMLTableElement | HTMLBodyElement | HTMLStyleElement | HTMLTitleElement | HTMLAreaElement | HTMLOutputElement | HTMLLinkElement | HTMLProgressElement | HTMLHRElement | HTMLAnchorElement | HTMLDataElement | HTMLBaseElement | HTMLTableCellElement | HTMLCanvasElement | HTMLAudioElement | HTMLQuoteElement | HTMLBRElement | HTMLButtonElement | HTMLTableCaptionElement | HTMLTableColElement | HTMLDataListElement | HTMLModElement | HTMLDetailsElement | HTMLDialogElement | HTMLDivElement | HTMLDListElement | HTMLEmbedElement | HTMLFieldSetElement | HTMLFormElement | HTMLHeadingElement | HTMLHeadElement | HTMLHtmlElement | HTMLIFrameElement | HTMLImageElement | HTMLLegendElement | HTMLLIElement | HTMLMenuElement | HTMLMetaElement | HTMLMeterElement | HTMLOListElement | HTMLOptGroupElement | HTMLOptionElement | HTMLParagraphElement | HTMLPictureElement | HTMLPreElement | HTMLScriptElement | HTMLSelectElement | HTMLSlotElement | HTMLSpanElement | HTMLTableSectionElement | HTMLTemplateElement | HTMLTextAreaElement | HTMLTableRowElement | HTMLTrackElement | HTMLUListElement | HTMLVideoElement>, "id" | "onResize"> & {
4
4
  className?: string | undefined;
5
5
  collapsedSize?: number | undefined;
6
6
  collapsible?: boolean | undefined;
@@ -2,4 +2,4 @@ import { ChartConfigParams, TChartConfiguration } from './types.js';
2
2
  /**
3
3
  * Create an area chart configuration
4
4
  */
5
- export declare function createAreaChart({ card, data, cfg, customCfg, preferences, cardType, comparisonMetadata, numericPresentation, temporalPresentation, }: ChartConfigParams): TChartConfiguration;
5
+ export declare function createAreaChart({ card, data: rawData, cfg, customCfg, preferences, cardType, columnKeyMap, comparisonMetadata, numericPresentation, temporalPresentation, }: ChartConfigParams): TChartConfiguration;
@@ -2,4 +2,4 @@ import { ChartConfigParams, TChartConfiguration } from './types.js';
2
2
  /**
3
3
  * Create a bar chart configuration
4
4
  */
5
- export declare function createBarChart({ card, data: rawData, cfg, customCfg, preferences, cardType, comparisonMetadata, numericPresentation, temporalPresentation, }: ChartConfigParams): TChartConfiguration;
5
+ export declare function createBarChart({ card, data: rawData, cfg, customCfg, preferences, cardType, columnKeyMap, comparisonMetadata, numericPresentation, temporalPresentation, }: ChartConfigParams): TChartConfiguration;
@@ -0,0 +1,72 @@
1
+ import { TCard, TCardPreferences } from '../types/common-types.js';
2
+ import { QueryColumnKeyMap } from '../types/explorer-types.js';
3
+ import { ComparisonMetadataMap } from '../types/query-types.js';
4
+ import { CartesianTemporalPresentation, CartesianTemporalSeriesValue } from '../formatters/cartesian-temporal-presentation.js';
5
+ import { ChartOptions, Plugin } from 'chart.js';
6
+ import { CategoryGroupAxisSide, CategoryGroupRun } from './shared/category-group-axis-plugin.js';
7
+ export type PreparedCartesianChartData = {
8
+ /** Ordered records, locally pivoted when `seriesKey` is set. */
9
+ records: Record<string, any>[];
10
+ axisKeys: string[];
11
+ /** Grouped field whose values became dataset labels through a local pivot. */
12
+ seriesKey?: string;
13
+ /** Original series values keyed by their pivoted dataset label. */
14
+ seriesValues?: ReadonlyMap<string, CartesianTemporalSeriesValue>;
15
+ /** Keys rendered as datasets, in display order. */
16
+ valueKeys: string[];
17
+ /** True when each value column is one Pivot member returned by the server. */
18
+ hasServerPivotedSeries: boolean;
19
+ labels: unknown[];
20
+ isComparison: boolean;
21
+ };
22
+ export declare function prepareCartesianChartData(input: {
23
+ card: TCard;
24
+ cardType: string;
25
+ records: Record<string, any>[];
26
+ columnKeyMap?: QueryColumnKeyMap;
27
+ comparisonMetadata?: ComparisonMetadataMap;
28
+ temporalPresentation?: CartesianTemporalPresentation;
29
+ sortChart?: 'asc' | 'desc' | 'none';
30
+ }): PreparedCartesianChartData;
31
+ /**
32
+ * The builder owns the identity of what it draws. Every dataset carries the
33
+ * drawn outer-level axis values, the full category path when the axis has two
34
+ * or more levels, and, when it is one series member, the canonical series
35
+ * value, regardless of temporal presentation. Consumers such
36
+ * as click context read this identity instead of recovering it from raw query
37
+ * records by position, which breaks whenever records are pivoted, grouped or
38
+ * sorted, or datasets are added or removed. Identity attached earlier (temporal
39
+ * or wide-pivot result identity) is kept as is.
40
+ */
41
+ export declare function attachRenderedIdentity<T extends object>(datasets: readonly T[], prepared: Pick<PreparedCartesianChartData, 'records' | 'axisKeys' | 'seriesKey' | 'seriesValues' | 'hasServerPivotedSeries'>): T[];
42
+ export type NestedCategoryAxis = {
43
+ axisId: 'x' | 'y';
44
+ side: CategoryGroupAxisSide;
45
+ innerLabels: string[];
46
+ runs: CategoryGroupRun[];
47
+ };
48
+ /**
49
+ * The nested axis applies to two-level paths (D8). Whether the category scale
50
+ * ends up on its default side, visible and labeled is decided at render time
51
+ * from the resolved scale (see category-group-axis-plugin), so custom chart
52
+ * options are covered too.
53
+ */
54
+ export declare function resolveNestedCategoryAxis(input: {
55
+ prepared: Pick<PreparedCartesianChartData, 'records' | 'axisKeys'>;
56
+ cardType: string;
57
+ preferences?: TCardPreferences;
58
+ temporalPresentation?: CartesianTemporalPresentation;
59
+ }): NestedCategoryAxis | undefined;
60
+ /**
61
+ * Add the nested category axis to final options when it applies. Returns the
62
+ * chart's plugins with the nested axis plugin appended, or the plugins as
63
+ * given.
64
+ */
65
+ export declare function withNestedCategoryAxis<P>(input: {
66
+ prepared: Pick<PreparedCartesianChartData, 'records' | 'axisKeys'>;
67
+ cardType: string;
68
+ preferences?: TCardPreferences;
69
+ temporalPresentation?: CartesianTemporalPresentation;
70
+ options: ChartOptions;
71
+ plugins: P[] | undefined;
72
+ }): Array<P | Plugin> | undefined;
@@ -0,0 +1,60 @@
1
+ import { TCard } from '../types/common-types.js';
2
+ import { CardConfig, Field, QueryColumnKeyMap } from '../types/explorer-types.js';
3
+ import { CartesianTemporalPresentation } from '../formatters/cartesian-temporal-presentation.js';
4
+ export declare const CARTESIAN_AXIS_PATH_SEPARATOR = " \u00B7 ";
5
+ export type CartesianFieldRoles = {
6
+ /** Result keys for the category path, outer to inner. */
7
+ axisKeys: string[];
8
+ /** Result key whose values become series through a local pivot. */
9
+ seriesKey?: string;
10
+ /** Result keys plotted as values, in display order. */
11
+ valueKeys: string[];
12
+ };
13
+ export declare function usesCartesianFieldRoles(cardType?: string): boolean;
14
+ /**
15
+ * The saved Sort setting applies only where the editor offers it, so a value
16
+ * left over from switching chart type has no effect.
17
+ */
18
+ export declare function supportsChartSort(cardType?: string): boolean;
19
+ export declare function isStackedCartesianChartType(cardType?: string): boolean;
20
+ /**
21
+ * Legacy stacked shape: exactly two Rows fields and an empty Pivot zone render
22
+ * the second Rows field as the series. Saved dashboards depend on this, so it
23
+ * is kept for that exact shape only and never extended to more Rows fields.
24
+ */
25
+ export declare function resolveLegacySeriesGroupField(cardConfig: CardConfig | undefined): Field | undefined;
26
+ /**
27
+ * Resolve cartesian roles for a chart.
28
+ *
29
+ * `keys` are the result keys in display order (comparison internals removed,
30
+ * temporal axis first), as builders already compute them.
31
+ */
32
+ export declare function resolveCartesianFieldRoles(input: {
33
+ card: TCard;
34
+ cardType: string;
35
+ keys: readonly string[];
36
+ columnKeyMap?: QueryColumnKeyMap;
37
+ isComparison: boolean;
38
+ }): CartesianFieldRoles;
39
+ /**
40
+ * Order records so bars sharing an outer axis value are contiguous, keeping
41
+ * first-appearance order of groups and query order within a group. With a sort
42
+ * direction, groups are ordered by group total and records within each group
43
+ * by record total. Single-level charts without a sort keep their order.
44
+ */
45
+ export declare function orderCartesianRecordsByAxisPath<T extends Record<string, unknown>>(input: {
46
+ records: readonly T[];
47
+ axisKeys: readonly string[];
48
+ valueKeys: readonly string[];
49
+ sortChart?: 'asc' | 'desc' | 'none';
50
+ }): T[];
51
+ /**
52
+ * One level of a multi-level path. Only null, undefined and empty text are
53
+ * missing, so `0` and `false` stay distinct categories.
54
+ */
55
+ export declare function formatAxisPathLevel(value: unknown, columnKey: string, temporalPresentation?: CartesianTemporalPresentation): string;
56
+ /**
57
+ * Axis labels for the category path. One-level paths match `getXaxisLabels`;
58
+ * deeper paths join each formatted level with ` · `.
59
+ */
60
+ export declare function formatCartesianAxisPathLabels(records: readonly Record<string, unknown>[], axisKeys: readonly string[], temporalPresentation?: CartesianTemporalPresentation): unknown[];
@@ -114,6 +114,7 @@ export declare function getDefaultDatasets(metricKeys: string[], data: any[], pr
114
114
  semaphorComparisonSeries?: boolean | undefined;
115
115
  label: string;
116
116
  data: any[];
117
+ semaphorResultColumnKey: string;
117
118
  } | {
118
119
  stack?: string | undefined;
119
120
  backgroundColor: string | ((ctx: any) => string);
@@ -162,6 +163,7 @@ export declare function getDefaultDatasets(metricKeys: string[], data: any[], pr
162
163
  semaphorComparisonSeries?: boolean | undefined;
163
164
  label: string;
164
165
  data: any[];
166
+ semaphorResultColumnKey: string;
165
167
  } | {
166
168
  stack?: string | undefined;
167
169
  backgroundColor: string | ((ctx: any) => string);
@@ -209,6 +211,7 @@ export declare function getDefaultDatasets(metricKeys: string[], data: any[], pr
209
211
  semaphorComparisonSeries?: boolean | undefined;
210
212
  label: string;
211
213
  data: any[];
214
+ semaphorResultColumnKey: string;
212
215
  }) & import('../formatters/cartesian-temporal-presentation.js').CartesianTemporalDatasetIdentity)[];
213
216
  export declare function getDatasetlabelColor(align: string | undefined, backgroundColor: string): (context: any) => string;
214
217
  /**
@@ -2,4 +2,4 @@ import { ChartConfigParams, TChartConfiguration } from './types.js';
2
2
  /**
3
3
  * Create a combo chart configuration
4
4
  */
5
- export declare function createComboChart({ card, data, cfg, customCfg, preferences, comparisonMetadata, numericPresentation, temporalPresentation, }: ChartConfigParams): TChartConfiguration;
5
+ export declare function createComboChart({ card, data: rawData, cfg, customCfg, preferences, columnKeyMap, comparisonMetadata, numericPresentation, temporalPresentation, }: ChartConfigParams): TChartConfiguration;
@@ -12,7 +12,7 @@ import { CoreChartOptions } from 'chart.js';
12
12
  * For stacked charts: Colors are applied to pivot values (dataset labels)
13
13
  * For regular charts: Colors are applied to category values (individual bars)
14
14
  */
15
- export declare function createStandardChart({ data, cfg, customCfg, preferences, cardType, card, comparisonMetadata, numericPresentation, temporalPresentation, datasetAxisColumnKey, datasetSeriesColumnKey, datasetSeriesValues, }: ChartConfigParams): TChartConfiguration;
15
+ export declare function createStandardChart({ data, cfg, customCfg, preferences, cardType, card, comparisonMetadata, numericPresentation, temporalPresentation, }: ChartConfigParams): TChartConfiguration;
16
16
  export declare function getNumberAxis(cardPreferences: TCardPreferences | undefined, cfg: TChartConfiguration | undefined): "x" | "y";
17
17
  export declare function getCategoryAxis(cardPreferences: TCardPreferences | undefined): "x" | "y";
18
18
  export declare function getFmtNumberOptions(cfg: TChartConfiguration | undefined, preferences: TCardPreferences | undefined): any;
@@ -2,4 +2,4 @@ import { ChartConfigParams, TChartConfiguration } from './types.js';
2
2
  /**
3
3
  * Create a line chart configuration
4
4
  */
5
- export declare function createLineChart({ card, data, cfg, customCfg, preferences, cardType, comparisonMetadata, numericPresentation, temporalPresentation, }: ChartConfigParams): TChartConfiguration;
5
+ export declare function createLineChart({ card, data: rawData, cfg, customCfg, preferences, cardType, columnKeyMap, comparisonMetadata, numericPresentation, temporalPresentation, }: ChartConfigParams): TChartConfiguration;
@@ -0,0 +1,23 @@
1
+ import { ChartOptions, Plugin } from 'chart.js';
2
+ export type CategoryGroupRun = {
3
+ label: string;
4
+ /** First category index in the run. */
5
+ start: number;
6
+ /** Last category index in the run (inclusive). */
7
+ end: number;
8
+ };
9
+ export type CategoryGroupAxisSide = 'left' | 'bottom';
10
+ /** Contiguous runs of equal outer values. */
11
+ export declare function computeCategoryGroupRuns(outerValues: readonly unknown[], outerLabels: readonly string[]): CategoryGroupRun[];
12
+ /**
13
+ * Apply the nested axis to final chart options: inner tick labels, a reserved
14
+ * band on the category scale, and the drawing plugin. Returns the plugin to
15
+ * add to the chart's plugins.
16
+ */
17
+ export declare function applyCategoryGroupAxis(input: {
18
+ options: ChartOptions;
19
+ axisId: 'x' | 'y';
20
+ side: CategoryGroupAxisSide;
21
+ innerLabels: readonly string[];
22
+ runs: readonly CategoryGroupRun[];
23
+ }): Plugin;
@@ -0,0 +1,2 @@
1
+ import { ChartConfigParams, TChartConfiguration } from './types.js';
2
+ export declare function createStackedLineChart({ card, data: rawData, cfg, customCfg, preferences, columnKeyMap, comparisonMetadata, numericPresentation, temporalPresentation, }: ChartConfigParams): TChartConfiguration;
@@ -5,7 +5,7 @@ import { ChartNumericPresentationContext } from '../formatters/chart-numeric-pre
5
5
  import { QueryColumnKeyMap } from '../types/explorer-types.js';
6
6
  import { SemaphorResultColumn } from '../../shared/analytics-protocol/index.js';
7
7
  import { PresentationExecutionSnapshot } from '../../shared/format-utils/index.js';
8
- import { CartesianTemporalPresentation, CartesianTemporalSeriesValue } from '../formatters/cartesian-temporal-presentation.js';
8
+ import { CartesianTemporalPresentation } from '../formatters/cartesian-temporal-presentation.js';
9
9
  export type ChartConfigParams = {
10
10
  card: TCard;
11
11
  data: any[];
@@ -13,12 +13,6 @@ export type ChartConfigParams = {
13
13
  resultColumns?: readonly SemaphorResultColumn[];
14
14
  columnKeyMap?: QueryColumnKeyMap;
15
15
  temporalPresentation?: CartesianTemporalPresentation;
16
- /** Exact category key retained by a local tall-to-wide pivot. */
17
- datasetAxisColumnKey?: string;
18
- /** Exact grouped field whose canonical values became dataset labels. */
19
- datasetSeriesColumnKey?: string;
20
- /** Original scalar values keyed by their pivoted dataset label. */
21
- datasetSeriesValues?: ReadonlyMap<string, CartesianTemporalSeriesValue>;
22
16
  presentationExecutionSnapshot?: PresentationExecutionSnapshot | null;
23
17
  dashboardId?: string;
24
18
  presentationAttachmentIndex?: number;
@@ -6,7 +6,7 @@ import { GroupedTemporalPresentation, GroupedTemporalViewerPreferences } from '.
6
6
  export type CartesianTemporalPresentation = GroupedTemporalPresentation & {
7
7
  /** Exact output key for the first grouped field. */
8
8
  axisColumnKey?: string;
9
- /** Exact output key for the second grouped field when it becomes a series. */
9
+ /** Exact output key for the grouped field rendered as the series (legacy two-Rows shape). */
10
10
  seriesColumnKey?: string;
11
11
  /** Physical wide-pivot columns keyed by their exact result accessor. */
12
12
  pivotSeriesByColumnKey: ReadonlyMap<string, SemaphorPivotResultColumnIdentity>;
@@ -15,6 +15,11 @@ export type CartesianTemporalSeriesValue = string | number | null;
15
15
  export type CartesianTemporalDatasetIdentity = {
16
16
  /** Canonical category values aligned with the rendered dataset's points. */
17
17
  semaphorCanonicalAxisValues?: readonly unknown[];
18
+ /**
19
+ * Canonical category path per point, outer to inner, aligned with the Rows
20
+ * fields that form the axis. Present only for paths of two or more levels.
21
+ */
22
+ semaphorAxisPath?: readonly (readonly unknown[])[];
18
23
  /** Canonical grouped-series value behind a presentation-only legend label. */
19
24
  semaphorCanonicalSeriesKey?: unknown;
20
25
  /** Exact physical result accessor used to build this dataset. */
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "email": "support@semaphor.cloud"
6
6
  },
7
7
  "license": "MIT",
8
- "version": "0.1.524",
8
+ "version": "0.1.525",
9
9
  "description": "Fully interactive and customizable dashboards for your apps.",
10
10
  "keywords": [
11
11
  "react",