@turquoisehealth/pit-viper 2.183.0 → 2.183.1-dev.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.
Files changed (38) hide show
  1. package/claude-plugin/skills/pit-viper/SKILL.md +28 -31
  2. package/package.json +1 -1
  3. package/pv-components/dist/stats/vue/base/stats.html +1 -1
  4. package/pv-components/dist/stats/vue/visualizations/stats.html +1 -1
  5. package/pv-components/dist/stats/web/pv-menu-stats.html +1 -1
  6. package/pv-components/dist/stats/web/pv-multi-select-button-stats.html +1 -1
  7. package/pv-components/dist/stats/web/pv-query-builder-input-stats.html +1 -1
  8. package/pv-components/dist/stats/web/pv-select-button-stats.html +1 -1
  9. package/pv-components/dist/vue/base/components/base/PvMenu/cascadeUtils.d.ts +2 -1
  10. package/pv-components/dist/vue/base/components/base/PvMultiSelectButton/PvMultiSelectButton.vue.d.ts +3 -0
  11. package/pv-components/dist/vue/base/components/base/PvMultiSelectButton/types.d.ts +3 -1
  12. package/pv-components/dist/vue/base/pv-components-base.mjs +924 -871
  13. package/pv-components/dist/vue/base/pv-components-base.mjs.map +1 -1
  14. package/pv-components/dist/vue/base/types.d.ts +6 -4
  15. package/pv-components/dist/vue/visualizations/components/base/PvMenu/cascadeUtils.d.ts +2 -1
  16. package/pv-components/dist/vue/visualizations/components/base/PvMultiSelectButton/PvMultiSelectButton.vue.d.ts +3 -0
  17. package/pv-components/dist/vue/visualizations/components/base/PvMultiSelectButton/types.d.ts +3 -1
  18. package/pv-components/dist/vue/visualizations/components/tables/PvDataTable/helpers.d.ts +5 -1
  19. package/pv-components/dist/vue/visualizations/components/tables/PvDataTable/table-components/FilterGroupMenu.vue.d.ts +21 -0
  20. package/pv-components/dist/vue/visualizations/components/tables/PvDataTable/types.d.ts +33 -17
  21. package/pv-components/dist/vue/visualizations/components/tables/PvDataTable/useFilterStore.d.ts +4 -0
  22. package/pv-components/dist/vue/visualizations/components/tables/PvDataTable/useSetFilter.d.ts +11 -8
  23. package/pv-components/dist/vue/visualizations/pv-components-visualizations.mjs +2287 -1802
  24. package/pv-components/dist/vue/visualizations/pv-components-visualizations.mjs.map +1 -1
  25. package/pv-components/dist/vue/visualizations/types.d.ts +6 -4
  26. package/pv-components/dist/web/components/pv-menu/pv-menu.js +44 -35
  27. package/pv-components/dist/web/components/pv-multi-select-button/pv-multi-select-button.js +1016 -963
  28. package/pv-components/dist/web/components/pv-query-builder-input/pv-query-builder-input.js +68 -59
  29. package/pv-components/dist/web/components/pv-select-button/pv-select-button.js +44 -35
  30. package/pv-components/dist/web/pv-components.iife.js +20 -20
  31. package/pv-components/dist/web/pv-components.iife.js.map +1 -1
  32. package/claude-plugin/skills/pit-viper/references/design-language.md +0 -80
  33. package/claude-plugin/skills/pit-viper/references/design-rules.md +0 -265
  34. package/claude-plugin/skills/pit-viper/references/html-patterns.md +0 -468
  35. package/claude-plugin/skills/pit-viper/references/layout-patterns.md +0 -367
  36. package/claude-plugin/skills/pit-viper/references/patterns-core.md +0 -97
  37. package/claude-plugin/skills/pit-viper/references/theme-guide.md +0 -160
  38. package/claude-plugin/skills/pit-viper/references/vue-guidelines.md +0 -526
@@ -56,12 +56,14 @@ export interface MenuOptionSelectedEvent {
56
56
  }
57
57
  export interface SeeMoreEvent {
58
58
  parentId?: string;
59
+ offset?: number;
59
60
  }
60
- export interface MultiSelectState {
61
- selectedParentIds: string[];
62
- selectedChildrenIds: string[];
63
- deselectedChildrenIds: string[];
61
+ export interface SelectionNode {
62
+ id: string;
63
+ state: "selected" | "deselected";
64
+ children?: SelectionNode[];
64
65
  }
66
+ export type MultiSelectState = SelectionNode[];
65
67
  export declare enum MenuItemType {
66
68
  simple = "simple",
67
69
  checkbox = "checkbox",
@@ -1,4 +1,4 @@
1
- import { MenuOption } from '../../../types';
1
+ import { MenuOption, MultiSelectState } from '../../../types';
2
2
  /** Recursively collect all leaf (childless) options from a tree. */
3
3
  export declare function collectLeafOptions<T>(options: MenuOption<T>[]): MenuOption<T>[];
4
4
  /**
@@ -21,6 +21,7 @@ export declare function mergeLeafOptions<T>(base: MenuOption<T>[], overlay: Menu
21
21
  * not depend on Map iteration order.
22
22
  */
23
23
  export declare function countWithCollapsedParents<T>(options: MenuOption<T>[], selectedIds: Set<string>): number;
24
+ export declare function countFromSelectionState(state: MultiSelectState): number;
24
25
  /**
25
26
  * Recursively filter a tree for a search value.
26
27
  *
@@ -34,6 +34,7 @@ declare const _default: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>
34
34
  groupings: string[];
35
35
  hideParentOnChildQueryMatch: boolean;
36
36
  icon: string;
37
+ hasMoreOptions: boolean;
37
38
  optionsAction: MenuAction<T> | undefined;
38
39
  optionsRenderer: Component;
39
40
  overlayTrigger: boolean;
@@ -72,6 +73,7 @@ declare const _default: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>
72
73
  groupings: string[];
73
74
  hideParentOnChildQueryMatch: boolean;
74
75
  icon: string;
76
+ hasMoreOptions: boolean;
75
77
  optionsAction: MenuAction<T> | undefined;
76
78
  optionsRenderer: Component;
77
79
  overlayTrigger: boolean;
@@ -110,6 +112,7 @@ declare const _default: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>
110
112
  groupings: string[];
111
113
  hideParentOnChildQueryMatch: boolean;
112
114
  icon: string;
115
+ hasMoreOptions: boolean;
113
116
  optionsAction: MenuAction<T> | undefined;
114
117
  optionsRenderer: Component;
115
118
  overlayTrigger: boolean;
@@ -47,6 +47,8 @@ export interface PvMultiSelectButtonProps<T = unknown, SlotContext extends Recor
47
47
  icon?: string;
48
48
  /** Show a loading spinner inside the dropdown */
49
49
  isLoading?: boolean;
50
+ /** Whether more top-level options are available after the loaded options */
51
+ hasMoreOptions?: boolean;
50
52
  /** Text label on the trigger button */
51
53
  label?: string;
52
54
  /** Style of the footer action panel. "select-clear" shows select/clear all; "cancel-confirm" requires explicit confirmation. */
@@ -82,7 +84,7 @@ export interface PvMultiSelectButtonProps<T = unknown, SlotContext extends Recor
82
84
  /** CSS selector for teleporting the popover dropdown */
83
85
  teleportLocation?: string;
84
86
  /** Total available top-level options (may exceed options.length when paginating).
85
- * When totalOptionCount > options.length, a "See more" button appears. */
87
+ * Used as a fallback to show "See more" when hasMoreOptions is not provided. */
86
88
  totalOptionCount?: number;
87
89
  /** Visual style of the trigger button */
88
90
  variant?: PvSelectButtonVariant;
@@ -1,6 +1,6 @@
1
1
  import { Column, ColumnVO, ICellRendererParams, ValueFormatterFunc } from 'ag-grid-enterprise';
2
2
  import { ColDef } from 'ag-grid-community';
3
- import { ColDefContextProps } from './types';
3
+ import { AggregateFieldHierarchy, ColDefContextProps } from './types';
4
4
  /**
5
5
  * Returns row data for a cell renderer. For leaf rows, returns `params.data` directly.
6
6
  * For group rows (where `params.data` is null), falls back to the first child row's data.
@@ -13,6 +13,10 @@ export declare const colDefValueFormatter: <T>(colDef: ColDef<T>) => ValueFormat
13
13
  export declare const colDefMaxSelectableValues: <T>(colDef: ColDef<T>) => number | null;
14
14
  export declare const isColDefSingleSelect: <T>(colDef: ColDef<T>) => boolean;
15
15
  export declare const isColDefNumericDataType: <T>(colDef: ColDef<T>) => boolean;
16
+ export declare const flattenAggregateFieldHierarchy: (hierarchy: AggregateFieldHierarchy | undefined) => string[];
17
+ export declare const getAggregateFields: <T>(colDef: ColDef<T>) => string[];
18
+ export declare const getAggregateLeafFields: (hierarchy: AggregateFieldHierarchy | undefined) => string[];
19
+ export declare const getAggregateRootField: <T>(colDef: ColDef<T>) => string | undefined;
16
20
  export declare const isAggregateColDef: <T>(colDef: ColDef<T>) => boolean;
17
21
  export declare const processRowGroupCols: (rowGroupCols: ColumnVO[], colDefs: (ColDef | null | undefined)[] | undefined) => ColumnVO[];
18
22
  export declare const mapColsToColumnV0: (columns: Column[]) => ColumnVO[];
@@ -0,0 +1,21 @@
1
+ import { ColDef } from 'ag-grid-community';
2
+ import { VNodeProps, AllowedComponentProps, ComponentCustomProps, PublicProps, ShallowUnwrapRef, Ref, VNode } from 'vue';
3
+ export interface FilterGroupMenuProps<T> {
4
+ filterColDef: ColDef<T>;
5
+ }
6
+ declare const _default: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
7
+ props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{} & VNodeProps & AllowedComponentProps & ComponentCustomProps, never>, never> & FilterGroupMenuProps<T> & Partial<{}>> & PublicProps;
8
+ expose(exposed: ShallowUnwrapRef<{
9
+ openForTest: () => void;
10
+ selectedValues: Ref<Set<string> & Omit<Set<string>, keyof Set<any>>, Set<string> | (Set<string> & Omit<Set<string>, keyof Set<any>>)>;
11
+ }>): void;
12
+ attrs: any;
13
+ slots: {};
14
+ emit: {};
15
+ }>) => VNode & {
16
+ __ctx?: Awaited<typeof __VLS_setup>;
17
+ };
18
+ export default _default;
19
+ type __VLS_PrettifyLocal<T> = {
20
+ [K in keyof T]: T[K];
21
+ } & {};
@@ -44,6 +44,12 @@ export interface TooltipDatum {
44
44
  [key: string]: string | number | undefined;
45
45
  }
46
46
  export type ChartTooltipRenderer = (params: AgCartesianSeriesTooltipRendererParams<TooltipDatum>) => string;
47
+ export interface AggregateFieldHierarchy {
48
+ /** Field represented by this hierarchy node. Parent/child relationships are determined by nesting. */
49
+ field: string;
50
+ /** Child fields nested under this field. */
51
+ children?: AggregateFieldHierarchy[];
52
+ }
47
53
  export interface ColDefContextProps<T> {
48
54
  /**
49
55
  * Display name for the aggregation function (e.g. "Sum", "Average", etc.) to show in the UI, if different from the aggFunc name
@@ -139,38 +145,44 @@ export interface ColDefContextProps<T> {
139
145
  customTooltipRenderer?: ChartTooltipRenderer;
140
146
  /**
141
147
  * For server-side filtering, list of associated column IDs to query against when searching for filter values.
142
- *
143
- * Interaction with `aggregateFields`:
144
- * - `queryColIds` only, with query: rows matching the query in any `queryColIds` field are found,
145
- * then the base column's `field` values are collected from those rows.
146
- * - `queryColIds` + `aggregateFields`, with query: rows matching the query via `queryColIds` are found,
147
- * then values are collected from each `aggregateFields` field (not the base `field`).
148
- * - `queryColIds` only, no query: ignored — all values from the base `field` are returned.
149
- * - `aggregateFields` only, no query: values are collected from each `aggregateFields` field across all rows.
150
148
  */
151
149
  queryColIds?: string[];
152
150
  /**
153
- * A list of fields to use when aggregating data for this column.
154
- * Fields must be present as their own columns in the table.
155
- * The filter types must match between the aggregated column AND the fields used for aggregation.
156
- * Filters for the aggregated fields will be hidden from the UI.
151
+ * Hierarchy of fields represented by this aggregate filter column.
157
152
  *
158
- * Requires `enableAdvancedFilter: true` on the table columns with `aggregateFields` are
159
- * excluded (and may log a console warning) when advanced filtering is disabled.
153
+ * Example: `{ field: "health_system", children: [{ field: "provider_id" }] }`
154
+ * renders health systems as parent options and providers as nested child options.
155
+ * Fields must be present as their own columns in the table. Filters for the
156
+ * hierarchy fields are hidden from the filter panel in favor of this aggregate filter.
160
157
  *
161
- * Selected filter values are routed back to their originating field via `colField` metadata
162
- * and composed into an OR join across fields, then ANDed with existing filters.
158
+ * Requires `enableAdvancedFilter: true` on the table columns with an aggregate hierarchy
159
+ * are excluded (and may log a console warning) when advanced filtering is disabled.
160
+ */
161
+ aggregateFieldHierarchy?: AggregateFieldHierarchy;
162
+ /**
163
+ * Aggregate filter column for columns that have "peer" relationships, as opposed to hierarchical
164
+ * Requires `enableAdvancedFilter: true` on the table — columns with aggregate fields
165
+ * are excluded (and may log a console warning) when advanced filtering is disabled.
163
166
  */
164
167
  aggregateFields?: string[];
165
168
  /**
166
169
  * If true, this column is considered a "dev" column and will only be shown when devMode is enabled
167
170
  */
168
171
  devOnly?: boolean;
172
+ /**
173
+ * A group of boolean sub-fields to render as a hover submenu above the filter options.
174
+ * Each field in `fields` must be present as a column in the table.
175
+ * Selecting an item toggles a `<field> = "true"` condition in the advanced filter model.
176
+ */
177
+ filterGroup?: {
178
+ label: string;
179
+ fields: string[];
180
+ };
169
181
  }
170
182
  export interface FilterValuesSetHandlerParams<T> {
171
183
  api?: GridApi<T>;
172
184
  colDef: ColDef<T>;
173
- filterModel?: FilterModel | null;
185
+ filterModel?: FilterModel | AdvancedFilterModel | null;
174
186
  query?: string;
175
187
  selectedValues?: (string | null)[];
176
188
  /** Pagination offset for "see more" requests */
@@ -191,6 +203,8 @@ export interface FilterValueMatchResult {
191
203
  }
192
204
  export interface FilterValuesResponse {
193
205
  values: (FilterValueResponseOption | null)[];
206
+ /** Whether additional matching values are available after this page */
207
+ hasMore?: boolean;
194
208
  /** Total count of matching values (before pagination/truncation) */
195
209
  totalCount?: number;
196
210
  }
@@ -217,6 +231,8 @@ export interface FilterValueResponseOption {
217
231
  matchedValue?: string;
218
232
  /** The field used to match the value (for search scenarios) */
219
233
  matchedField?: string;
234
+ /** Optional PvMenu option props to apply when rendering this value in custom/nested filters. */
235
+ menuOption?: Partial<Omit<MenuOption<FilterValueResponseOption>, "id" | "text" | "children" | "context">>;
220
236
  /** Nested child options for hierarchical/cascade filtering */
221
237
  children?: FilterValueResponseOption[];
222
238
  /** Total number of children available (may exceed children.length when paginating) */
@@ -21,6 +21,7 @@ export declare const createFilterStore: () => {
21
21
  filterModel?: FilterModel | AdvancedFilterModel;
22
22
  offset?: number;
23
23
  parentId?: string;
24
+ useStaged?: boolean;
24
25
  }) => Promise<(string | null)[]>;
25
26
  filterValueContext: (colField: string, value: string | null) => FilterValueResponseOption | null | undefined;
26
27
  filterModelEmpty: ComputedRef<boolean>;
@@ -51,6 +52,7 @@ export declare const createFilterStore: () => {
51
52
  getStagedSelectedValues: (colField: string) => (string | null)[];
52
53
  setStagedSelectedValues: (colField: string, selectedValues: (string | null)[]) => void;
53
54
  filterValueSearchTextMap: Ref<Record<string, string | null>, Record<string, string | null>>;
55
+ filterValuesHasMoreMap: Ref<Record<string, boolean | undefined>, Record<string, boolean | undefined>>;
54
56
  filterValuesTotalCountMap: Ref<Record<string, number | undefined>, Record<string, number | undefined>>;
55
57
  };
56
58
  export declare const useFilterStore: () => {
@@ -67,6 +69,7 @@ export declare const useFilterStore: () => {
67
69
  filterModel?: FilterModel | AdvancedFilterModel;
68
70
  offset?: number;
69
71
  parentId?: string;
72
+ useStaged?: boolean;
70
73
  }) => Promise<(string | null)[]>;
71
74
  filterValueContext: (colField: string, value: string | null) => FilterValueResponseOption | null | undefined;
72
75
  filterModelEmpty: ComputedRef<boolean>;
@@ -97,5 +100,6 @@ export declare const useFilterStore: () => {
97
100
  getStagedSelectedValues: (colField: string) => (string | null)[];
98
101
  setStagedSelectedValues: (colField: string, selectedValues: (string | null)[]) => void;
99
102
  filterValueSearchTextMap: Ref<Record<string, string | null>, Record<string, string | null>>;
103
+ filterValuesHasMoreMap: Ref<Record<string, boolean | undefined>, Record<string, boolean | undefined>>;
100
104
  filterValuesTotalCountMap: Ref<Record<string, number | undefined>, Record<string, number | undefined>>;
101
105
  };
@@ -6,6 +6,7 @@ export interface UseSetFilterOptions<T> {
6
6
  filterColDef: Ref<ColDef<T>>;
7
7
  filterStyle?: Ref<"horizontal" | "vertical">;
8
8
  onSelectionChanged?: () => void;
9
+ filterGroupStagedFields?: Ref<Set<string>>;
9
10
  }
10
11
  export declare const useSetFilter: <T>(options: UseSetFilterOptions<T>) => {
11
12
  selectedValues: WritableComputedRef<(string | null)[], (string | null)[]>;
@@ -32,18 +33,20 @@ export declare const useSetFilter: <T>(options: UseSetFilterOptions<T>) => {
32
33
  filterOptionsSortDescription: ComputedRef<string | undefined>;
33
34
  filterOptionsSortTooltip: ComputedRef<string | undefined>;
34
35
  totalOptionCount: ComputedRef<number | undefined>;
36
+ hasMoreOptions: ComputedRef<boolean | undefined>;
35
37
  isAggregate: ComputedRef<boolean>;
36
38
  cascadeSelectionState: Ref<{
37
- selectedParentIds: string[];
38
- selectedChildrenIds: string[];
39
- deselectedChildrenIds: string[];
40
- }, MultiSelectState | {
41
- selectedParentIds: string[];
42
- selectedChildrenIds: string[];
43
- deselectedChildrenIds: string[];
44
- }>;
39
+ id: string;
40
+ state: "selected" | "deselected";
41
+ children?: /*elided*/ any[] | undefined;
42
+ }[], MultiSelectState | {
43
+ id: string;
44
+ state: "selected" | "deselected";
45
+ children?: /*elided*/ any[] | undefined;
46
+ }[]>;
45
47
  filterValueContext: (colField: string, value: string | null) => FilterValueResponseOption | null | undefined;
46
48
  formatDisplayValue: (input: string | null) => string | null;
49
+ resolvedFilterValueContext: (input: string | null) => FilterValueResponseOption | null | undefined;
47
50
  isUnresolvedMetadataValue: (value: string | null) => boolean;
48
51
  getLatestFilterValues: (fetchNewValues?: boolean, forceFetchValues?: boolean) => Promise<void>;
49
52
  addSelectedValue: (value: string | null, field?: string) => void;