@platforma-sdk/model 1.65.9 → 1.66.2

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 (121) hide show
  1. package/dist/block_model.cjs +8 -11
  2. package/dist/block_model.cjs.map +1 -1
  3. package/dist/block_model.d.ts.map +1 -1
  4. package/dist/block_model.js +8 -10
  5. package/dist/block_model.js.map +1 -1
  6. package/dist/columns/column_collection_builder.cjs +61 -74
  7. package/dist/columns/column_collection_builder.cjs.map +1 -1
  8. package/dist/columns/column_collection_builder.d.ts +16 -22
  9. package/dist/columns/column_collection_builder.d.ts.map +1 -1
  10. package/dist/columns/column_collection_builder.js +62 -75
  11. package/dist/columns/column_collection_builder.js.map +1 -1
  12. package/dist/columns/column_selector.cjs.map +1 -1
  13. package/dist/columns/column_selector.d.ts +1 -1
  14. package/dist/columns/column_selector.js.map +1 -1
  15. package/dist/columns/column_snapshot.cjs.map +1 -1
  16. package/dist/columns/column_snapshot.d.ts +4 -4
  17. package/dist/columns/column_snapshot.d.ts.map +1 -1
  18. package/dist/columns/column_snapshot.js.map +1 -1
  19. package/dist/columns/ctx_column_sources.cjs.map +1 -1
  20. package/dist/columns/ctx_column_sources.d.ts +1 -1
  21. package/dist/columns/ctx_column_sources.d.ts.map +1 -1
  22. package/dist/columns/ctx_column_sources.js.map +1 -1
  23. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs +2 -2
  24. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs.map +1 -1
  25. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js +2 -2
  26. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js.map +1 -1
  27. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs +17 -18
  28. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs.map +1 -1
  29. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js +17 -18
  30. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js.map +1 -1
  31. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs +99 -91
  32. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs.map +1 -1
  33. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts +16 -16
  34. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts.map +1 -1
  35. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js +102 -94
  36. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js.map +1 -1
  37. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs +32 -23
  38. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs.map +1 -1
  39. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.d.ts +5 -5
  40. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.d.ts.map +1 -1
  41. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js +33 -24
  42. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js.map +1 -1
  43. package/dist/components/PlDataTable/createPlDataTable/index.cjs.map +1 -1
  44. package/dist/components/PlDataTable/createPlDataTable/index.d.ts +2 -3
  45. package/dist/components/PlDataTable/createPlDataTable/index.d.ts.map +1 -1
  46. package/dist/components/PlDataTable/createPlDataTable/index.js.map +1 -1
  47. package/dist/components/PlDataTable/createPlDataTable/utils.cjs +133 -16
  48. package/dist/components/PlDataTable/createPlDataTable/utils.cjs.map +1 -1
  49. package/dist/components/PlDataTable/createPlDataTable/utils.d.ts +8 -6
  50. package/dist/components/PlDataTable/createPlDataTable/utils.d.ts.map +1 -1
  51. package/dist/components/PlDataTable/createPlDataTable/utils.js +130 -17
  52. package/dist/components/PlDataTable/createPlDataTable/utils.js.map +1 -1
  53. package/dist/components/PlDataTable/labels.cjs +1 -2
  54. package/dist/components/PlDataTable/labels.cjs.map +1 -1
  55. package/dist/components/PlDataTable/labels.js +1 -2
  56. package/dist/components/PlDataTable/labels.js.map +1 -1
  57. package/dist/filters/distill.cjs +73 -30
  58. package/dist/filters/distill.cjs.map +1 -1
  59. package/dist/filters/distill.d.ts.map +1 -1
  60. package/dist/filters/distill.js +73 -30
  61. package/dist/filters/distill.js.map +1 -1
  62. package/dist/index.cjs +19 -15
  63. package/dist/index.d.ts +4 -2
  64. package/dist/index.js +6 -4
  65. package/dist/labels/derive_distinct_tooltips.cjs +85 -0
  66. package/dist/labels/derive_distinct_tooltips.cjs.map +1 -0
  67. package/dist/labels/derive_distinct_tooltips.d.ts +17 -0
  68. package/dist/labels/derive_distinct_tooltips.d.ts.map +1 -0
  69. package/dist/labels/derive_distinct_tooltips.js +84 -0
  70. package/dist/labels/derive_distinct_tooltips.js.map +1 -0
  71. package/dist/labels/index.cjs +1 -0
  72. package/dist/labels/index.d.ts +2 -1
  73. package/dist/labels/index.js +1 -0
  74. package/dist/package.cjs +1 -1
  75. package/dist/package.js +1 -1
  76. package/dist/render/api.cjs +8 -13
  77. package/dist/render/api.cjs.map +1 -1
  78. package/dist/render/api.d.ts +8 -11
  79. package/dist/render/api.d.ts.map +1 -1
  80. package/dist/render/api.js +8 -13
  81. package/dist/render/api.js.map +1 -1
  82. package/dist/services/get_services.cjs +19 -0
  83. package/dist/services/get_services.cjs.map +1 -0
  84. package/dist/services/get_services.d.ts +7 -0
  85. package/dist/services/get_services.d.ts.map +1 -0
  86. package/dist/services/get_services.js +19 -0
  87. package/dist/services/get_services.js.map +1 -0
  88. package/dist/services/index.cjs +1 -0
  89. package/dist/services/index.d.ts +2 -1
  90. package/dist/services/index.js +1 -0
  91. package/dist/services/service_bridge.cjs +4 -4
  92. package/dist/services/service_bridge.cjs.map +1 -1
  93. package/dist/services/service_bridge.d.ts +4 -4
  94. package/dist/services/service_bridge.d.ts.map +1 -1
  95. package/dist/services/service_bridge.js +4 -4
  96. package/dist/services/service_bridge.js.map +1 -1
  97. package/package.json +6 -6
  98. package/src/block_model.ts +8 -11
  99. package/src/columns/column_collection_builder.test.ts +75 -30
  100. package/src/columns/column_collection_builder.ts +96 -133
  101. package/src/columns/column_selector.ts +1 -1
  102. package/src/columns/column_snapshot.ts +7 -4
  103. package/src/columns/ctx_column_sources.ts +1 -3
  104. package/src/components/PFrameForGraphs.test.ts +4 -4
  105. package/src/components/PlDataTable/createPlDataTable/createPTableDefV2.ts +2 -2
  106. package/src/components/PlDataTable/createPlDataTable/createPTableDefV3.ts +44 -21
  107. package/src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts +202 -218
  108. package/src/components/PlDataTable/createPlDataTable/discoverColumns.ts +69 -56
  109. package/src/components/PlDataTable/createPlDataTable/index.ts +6 -7
  110. package/src/components/PlDataTable/createPlDataTable/utils.test.ts +97 -1
  111. package/src/components/PlDataTable/createPlDataTable/utils.ts +190 -35
  112. package/src/components/PlDataTable/labels.ts +3 -7
  113. package/src/filters/distill.test.ts +91 -0
  114. package/src/filters/distill.ts +102 -46
  115. package/src/labels/derive_distinct_tooltips.test.ts +233 -0
  116. package/src/labels/derive_distinct_tooltips.ts +130 -0
  117. package/src/labels/index.ts +1 -0
  118. package/src/render/api.ts +15 -50
  119. package/src/services/get_services.ts +28 -0
  120. package/src/services/index.ts +1 -0
  121. package/src/services/service_bridge.ts +5 -5
@@ -7,21 +7,18 @@ let es_toolkit = require("es-toolkit");
7
7
  //#region src/components/PlDataTable/createPlDataTable/createPTableDefV3.ts
8
8
  function createPTableDefV3(params) {
9
9
  let query = {
10
+ type: params.primaryJoinType === "inner" ? "innerJoin" : "fullJoin",
11
+ entries: params.primary.map((a) => toLeaf(a.column, []))
12
+ };
13
+ for (const group of params.secondary) query = {
10
14
  type: "outerJoin",
11
- primary: toJoinEntry({
12
- type: params.primaryJoinType === "inner" ? "innerJoin" : "fullJoin",
13
- entries: params.primaryColumns.map((c) => toJoinEntry({
14
- type: "column",
15
- column: c
16
- }))
17
- }),
18
- secondary: params.secondaryGroups.map((group) => toJoinEntry({
19
- type: "innerJoin",
20
- entries: group.map((c) => toJoinEntry({
21
- type: "column",
22
- column: c
23
- }))
24
- }))
15
+ primary: {
16
+ entry: query,
17
+ qualifications: params.primary.flatMap((p) => {
18
+ return group.primaryQualifications?.[p.column.id] ?? [];
19
+ })
20
+ },
21
+ secondary: group.entries.map((e) => toLeaf(e.column, e.qualifications ?? []))
25
22
  };
26
23
  if (!(0, es_toolkit.isNil)(params.filters)) {
27
24
  const nonEmpty = require_distill.distillFilterSpec(params.filters);
@@ -46,7 +43,6 @@ function createPTableDefV3(params) {
46
43
  };
47
44
  return { query };
48
45
  }
49
- /** Convert a PTableColumnId to a SpecQueryExpression reference. */
50
46
  function columnIdToExpr(col) {
51
47
  return col.type === "axis" ? {
52
48
  type: "axisRef",
@@ -56,10 +52,13 @@ function columnIdToExpr(col) {
56
52
  value: col.id
57
53
  };
58
54
  }
59
- function toJoinEntry(input) {
55
+ function toLeaf(col, qs) {
60
56
  return {
61
- entry: input,
62
- qualifications: []
57
+ entry: {
58
+ type: "column",
59
+ column: col
60
+ },
61
+ qualifications: qs
63
62
  };
64
63
  }
65
64
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"createPTableDefV3.cjs","names":["distillFilterSpec","filterSpecToSpecQueryExpr"],"sources":["../../../../src/components/PlDataTable/createPlDataTable/createPTableDefV3.ts"],"sourcesContent":["import type {\n PColumn,\n PTableColumnId,\n PTableSorting,\n PTableDefV2,\n SingleAxisSelector,\n SpecQuery,\n SpecQueryExpression,\n SpecQueryJoinEntry,\n} from \"@milaboratories/pl-model-common\";\nimport { isBooleanExpression } from \"@milaboratories/pl-model-common\";\nimport type { PColumnDataUniversal } from \"../../../render\";\nimport { isNil } from \"es-toolkit\";\nimport type { PlDataTableFilters } from \"../typesV5\";\nimport { distillFilterSpec, filterSpecToSpecQueryExpr } from \"../../../filters\";\nimport type { Nil } from \"@milaboratories/helpers\";\n\nexport function createPTableDefV3<Data = PColumnDataUniversal>(params: {\n primaryJoinType: \"inner\" | \"full\";\n primaryColumns: PColumn<Data>[];\n secondaryGroups: PColumn<Data>[][];\n filters?: Nil | PlDataTableFilters;\n sorting?: Nil | PTableSorting[];\n}): PTableDefV2<PColumn<Data>> {\n // Build SpecQuery directly from columns\n const coreJoinQuery: SpecQuery<PColumn<Data>> = {\n type: params.primaryJoinType === \"inner\" ? \"innerJoin\" : \"fullJoin\",\n entries: params.primaryColumns.map((c) => toJoinEntry({ type: \"column\", column: c })),\n };\n\n let query: SpecQuery<PColumn<Data>> = {\n type: \"outerJoin\",\n primary: toJoinEntry(coreJoinQuery),\n secondary: params.secondaryGroups.map((group) =>\n toJoinEntry({\n type: \"innerJoin\" as const,\n entries: group.map((c) => toJoinEntry({ type: \"column\" as const, column: c })),\n }),\n ),\n };\n\n // Apply filters\n if (!isNil(params.filters)) {\n const nonEmpty = distillFilterSpec(params.filters);\n\n if (!isNil(nonEmpty)) {\n const pridicate = filterSpecToSpecQueryExpr(nonEmpty);\n if (!isBooleanExpression(pridicate)) {\n throw new Error(\n `Filter conversion produced a non-boolean expression (got type \"${pridicate.type}\"), expected a boolean predicate for query filtering`,\n );\n }\n query = {\n type: \"filter\",\n input: query,\n predicate: pridicate,\n };\n }\n }\n\n // Apply sorting\n if (!isNil(params.sorting) && params.sorting.length > 0) {\n query = {\n type: \"sort\",\n input: query,\n sortBy: params.sorting.map((s) => ({\n expression: columnIdToExpr(s.column),\n ascending: s.ascending,\n nullsFirst: !s.naAndAbsentAreLeastValues,\n })),\n };\n }\n\n return { query };\n}\n\n/** Convert a PTableColumnId to a SpecQueryExpression reference. */\nfunction columnIdToExpr(col: PTableColumnId): SpecQueryExpression {\n return col.type === \"axis\"\n ? { type: \"axisRef\", value: col.id as SingleAxisSelector }\n : { type: \"columnRef\", value: col.id };\n}\n\nfunction toJoinEntry<C>(input: SpecQuery<C>): SpecQueryJoinEntry<C> {\n return {\n entry: input,\n qualifications: [],\n };\n}\n"],"mappings":";;;;;;;AAiBA,SAAgB,kBAA+C,QAMhC;CAO7B,IAAI,QAAkC;EACpC,MAAM;EACN,SAAS,YAPqC;GAC9C,MAAM,OAAO,oBAAoB,UAAU,cAAc;GACzD,SAAS,OAAO,eAAe,KAAK,MAAM,YAAY;IAAE,MAAM;IAAU,QAAQ;IAAG,CAAC,CAAC;GACtF,CAIoC;EACnC,WAAW,OAAO,gBAAgB,KAAK,UACrC,YAAY;GACV,MAAM;GACN,SAAS,MAAM,KAAK,MAAM,YAAY;IAAE,MAAM;IAAmB,QAAQ;IAAG,CAAC,CAAC;GAC/E,CAAC,CACH;EACF;AAGD,KAAI,EAAA,GAAA,WAAA,OAAO,OAAO,QAAQ,EAAE;EAC1B,MAAM,WAAWA,gBAAAA,kBAAkB,OAAO,QAAQ;AAElD,MAAI,EAAA,GAAA,WAAA,OAAO,SAAS,EAAE;GACpB,MAAM,YAAYC,sBAAAA,0BAA0B,SAAS;AACrD,OAAI,EAAA,GAAA,gCAAA,qBAAqB,UAAU,CACjC,OAAM,IAAI,MACR,kEAAkE,UAAU,KAAK,sDAClF;AAEH,WAAQ;IACN,MAAM;IACN,OAAO;IACP,WAAW;IACZ;;;AAKL,KAAI,EAAA,GAAA,WAAA,OAAO,OAAO,QAAQ,IAAI,OAAO,QAAQ,SAAS,EACpD,SAAQ;EACN,MAAM;EACN,OAAO;EACP,QAAQ,OAAO,QAAQ,KAAK,OAAO;GACjC,YAAY,eAAe,EAAE,OAAO;GACpC,WAAW,EAAE;GACb,YAAY,CAAC,EAAE;GAChB,EAAE;EACJ;AAGH,QAAO,EAAE,OAAO;;;AAIlB,SAAS,eAAe,KAA0C;AAChE,QAAO,IAAI,SAAS,SAChB;EAAE,MAAM;EAAW,OAAO,IAAI;EAA0B,GACxD;EAAE,MAAM;EAAa,OAAO,IAAI;EAAI;;AAG1C,SAAS,YAAe,OAA4C;AAClE,QAAO;EACL,OAAO;EACP,gBAAgB,EAAE;EACnB"}
1
+ {"version":3,"file":"createPTableDefV3.cjs","names":["distillFilterSpec","filterSpecToSpecQueryExpr"],"sources":["../../../../src/components/PlDataTable/createPlDataTable/createPTableDefV3.ts"],"sourcesContent":["import type {\n AxisQualification,\n PColumn,\n PTableColumnId,\n PTableSorting,\n PTableDefV2,\n SingleAxisSelector,\n SpecQuery,\n SpecQueryExpression,\n SpecQueryJoinEntry,\n PObjectId,\n} from \"@milaboratories/pl-model-common\";\nimport { isBooleanExpression } from \"@milaboratories/pl-model-common\";\nimport type { PColumnDataUniversal } from \"../../../render\";\nimport { isNil } from \"es-toolkit\";\nimport type { PlDataTableFilters } from \"../typesV5\";\nimport { distillFilterSpec, filterSpecToSpecQueryExpr } from \"../../../filters\";\nimport type { Nil } from \"@milaboratories/helpers\";\n\n/** Primary side — base row grid. */\nexport type PrimaryEntry<Data> = {\n column: PColumn<Data>;\n};\n\n/** Secondary side leaf — the hit column, a linker step, or a label column. */\nexport type SecondaryEntry<Data> = {\n column: PColumn<Data>;\n /** For hit: `forHit`. For linker step k: `path[k].qualifications`. For label/direct: omit. */\n qualifications?: AxisQualification[];\n};\n\n/** Secondary group — one join subtree outer-joined onto primary. */\nexport type SecondaryGroup<Data> = {\n entries: SecondaryEntry<Data>[];\n /** Per-variant qualifications applied to the cloned primary anchors on this group's side.\n * Keyed by `PrimaryEntry.column.id`. Omit → base primary used unqualified (labels, non-variant columns). */\n primaryQualifications?: Record<PObjectId, AxisQualification[]>;\n};\n\nexport function createPTableDefV3<Data = PColumnDataUniversal>(params: {\n primaryJoinType: \"inner\" | \"full\";\n primary: PrimaryEntry<Data>[];\n secondary: SecondaryGroup<Data>[];\n filters?: Nil | PlDataTableFilters;\n sorting?: Nil | PTableSorting[];\n}): PTableDefV2<PColumn<Data>> {\n let query: SpecQuery<PColumn<Data>> = {\n type: params.primaryJoinType === \"inner\" ? \"innerJoin\" : \"fullJoin\",\n entries: params.primary.map((a) => toLeaf(a.column, [])),\n };\n\n for (const group of params.secondary) {\n query = {\n type: \"outerJoin\",\n primary: {\n entry: query,\n qualifications: params.primary.flatMap((p) => {\n return group.primaryQualifications?.[p.column.id] ?? [];\n }),\n },\n secondary: group.entries.map((e) => toLeaf(e.column, e.qualifications ?? [])),\n };\n }\n\n if (!isNil(params.filters)) {\n const nonEmpty = distillFilterSpec(params.filters);\n\n if (!isNil(nonEmpty)) {\n const pridicate = filterSpecToSpecQueryExpr(nonEmpty);\n if (!isBooleanExpression(pridicate)) {\n throw new Error(\n `Filter conversion produced a non-boolean expression (got type \"${pridicate.type}\"), expected a boolean predicate for query filtering`,\n );\n }\n query = {\n type: \"filter\",\n input: query,\n predicate: pridicate,\n };\n }\n }\n\n if (!isNil(params.sorting) && params.sorting.length > 0) {\n query = {\n type: \"sort\",\n input: query,\n sortBy: params.sorting.map((s) => ({\n expression: columnIdToExpr(s.column),\n ascending: s.ascending,\n nullsFirst: !s.naAndAbsentAreLeastValues,\n })),\n };\n }\n\n return { query };\n}\n\nfunction columnIdToExpr(col: PTableColumnId): SpecQueryExpression {\n return col.type === \"axis\"\n ? { type: \"axisRef\", value: col.id as SingleAxisSelector }\n : { type: \"columnRef\", value: col.id };\n}\n\nfunction toLeaf<Data>(\n col: PColumn<Data>,\n qs: AxisQualification[],\n): SpecQueryJoinEntry<PColumn<Data>> {\n return {\n entry: { type: \"column\", column: col },\n qualifications: qs,\n };\n}\n"],"mappings":";;;;;;;AAuCA,SAAgB,kBAA+C,QAMhC;CAC7B,IAAI,QAAkC;EACpC,MAAM,OAAO,oBAAoB,UAAU,cAAc;EACzD,SAAS,OAAO,QAAQ,KAAK,MAAM,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;EACzD;AAED,MAAK,MAAM,SAAS,OAAO,UACzB,SAAQ;EACN,MAAM;EACN,SAAS;GACP,OAAO;GACP,gBAAgB,OAAO,QAAQ,SAAS,MAAM;AAC5C,WAAO,MAAM,wBAAwB,EAAE,OAAO,OAAO,EAAE;KACvD;GACH;EACD,WAAW,MAAM,QAAQ,KAAK,MAAM,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CAAC,CAAC;EAC9E;AAGH,KAAI,EAAA,GAAA,WAAA,OAAO,OAAO,QAAQ,EAAE;EAC1B,MAAM,WAAWA,gBAAAA,kBAAkB,OAAO,QAAQ;AAElD,MAAI,EAAA,GAAA,WAAA,OAAO,SAAS,EAAE;GACpB,MAAM,YAAYC,sBAAAA,0BAA0B,SAAS;AACrD,OAAI,EAAA,GAAA,gCAAA,qBAAqB,UAAU,CACjC,OAAM,IAAI,MACR,kEAAkE,UAAU,KAAK,sDAClF;AAEH,WAAQ;IACN,MAAM;IACN,OAAO;IACP,WAAW;IACZ;;;AAIL,KAAI,EAAA,GAAA,WAAA,OAAO,OAAO,QAAQ,IAAI,OAAO,QAAQ,SAAS,EACpD,SAAQ;EACN,MAAM;EACN,OAAO;EACP,QAAQ,OAAO,QAAQ,KAAK,OAAO;GACjC,YAAY,eAAe,EAAE,OAAO;GACpC,WAAW,EAAE;GACb,YAAY,CAAC,EAAE;GAChB,EAAE;EACJ;AAGH,QAAO,EAAE,OAAO;;AAGlB,SAAS,eAAe,KAA0C;AAChE,QAAO,IAAI,SAAS,SAChB;EAAE,MAAM;EAAW,OAAO,IAAI;EAA0B,GACxD;EAAE,MAAM;EAAa,OAAO,IAAI;EAAI;;AAG1C,SAAS,OACP,KACA,IACmC;AACnC,QAAO;EACL,OAAO;GAAE,MAAM;GAAU,QAAQ;GAAK;EACtC,gBAAgB;EACjB"}
@@ -6,21 +6,18 @@ import { isNil } from "es-toolkit";
6
6
  //#region src/components/PlDataTable/createPlDataTable/createPTableDefV3.ts
7
7
  function createPTableDefV3(params) {
8
8
  let query = {
9
+ type: params.primaryJoinType === "inner" ? "innerJoin" : "fullJoin",
10
+ entries: params.primary.map((a) => toLeaf(a.column, []))
11
+ };
12
+ for (const group of params.secondary) query = {
9
13
  type: "outerJoin",
10
- primary: toJoinEntry({
11
- type: params.primaryJoinType === "inner" ? "innerJoin" : "fullJoin",
12
- entries: params.primaryColumns.map((c) => toJoinEntry({
13
- type: "column",
14
- column: c
15
- }))
16
- }),
17
- secondary: params.secondaryGroups.map((group) => toJoinEntry({
18
- type: "innerJoin",
19
- entries: group.map((c) => toJoinEntry({
20
- type: "column",
21
- column: c
22
- }))
23
- }))
14
+ primary: {
15
+ entry: query,
16
+ qualifications: params.primary.flatMap((p) => {
17
+ return group.primaryQualifications?.[p.column.id] ?? [];
18
+ })
19
+ },
20
+ secondary: group.entries.map((e) => toLeaf(e.column, e.qualifications ?? []))
24
21
  };
25
22
  if (!isNil(params.filters)) {
26
23
  const nonEmpty = distillFilterSpec(params.filters);
@@ -45,7 +42,6 @@ function createPTableDefV3(params) {
45
42
  };
46
43
  return { query };
47
44
  }
48
- /** Convert a PTableColumnId to a SpecQueryExpression reference. */
49
45
  function columnIdToExpr(col) {
50
46
  return col.type === "axis" ? {
51
47
  type: "axisRef",
@@ -55,10 +51,13 @@ function columnIdToExpr(col) {
55
51
  value: col.id
56
52
  };
57
53
  }
58
- function toJoinEntry(input) {
54
+ function toLeaf(col, qs) {
59
55
  return {
60
- entry: input,
61
- qualifications: []
56
+ entry: {
57
+ type: "column",
58
+ column: col
59
+ },
60
+ qualifications: qs
62
61
  };
63
62
  }
64
63
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"createPTableDefV3.js","names":[],"sources":["../../../../src/components/PlDataTable/createPlDataTable/createPTableDefV3.ts"],"sourcesContent":["import type {\n PColumn,\n PTableColumnId,\n PTableSorting,\n PTableDefV2,\n SingleAxisSelector,\n SpecQuery,\n SpecQueryExpression,\n SpecQueryJoinEntry,\n} from \"@milaboratories/pl-model-common\";\nimport { isBooleanExpression } from \"@milaboratories/pl-model-common\";\nimport type { PColumnDataUniversal } from \"../../../render\";\nimport { isNil } from \"es-toolkit\";\nimport type { PlDataTableFilters } from \"../typesV5\";\nimport { distillFilterSpec, filterSpecToSpecQueryExpr } from \"../../../filters\";\nimport type { Nil } from \"@milaboratories/helpers\";\n\nexport function createPTableDefV3<Data = PColumnDataUniversal>(params: {\n primaryJoinType: \"inner\" | \"full\";\n primaryColumns: PColumn<Data>[];\n secondaryGroups: PColumn<Data>[][];\n filters?: Nil | PlDataTableFilters;\n sorting?: Nil | PTableSorting[];\n}): PTableDefV2<PColumn<Data>> {\n // Build SpecQuery directly from columns\n const coreJoinQuery: SpecQuery<PColumn<Data>> = {\n type: params.primaryJoinType === \"inner\" ? \"innerJoin\" : \"fullJoin\",\n entries: params.primaryColumns.map((c) => toJoinEntry({ type: \"column\", column: c })),\n };\n\n let query: SpecQuery<PColumn<Data>> = {\n type: \"outerJoin\",\n primary: toJoinEntry(coreJoinQuery),\n secondary: params.secondaryGroups.map((group) =>\n toJoinEntry({\n type: \"innerJoin\" as const,\n entries: group.map((c) => toJoinEntry({ type: \"column\" as const, column: c })),\n }),\n ),\n };\n\n // Apply filters\n if (!isNil(params.filters)) {\n const nonEmpty = distillFilterSpec(params.filters);\n\n if (!isNil(nonEmpty)) {\n const pridicate = filterSpecToSpecQueryExpr(nonEmpty);\n if (!isBooleanExpression(pridicate)) {\n throw new Error(\n `Filter conversion produced a non-boolean expression (got type \"${pridicate.type}\"), expected a boolean predicate for query filtering`,\n );\n }\n query = {\n type: \"filter\",\n input: query,\n predicate: pridicate,\n };\n }\n }\n\n // Apply sorting\n if (!isNil(params.sorting) && params.sorting.length > 0) {\n query = {\n type: \"sort\",\n input: query,\n sortBy: params.sorting.map((s) => ({\n expression: columnIdToExpr(s.column),\n ascending: s.ascending,\n nullsFirst: !s.naAndAbsentAreLeastValues,\n })),\n };\n }\n\n return { query };\n}\n\n/** Convert a PTableColumnId to a SpecQueryExpression reference. */\nfunction columnIdToExpr(col: PTableColumnId): SpecQueryExpression {\n return col.type === \"axis\"\n ? { type: \"axisRef\", value: col.id as SingleAxisSelector }\n : { type: \"columnRef\", value: col.id };\n}\n\nfunction toJoinEntry<C>(input: SpecQuery<C>): SpecQueryJoinEntry<C> {\n return {\n entry: input,\n qualifications: [],\n };\n}\n"],"mappings":";;;;;;AAiBA,SAAgB,kBAA+C,QAMhC;CAO7B,IAAI,QAAkC;EACpC,MAAM;EACN,SAAS,YAPqC;GAC9C,MAAM,OAAO,oBAAoB,UAAU,cAAc;GACzD,SAAS,OAAO,eAAe,KAAK,MAAM,YAAY;IAAE,MAAM;IAAU,QAAQ;IAAG,CAAC,CAAC;GACtF,CAIoC;EACnC,WAAW,OAAO,gBAAgB,KAAK,UACrC,YAAY;GACV,MAAM;GACN,SAAS,MAAM,KAAK,MAAM,YAAY;IAAE,MAAM;IAAmB,QAAQ;IAAG,CAAC,CAAC;GAC/E,CAAC,CACH;EACF;AAGD,KAAI,CAAC,MAAM,OAAO,QAAQ,EAAE;EAC1B,MAAM,WAAW,kBAAkB,OAAO,QAAQ;AAElD,MAAI,CAAC,MAAM,SAAS,EAAE;GACpB,MAAM,YAAY,0BAA0B,SAAS;AACrD,OAAI,CAAC,oBAAoB,UAAU,CACjC,OAAM,IAAI,MACR,kEAAkE,UAAU,KAAK,sDAClF;AAEH,WAAQ;IACN,MAAM;IACN,OAAO;IACP,WAAW;IACZ;;;AAKL,KAAI,CAAC,MAAM,OAAO,QAAQ,IAAI,OAAO,QAAQ,SAAS,EACpD,SAAQ;EACN,MAAM;EACN,OAAO;EACP,QAAQ,OAAO,QAAQ,KAAK,OAAO;GACjC,YAAY,eAAe,EAAE,OAAO;GACpC,WAAW,EAAE;GACb,YAAY,CAAC,EAAE;GAChB,EAAE;EACJ;AAGH,QAAO,EAAE,OAAO;;;AAIlB,SAAS,eAAe,KAA0C;AAChE,QAAO,IAAI,SAAS,SAChB;EAAE,MAAM;EAAW,OAAO,IAAI;EAA0B,GACxD;EAAE,MAAM;EAAa,OAAO,IAAI;EAAI;;AAG1C,SAAS,YAAe,OAA4C;AAClE,QAAO;EACL,OAAO;EACP,gBAAgB,EAAE;EACnB"}
1
+ {"version":3,"file":"createPTableDefV3.js","names":[],"sources":["../../../../src/components/PlDataTable/createPlDataTable/createPTableDefV3.ts"],"sourcesContent":["import type {\n AxisQualification,\n PColumn,\n PTableColumnId,\n PTableSorting,\n PTableDefV2,\n SingleAxisSelector,\n SpecQuery,\n SpecQueryExpression,\n SpecQueryJoinEntry,\n PObjectId,\n} from \"@milaboratories/pl-model-common\";\nimport { isBooleanExpression } from \"@milaboratories/pl-model-common\";\nimport type { PColumnDataUniversal } from \"../../../render\";\nimport { isNil } from \"es-toolkit\";\nimport type { PlDataTableFilters } from \"../typesV5\";\nimport { distillFilterSpec, filterSpecToSpecQueryExpr } from \"../../../filters\";\nimport type { Nil } from \"@milaboratories/helpers\";\n\n/** Primary side — base row grid. */\nexport type PrimaryEntry<Data> = {\n column: PColumn<Data>;\n};\n\n/** Secondary side leaf — the hit column, a linker step, or a label column. */\nexport type SecondaryEntry<Data> = {\n column: PColumn<Data>;\n /** For hit: `forHit`. For linker step k: `path[k].qualifications`. For label/direct: omit. */\n qualifications?: AxisQualification[];\n};\n\n/** Secondary group — one join subtree outer-joined onto primary. */\nexport type SecondaryGroup<Data> = {\n entries: SecondaryEntry<Data>[];\n /** Per-variant qualifications applied to the cloned primary anchors on this group's side.\n * Keyed by `PrimaryEntry.column.id`. Omit → base primary used unqualified (labels, non-variant columns). */\n primaryQualifications?: Record<PObjectId, AxisQualification[]>;\n};\n\nexport function createPTableDefV3<Data = PColumnDataUniversal>(params: {\n primaryJoinType: \"inner\" | \"full\";\n primary: PrimaryEntry<Data>[];\n secondary: SecondaryGroup<Data>[];\n filters?: Nil | PlDataTableFilters;\n sorting?: Nil | PTableSorting[];\n}): PTableDefV2<PColumn<Data>> {\n let query: SpecQuery<PColumn<Data>> = {\n type: params.primaryJoinType === \"inner\" ? \"innerJoin\" : \"fullJoin\",\n entries: params.primary.map((a) => toLeaf(a.column, [])),\n };\n\n for (const group of params.secondary) {\n query = {\n type: \"outerJoin\",\n primary: {\n entry: query,\n qualifications: params.primary.flatMap((p) => {\n return group.primaryQualifications?.[p.column.id] ?? [];\n }),\n },\n secondary: group.entries.map((e) => toLeaf(e.column, e.qualifications ?? [])),\n };\n }\n\n if (!isNil(params.filters)) {\n const nonEmpty = distillFilterSpec(params.filters);\n\n if (!isNil(nonEmpty)) {\n const pridicate = filterSpecToSpecQueryExpr(nonEmpty);\n if (!isBooleanExpression(pridicate)) {\n throw new Error(\n `Filter conversion produced a non-boolean expression (got type \"${pridicate.type}\"), expected a boolean predicate for query filtering`,\n );\n }\n query = {\n type: \"filter\",\n input: query,\n predicate: pridicate,\n };\n }\n }\n\n if (!isNil(params.sorting) && params.sorting.length > 0) {\n query = {\n type: \"sort\",\n input: query,\n sortBy: params.sorting.map((s) => ({\n expression: columnIdToExpr(s.column),\n ascending: s.ascending,\n nullsFirst: !s.naAndAbsentAreLeastValues,\n })),\n };\n }\n\n return { query };\n}\n\nfunction columnIdToExpr(col: PTableColumnId): SpecQueryExpression {\n return col.type === \"axis\"\n ? { type: \"axisRef\", value: col.id as SingleAxisSelector }\n : { type: \"columnRef\", value: col.id };\n}\n\nfunction toLeaf<Data>(\n col: PColumn<Data>,\n qs: AxisQualification[],\n): SpecQueryJoinEntry<PColumn<Data>> {\n return {\n entry: { type: \"column\", column: col },\n qualifications: qs,\n };\n}\n"],"mappings":";;;;;;AAuCA,SAAgB,kBAA+C,QAMhC;CAC7B,IAAI,QAAkC;EACpC,MAAM,OAAO,oBAAoB,UAAU,cAAc;EACzD,SAAS,OAAO,QAAQ,KAAK,MAAM,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;EACzD;AAED,MAAK,MAAM,SAAS,OAAO,UACzB,SAAQ;EACN,MAAM;EACN,SAAS;GACP,OAAO;GACP,gBAAgB,OAAO,QAAQ,SAAS,MAAM;AAC5C,WAAO,MAAM,wBAAwB,EAAE,OAAO,OAAO,EAAE;KACvD;GACH;EACD,WAAW,MAAM,QAAQ,KAAK,MAAM,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CAAC,CAAC;EAC9E;AAGH,KAAI,CAAC,MAAM,OAAO,QAAQ,EAAE;EAC1B,MAAM,WAAW,kBAAkB,OAAO,QAAQ;AAElD,MAAI,CAAC,MAAM,SAAS,EAAE;GACpB,MAAM,YAAY,0BAA0B,SAAS;AACrD,OAAI,CAAC,oBAAoB,UAAU,CACjC,OAAM,IAAI,MACR,kEAAkE,UAAU,KAAK,sDAClF;AAEH,WAAQ;IACN,MAAM;IACN,OAAO;IACP,WAAW;IACZ;;;AAIL,KAAI,CAAC,MAAM,OAAO,QAAQ,IAAI,OAAO,QAAQ,SAAS,EACpD,SAAQ;EACN,MAAM;EACN,OAAO;EACP,QAAQ,OAAO,QAAQ,KAAK,OAAO;GACjC,YAAY,eAAe,EAAE,OAAO;GACpC,WAAW,EAAE;GACb,YAAY,CAAC,EAAE;GAChB,EAAE;EACJ;AAGH,QAAO,EAAE,OAAO;;AAGlB,SAAS,eAAe,KAA0C;AAChE,QAAO,IAAI,SAAS,SAChB;EAAE,MAAM;EAAW,OAAO,IAAI;EAA0B,GACxD;EAAE,MAAM;EAAa,OAAO,IAAI;EAAI;;AAG1C,SAAS,OACP,KACA,IACmC;AACnC,QAAO;EACL,OAAO;GAAE,MAAM;GAAU,QAAQ;GAAK;EACtC,gBAAgB;EACjB"}
@@ -10,13 +10,14 @@ let _milaboratories_helpers = require("@milaboratories/helpers");
10
10
  let es_toolkit_compat = require("es-toolkit/compat");
11
11
  //#region src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts
12
12
  function createPlDataTableV3(ctx, options) {
13
+ const pframeSpec = ctx.getService("pframeSpec");
13
14
  const state = require_state_migration.upgradePlDataTableStateV2(options.tableState);
14
15
  const primaryJoinType = options.primaryJoinType ?? "full";
15
- const discovered = "discoverColumnOptions" in options ? require_discoverColumns.discoverTableColumnSnaphots(ctx, options.discoverColumnOptions) : options.columns;
16
+ const discovered = (0, _milaboratories_helpers.isPlainObject)(options.columns) ? require_discoverColumns.discoverTableColumnSnaphots(ctx, options.columns) : options.columns;
16
17
  if ((0, _milaboratories_helpers.isNil)(discovered) || discovered.length === 0) return void 0;
17
- const resolved = resolveDiscoveredColumns(splitDiscoveredColumns(discovered), discovered);
18
- const labelColumns = require_labels.getMatchingLabelColumns(resolved.all, require_labels.getAllLabelColumns(ctx));
19
- const annotated = annotateColumnGroups(resolved, labelColumns, require_utils.deriveAllLabels({
18
+ const splited = splitDiscoveredColumns(discovered);
19
+ const labelColumns = require_labels.getMatchingLabelColumns([...splited.direct, ...splited.linked], require_labels.getAllLabelColumns(ctx));
20
+ const derivedLabels = require_utils.deriveAllLabels({
20
21
  columns: discovered.map((dc) => ({
21
22
  id: dc.id,
22
23
  spec: dc.spec,
@@ -27,14 +28,29 @@ function createPlDataTableV3(ctx, options) {
27
28
  includeNativeLabel: true,
28
29
  ...options.labelsOptions
29
30
  }
30
- }), options.columnsDisplayOptions);
31
- const primaryColumnIds = new Set(discovered.filter((dc) => dc.isPrimary).map((dc) => dc.id));
32
- const primaryColumns = annotated.direct.filter((c) => primaryColumnIds.has(c.id));
33
- const secondaryColumns = annotated.direct.filter((c) => !primaryColumnIds.has(c.id));
34
- if (primaryColumns.length === 0) return void 0;
31
+ });
32
+ const derivedTooltips = require_utils.deriveAllTooltips({ columns: discovered.map((dc) => ({
33
+ id: dc.id,
34
+ originalId: dc.originalId,
35
+ spec: dc.spec,
36
+ linkerPath: dc.linkerPath,
37
+ qualifications: dc.qualifications,
38
+ distinctiveQualifications: dc.distinctiveQualifications
39
+ })) });
40
+ const annotated = annotateColumnGroups({
41
+ pframeSpec,
42
+ ...splited,
43
+ labelColumns,
44
+ derivedLabels,
45
+ derivedTooltips,
46
+ displayOptions: options.displayOptions
47
+ });
48
+ const primarySnapshots = annotated.direct.filter((c) => c.isPrimary);
49
+ const secondarySnapshots = annotated.direct.filter((c) => !c.isPrimary);
50
+ if (primarySnapshots.length === 0) return void 0;
35
51
  const columnIsAvailable = createColumnValidationById([
36
52
  ...annotated.direct,
37
- ...annotated.linked.flatMap((lc) => [...annotated.linkers.get(lc.id) ?? [], lc]),
53
+ ...annotated.linked.flatMap((lc) => [...(lc.linkerPath ?? []).map((s) => s.linker), lc]),
38
54
  ...annotated.labels
39
55
  ]);
40
56
  const remapedDefaultFilters = remapFilterColumnIds(options.filters, discovered);
@@ -42,37 +58,27 @@ function createPlDataTableV3(ctx, options) {
42
58
  validateFilters(filters, columnIsAvailable);
43
59
  const sorting = resolveSorting(state.pTableParams.sorting, remapSortingColumnIds(options.sorting, discovered));
44
60
  validateSorting(sorting, columnIsAvailable);
61
+ const primaryEntries = primarySnapshots.map((snap) => ({ column: resolveSnapshot(snap) }));
45
62
  const fullDef = require_createPTableDefV3.createPTableDefV3({
46
63
  primaryJoinType,
47
- primaryColumns,
48
- secondaryGroups: [
49
- ...secondaryColumns.map((c) => [c]),
50
- ...annotated.linked.map((lc) => [...annotated.linkers.get(lc.id) ?? [], lc]),
51
- ...annotated.labels.map((c) => [c])
52
- ],
64
+ primary: primaryEntries,
65
+ secondary: buildSecondaryGroups(secondarySnapshots, annotated.linked, annotated.labels),
53
66
  filters,
54
67
  sorting
55
68
  });
56
69
  const fullHandle = ctx.createPTableV2(fullDef);
57
70
  const pframeHandle = ctx.createPFrame([
58
- ...annotated.direct,
59
- ...annotated.linked,
71
+ ...annotated.direct.map(resolveSnapshot),
72
+ ...annotated.linked.map(resolveSnapshot),
60
73
  ...annotated.labels,
61
- ...(0, _milaboratories_pl_model_common.uniqueBy)([...annotated.linkers.values()].flat(), (c) => c.id)
74
+ ...collectLinkerSnapshots(annotated.linked).map(resolveSnapshot)
62
75
  ]);
63
76
  const hiddenSpecs = state.pTableParams.hiddenColIds;
64
- const hiddenColumnIds = computeHiddenColumns([...annotated.direct, ...annotated.linked], sorting, filters, hiddenSpecs);
65
- const visible = buildVisibleColumns(annotated, hiddenColumnIds, labelColumns);
66
- const visibleNonCoreDirect = secondaryColumns.filter((c) => !hiddenColumnIds.has(c.id));
67
- const visibleLinkedGroups = buildVisibleLinkedGroups(visible.direct, visible.linked, annotated.linkers, hiddenSpecs);
77
+ const visible = buildVisibleColumns(annotated, computeHiddenColumns([...annotated.direct, ...annotated.linked], sorting, filters, hiddenSpecs), labelColumns);
68
78
  const visibleDef = require_createPTableDefV3.createPTableDefV3({
69
79
  primaryJoinType,
70
- primaryColumns,
71
- secondaryGroups: [
72
- ...visibleNonCoreDirect.map((c) => [c]),
73
- ...visibleLinkedGroups,
74
- ...visible.labels.map((c) => [c])
75
- ],
80
+ primary: primaryEntries,
81
+ secondary: buildSecondaryGroups(visible.direct.filter((c) => !c.isPrimary), visible.linked, visible.labels),
76
82
  filters,
77
83
  sorting
78
84
  });
@@ -92,26 +98,52 @@ function splitDiscoveredColumns(columns) {
92
98
  linked: columns.filter((dc) => !(0, _milaboratories_helpers.isNil)(dc.linkerPath) && dc.linkerPath.length > 0)
93
99
  };
94
100
  }
95
- /** Resolve DiscoveredColumn snapshots into PColumn objects with lazily-evaluated data. */
96
- function resolveDiscoveredColumns(split, allDiscovered) {
97
- const linked = split.linked.map(resolveSnapshot);
98
- const linkers = new Map(split.linked.filter((dc) => !(0, _milaboratories_helpers.isNil)(dc.linkerPath)).map((dc, i) => [linked[i].id, dc.linkerPath.map((s) => resolveSnapshot(s.linker))]));
99
- return {
100
- all: allDiscovered.map(resolveSnapshot),
101
- direct: split.direct.map(resolveSnapshot),
102
- linked,
103
- linkers
104
- };
101
+ /** All linker snapshots across the given linked columns, deduped by id. */
102
+ function collectLinkerSnapshots(linked) {
103
+ return (0, _milaboratories_pl_model_common.uniqueBy)(linked.flatMap((lc) => (lc.linkerPath ?? []).map((s) => s.linker)), (c) => c.id);
105
104
  }
106
- /** Annotate all column groups with derived labels and display options. */
107
- function annotateColumnGroups(resolved, labelColumns, derivedLabels, displayOptions) {
105
+ /**
106
+ * Annotate all column groups with derived labels and display-rule annotations.
107
+ * Evaluates `displayOptions` rules against all discovered columns (direct,
108
+ * linked, labels, linkers) and writes the winning visibility/priority into
109
+ * column annotations via `withTableVisualAnnotations`.
110
+ */
111
+ function annotateColumnGroups(params) {
112
+ const { direct, linked, labelColumns, derivedLabels, derivedTooltips, displayOptions, pframeSpec } = params;
113
+ const allColumnsForRules = [
114
+ ...direct,
115
+ ...linked,
116
+ ...labelColumns,
117
+ ...collectLinkerSnapshots(linked)
118
+ ];
119
+ const visibilityByColId = require_utils.evaluateRules(displayOptions?.visibility ?? [], allColumnsForRules, pframeSpec);
120
+ const orderByColId = require_utils.evaluateRules(displayOptions?.ordering ?? [], allColumnsForRules, pframeSpec);
108
121
  return {
109
- direct: require_utils.withTableVisualAnnotations(displayOptions, require_utils.withLabelAnnotations(derivedLabels, resolved.direct)),
110
- linked: require_utils.withTableVisualAnnotations(displayOptions, require_utils.withLabelAnnotations(derivedLabels, resolved.linked)),
111
- linkers: new Map([...resolved.linkers].map(([id, cols]) => [id, require_utils.withLabelAnnotations(derivedLabels, cols)])),
122
+ direct: [
123
+ require_utils.withLabelAnnotations.bind(null, derivedLabels),
124
+ require_utils.withInfoAnnotations.bind(null, derivedTooltips),
125
+ require_utils.withTableVisualAnnotations.bind(null, visibilityByColId, orderByColId)
126
+ ].reduce((cols, fn) => fn(cols), direct),
127
+ linked: [
128
+ require_utils.withLabelAnnotations.bind(null, derivedLabels),
129
+ require_utils.withInfoAnnotations.bind(null, derivedTooltips),
130
+ require_utils.withTableVisualAnnotations.bind(null, visibilityByColId, orderByColId),
131
+ (cols) => cols.map((lc) => ({
132
+ ...lc,
133
+ linkerPath: annotateLinkerPath(derivedLabels, lc.linkerPath)
134
+ }))
135
+ ].reduce((cols, fn) => fn(cols), linked),
112
136
  labels: require_utils.withLabelAnnotations(derivedLabels, labelColumns)
113
137
  };
114
138
  }
139
+ function annotateLinkerPath(derivedLabels, path) {
140
+ if ((0, _milaboratories_helpers.isNil)(path) || path.length === 0) return path;
141
+ const annotatedLinkers = require_utils.withHidenAxesAnnotations(require_utils.withLabelAnnotations(derivedLabels, path.map((s) => s.linker)));
142
+ return path.map((s, i) => ({
143
+ ...s,
144
+ linker: annotatedLinkers[i]
145
+ }));
146
+ }
115
147
  /** Build an index of all valid column IDs (axes + columns) for filter/sorting validation. */
116
148
  function createColumnValidationById(fullColumns) {
117
149
  const allIds = [...(0, _milaboratories_pl_model_common.uniqueBy)(fullColumns.flatMap((c) => c.spec.axesSpec.map(_milaboratories_pl_model_common.getAxisId)), (a) => (0, _milaboratories_pl_model_common.canonicalizeJson)(a)).map((a) => ({
@@ -150,6 +182,28 @@ function validateSorting(sorting, isValidColumnId) {
150
182
  const firstInvalid = sorting.find((s) => !isValidColumnId((0, _milaboratories_pl_model_common.canonicalizeJson)(s.column)));
151
183
  if (firstInvalid !== void 0) throw new Error(`Invalid sorting column ${JSON.stringify(firstInvalid.column)}: column reference does not match the table columns`);
152
184
  }
185
+ function buildSecondaryGroups(direct, linked, labels) {
186
+ return [
187
+ ...direct.map((c) => ({
188
+ entries: [{
189
+ column: resolveSnapshot(c),
190
+ qualifications: c.qualifications?.forHit
191
+ }],
192
+ primaryQualifications: c.qualifications?.forQueries
193
+ })),
194
+ ...linked.map((lc) => ({
195
+ entries: [...(lc.linkerPath ?? []).map((s) => ({
196
+ column: resolveSnapshot(s.linker),
197
+ qualifications: s.qualifications
198
+ })), {
199
+ column: resolveSnapshot(lc),
200
+ qualifications: lc.qualifications?.forHit
201
+ }],
202
+ primaryQualifications: lc.qualifications?.forQueries
203
+ })),
204
+ ...labels.map((c) => ({ entries: [{ column: c }] }))
205
+ ];
206
+ }
153
207
  /** Determine which columns should be hidden based on state or optional-column defaults. */
154
208
  function computeHiddenColumns(columns, sorting, filters, hiddenSpecs) {
155
209
  const alwaysHidden = columns.filter((c) => require_utils.isColumnHidden(c.spec)).map((c) => c.id);
@@ -158,52 +212,6 @@ function computeHiddenColumns(columns, sorting, filters, hiddenSpecs) {
158
212
  const preserved = collectPreservedColumnIds(sorting, filters);
159
213
  return new Set(initial.filter((id) => !preserved.has(id)));
160
214
  }
161
- /**
162
- * Build visible linked column groups. Non-hidden groups are included fully;
163
- * hidden groups are trimmed to only the prefix that brings axes not yet
164
- * covered by earlier groups (visible or previously trimmed).
165
- */
166
- function buildVisibleLinkedGroups(direct, linked, linkers, hiddenSpecs) {
167
- const result = [];
168
- const coveredAxisIds = /* @__PURE__ */ new Set();
169
- const collectAxes = (group) => {
170
- for (const col of group) for (const as of col.spec.axesSpec) coveredAxisIds.add((0, _milaboratories_pl_model_common.canonicalizeJson)((0, _milaboratories_pl_model_common.getAxisId)(as)));
171
- };
172
- collectAxes(direct);
173
- for (const lc of linked) {
174
- const group = [...linkers.get(lc.id) ?? [], lc];
175
- result.push(group);
176
- collectAxes(group);
177
- }
178
- for (const group of linkers.values()) {
179
- const trimmed = trimGroupByVisibleAxes(group, hiddenSpecs, coveredAxisIds);
180
- if (trimmed.length > 0) {
181
- result.push(trimmed);
182
- collectAxes(trimmed);
183
- }
184
- }
185
- return result;
186
- }
187
- /**
188
- * For a linked column group [linker1, ..., linkerN, column], find the rightmost
189
- * element that has at least one non-hidden and not-yet-covered axis.
190
- * Return the prefix up to and including that element.
191
- * If no element has such an axis, return empty array.
192
- */
193
- function trimGroupByVisibleAxes(group, hiddenSpecs, coveredAxisIds) {
194
- if (hiddenSpecs === null) return group;
195
- const hiddenAxisIds = new Set(hiddenSpecs.filter((s) => s.type === "axis").map((s) => (0, _milaboratories_pl_model_common.canonicalizeJson)(s.id)));
196
- const uncoveredAxisIds = new Set(group.flatMap((c) => c.spec.axesSpec.map((as) => (0, _milaboratories_pl_model_common.canonicalizeJson)((0, _milaboratories_pl_model_common.getAxisId)(as)))).filter((id) => !hiddenAxisIds.has(id) && !coveredAxisIds.has(id)));
197
- let lastNeeded = -1;
198
- for (let i = 0; i < group.length; i++) {
199
- const newAxes = group[i].spec.axesSpec.map((as) => (0, _milaboratories_pl_model_common.canonicalizeJson)((0, _milaboratories_pl_model_common.getAxisId)(as))).filter((id) => uncoveredAxisIds.has(id));
200
- if (newAxes.length > 0) {
201
- for (const id of newAxes) uncoveredAxisIds.delete(id);
202
- lastNeeded = i;
203
- }
204
- }
205
- return lastNeeded === -1 ? [] : group.slice(0, lastNeeded + 1);
206
- }
207
215
  /** Collect IDs of columns that must remain visible (sorted, filtered). */
208
216
  function collectPreservedColumnIds(sorting, filters) {
209
217
  const sortedIds = (sorting ?? []).map((s) => s.column).filter((c) => c.type === "column").map((c) => c.id);
@@ -220,7 +228,7 @@ function buildVisibleColumns(annotated, hiddenColumns, originalLabelColumns) {
220
228
  return {
221
229
  direct,
222
230
  linked,
223
- labels: require_labels.getMatchingLabelColumns([...direct, ...linked].map(_milaboratories_pl_model_common.getColumnIdAndSpec), originalLabelColumns)
231
+ labels: require_labels.getMatchingLabelColumns([...direct, ...linked], originalLabelColumns)
224
232
  };
225
233
  }
226
234
  /** Resolve a ColumnSnapshot to a PColumn with lazily-evaluated data. */
@@ -1 +1 @@
1
- {"version":3,"file":"createPlDataTableV3.cjs","names":["upgradePlDataTableStateV2","discoverTableColumnSnaphots","getMatchingLabelColumns","getAllLabelColumns","deriveAllLabels","createPTableDefV3","withTableVisualAnnotations","withLabelAnnotations","getAxisId","collectFilterSpecColumns","isColumnHidden","isColumnOptional","getColumnIdAndSpec","traverseFilterSpec"],"sources":["../../../../src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts"],"sourcesContent":["import type {\n AxisId,\n CanonicalizedJson,\n FilterSpecNode,\n PColumn,\n PObjectId,\n PTableColumnId,\n PTableColumnIdAxis,\n PTableColumnIdColumn,\n PTableSorting,\n PColumnSpec,\n MultiColumnSelector,\n SUniversalPColumnId,\n} from \"@milaboratories/pl-model-common\";\nimport {\n canonicalizeJson,\n getAxisId,\n getColumnIdAndSpec,\n parseJson,\n uniqueBy,\n} from \"@milaboratories/pl-model-common\";\nimport { collectFilterSpecColumns, traverseFilterSpec } from \"../../../filters/traverse\";\nimport type { RenderCtxBase, PColumnDataUniversal } from \"../../../render\";\nimport { isEmpty } from \"es-toolkit/compat\";\nimport type { PlDataTableFilters, PlDataTableFilterSpecLeaf, PlDataTableModel } from \"../typesV5\";\nimport { upgradePlDataTableStateV2 } from \"../state-migration\";\nimport type { PlDataTableStateV2 } from \"../state-migration\";\nimport type { ColumnMatch, ColumnSnapshot, MatchingMode } from \"../../../columns\";\nimport { Services, type RequireServices } from \"@milaboratories/pl-model-common\";\nimport { getAllLabelColumns, getMatchingLabelColumns } from \"../labels\";\nimport type { DeriveLabelsOptions } from \"../../../labels/derive_distinct_labels\";\nimport {\n deriveAllLabels,\n isColumnHidden,\n isColumnOptional,\n withLabelAnnotations,\n withTableVisualAnnotations,\n} from \"./utils\";\nimport { createPTableDefV3 } from \"./createPTableDefV3\";\nimport { discoverTableColumnSnaphots, type DiscoveredTableColumnOptions } from \"./discoverColumns\";\nimport { isNil, RequiredBy, throwError, type Nil } from \"@milaboratories/helpers\";\n\nexport type createPlDataTableOptionsV3 = (\n | {\n discoverColumnOptions: DiscoveredTableColumnOptions;\n }\n | {\n columns: Nil | TableColumnSnapshot<SUniversalPColumnId>[];\n }\n) & {\n filters?: PlDataTableFilters;\n sorting?: PTableSorting[];\n primaryJoinType?: \"inner\" | \"full\";\n\n tableState?: PlDataTableStateV2;\n labelsOptions?: DeriveLabelsOptions;\n columnsDisplayOptions?: ColumnsDisplayOptions;\n};\n\n/** Structured source config — selectors/anchors instead of raw ColumnSource. */\nexport type ColumnsSelectorConfig = {\n include?: MultiColumnSelector | MultiColumnSelector[];\n exclude?: MultiColumnSelector | MultiColumnSelector[];\n mode?: MatchingMode;\n maxHops?: number;\n};\n\nexport type ColumnsDisplayOptions = {\n /** Column ordering rules. Higher priority = further left. First matching rule wins. */\n ordering?: ColumnOrderRule[];\n /** Column visibility rules. First matching rule wins. Unmatched columns use default visibility. */\n visibility?: ColumnVisibilityRule[];\n};\n\nexport type ColumnOrderRule = {\n match: ColumnMatcher;\n /** Higher number = further left in table */\n priority: number;\n};\n\nexport type ColumnVisibilityRule = {\n match: ColumnMatcher;\n visibility: \"default\" | \"optional\" | \"hidden\";\n};\n\nexport type ColumnMatcher = (spec: PColumnSpec) => boolean;\n\n// Main Function\n\nexport function createPlDataTableV3<A, U, S extends RequireServices<typeof Services.PFrameSpec>>(\n ctx: RenderCtxBase<A, U, S>,\n options: createPlDataTableOptionsV3,\n): PlDataTableModel | undefined {\n const state = upgradePlDataTableStateV2(options.tableState);\n const primaryJoinType = options.primaryJoinType ?? \"full\";\n\n const discovered =\n \"discoverColumnOptions\" in options\n ? discoverTableColumnSnaphots(ctx, options.discoverColumnOptions)\n : options.columns;\n if (isNil(discovered) || discovered.length === 0) return undefined;\n\n const splited = splitDiscoveredColumns(discovered);\n const resolved = resolveDiscoveredColumns(splited, discovered);\n\n const labelColumns = getMatchingLabelColumns(resolved.all, getAllLabelColumns(ctx));\n\n const derivedLabels = deriveAllLabels({\n columns: discovered.map((dc) => ({\n id: dc.id,\n spec: dc.spec,\n linkerPath: dc.linkerPath?.map((lp) => ({ spec: lp.linker.spec })),\n })),\n labelColumns,\n deriveLabelsOptions: {\n includeNativeLabel: true,\n ...options.labelsOptions,\n },\n });\n\n const annotated = annotateColumnGroups(\n resolved,\n labelColumns,\n derivedLabels,\n options.columnsDisplayOptions,\n );\n\n const primaryColumnIds = new Set<PObjectId>(\n discovered.filter((dc) => dc.isPrimary).map((dc) => dc.id),\n );\n const primaryColumns = annotated.direct.filter((c) => primaryColumnIds.has(c.id));\n const secondaryColumns = annotated.direct.filter((c) => !primaryColumnIds.has(c.id));\n\n if (primaryColumns.length === 0) return undefined;\n\n const columnIsAvailable = createColumnValidationById([\n ...annotated.direct,\n ...annotated.linked.flatMap((lc) => [...(annotated.linkers.get(lc.id) ?? []), lc]),\n ...annotated.labels,\n ]);\n\n const remapedDefaultFilters = remapFilterColumnIds(options.filters, discovered);\n const filters = concatFilters(\n state.pTableParams.filters,\n state.pTableParams.defaultFilters ?? remapedDefaultFilters,\n );\n validateFilters(filters, columnIsAvailable);\n\n const sorting = resolveSorting(\n state.pTableParams.sorting,\n remapSortingColumnIds(options.sorting, discovered),\n );\n validateSorting(sorting, columnIsAvailable);\n\n const fullDef = createPTableDefV3({\n primaryJoinType,\n primaryColumns,\n secondaryGroups: [\n ...secondaryColumns.map((c) => [c]),\n ...annotated.linked.map((lc) => [...(annotated.linkers.get(lc.id) ?? []), lc]),\n ...annotated.labels.map((c) => [c]),\n ],\n filters,\n sorting,\n });\n\n const fullHandle = ctx.createPTableV2(fullDef);\n const pframeHandle = ctx.createPFrame([\n ...annotated.direct,\n ...annotated.linked,\n ...annotated.labels,\n ...uniqueBy([...annotated.linkers.values()].flat(), (c) => c.id),\n ]);\n\n const hiddenSpecs = state.pTableParams.hiddenColIds;\n const hiddenColumnIds = computeHiddenColumns(\n [...annotated.direct, ...annotated.linked],\n sorting,\n filters,\n hiddenSpecs,\n );\n\n const visible = buildVisibleColumns(annotated, hiddenColumnIds, labelColumns);\n const visibleNonCoreDirect = secondaryColumns.filter((c) => !hiddenColumnIds.has(c.id));\n const visibleLinkedGroups = buildVisibleLinkedGroups(\n visible.direct,\n visible.linked,\n annotated.linkers,\n hiddenSpecs,\n );\n\n const visibleDef = createPTableDefV3({\n primaryJoinType,\n primaryColumns,\n secondaryGroups: [\n ...visibleNonCoreDirect.map((c) => [c]),\n ...visibleLinkedGroups,\n ...visible.labels.map((c) => [c]),\n ],\n filters,\n sorting,\n });\n const visibleHandle = ctx.createPTableV2(visibleDef);\n\n return {\n sourceId: state.pTableParams.sourceId,\n fullTableHandle: fullHandle,\n fullPframeHandle: pframeHandle,\n visibleTableHandle: visibleHandle,\n defaultFilters: remapedDefaultFilters,\n } satisfies PlDataTableModel;\n}\n\n/** A single column discovered from sources — normalized from raw ColumnSnapshot/ColumnMatch. */\nexport type TableColumnSnapshot<Id extends PObjectId | SUniversalPColumnId> = ColumnSnapshot<Id> & {\n readonly isPrimary?: boolean;\n readonly originalId?: PObjectId;\n readonly linkerPath?: ColumnMatch[\"path\"];\n};\n\ntype TableColumn = PColumn<undefined | PColumnDataUniversal>;\n\ntype SplitDiscoveredColumns = {\n readonly direct: TableColumnSnapshot<SUniversalPColumnId>[];\n readonly linked: TableColumnSnapshot<SUniversalPColumnId>[];\n};\n\ntype ResolvedColumns = {\n readonly direct: TableColumn[];\n readonly linked: TableColumn[];\n readonly linkers: Map<PObjectId, TableColumn[]>;\n readonly all: TableColumn[];\n};\n\ntype AnnotatedColumnGroups = {\n readonly direct: TableColumn[];\n readonly linked: TableColumn[];\n readonly linkers: Map<PObjectId, TableColumn[]>;\n readonly labels: TableColumn[];\n};\n\ntype VisibleColumns = {\n readonly direct: TableColumn[];\n readonly linked: TableColumn[];\n readonly labels: PColumn<PColumnDataUniversal>[];\n};\n\n/** Split discovered columns into direct (no linker path) and linked (with linker path). */\nfunction splitDiscoveredColumns(\n columns: TableColumnSnapshot<SUniversalPColumnId>[],\n): SplitDiscoveredColumns {\n return {\n direct: columns.filter((dc) => isNil(dc.linkerPath) || dc.linkerPath.length === 0),\n linked: columns.filter((dc) => !isNil(dc.linkerPath) && dc.linkerPath.length > 0),\n };\n}\n\n/** Resolve DiscoveredColumn snapshots into PColumn objects with lazily-evaluated data. */\nfunction resolveDiscoveredColumns(\n split: SplitDiscoveredColumns,\n allDiscovered: TableColumnSnapshot<SUniversalPColumnId>[],\n): ResolvedColumns {\n const linked = split.linked.map(resolveSnapshot);\n const linkers = new Map<PObjectId, TableColumn[]>(\n split.linked\n .filter(\n (dc): dc is RequiredBy<TableColumnSnapshot<SUniversalPColumnId>, \"linkerPath\"> =>\n !isNil(dc.linkerPath),\n )\n .map((dc, i) => [linked[i].id, dc.linkerPath.map((s) => resolveSnapshot(s.linker))]),\n );\n\n return {\n all: allDiscovered.map(resolveSnapshot),\n direct: split.direct.map(resolveSnapshot),\n linked,\n linkers,\n };\n}\n\n/** Annotate all column groups with derived labels and display options. */\nfunction annotateColumnGroups(\n resolved: ResolvedColumns,\n labelColumns: PColumn<PColumnDataUniversal>[],\n derivedLabels: Record<string, string>,\n displayOptions: ColumnsDisplayOptions | undefined,\n): AnnotatedColumnGroups {\n const direct = withTableVisualAnnotations(\n displayOptions,\n withLabelAnnotations(derivedLabels, resolved.direct),\n );\n const linked = withTableVisualAnnotations(\n displayOptions,\n withLabelAnnotations(derivedLabels, resolved.linked),\n );\n const linkers = new Map<PObjectId, TableColumn[]>(\n [...resolved.linkers].map(([id, cols]) => [id, withLabelAnnotations(derivedLabels, cols)]),\n );\n const labels = withLabelAnnotations(derivedLabels, labelColumns);\n\n return { direct, linked, linkers, labels };\n}\n\n/** Build an index of all valid column IDs (axes + columns) for filter/sorting validation. */\nfunction createColumnValidationById(fullColumns: TableColumn[]) {\n const axisIds = uniqueBy(\n fullColumns.flatMap((c) => c.spec.axesSpec.map(getAxisId)),\n (a) => canonicalizeJson<AxisId>(a),\n );\n\n const allIds: PTableColumnId[] = [\n ...axisIds.map((a) => ({ type: \"axis\", id: a }) satisfies PTableColumnIdAxis),\n ...fullColumns.map((c) => ({ type: \"column\", id: c.id }) satisfies PTableColumnIdColumn),\n ];\n\n const validIdSet = new Set(allIds.map((c) => canonicalizeJson<PTableColumnId>(c)));\n\n return (id: string): boolean => {\n return validIdSet.has(id as CanonicalizedJson<PTableColumnId>);\n };\n}\n\n/** Validate that all column references in filters exist in the table. */\nfunction validateFilters(\n filters: Nil | PlDataTableFilters,\n isValidColumnId: (id: string) => boolean,\n): void {\n if (filters == null) return;\n const filterColumns = collectFilterSpecColumns(filters);\n const firstInvalid = filterColumns.find((col) => !isValidColumnId(col));\n if (firstInvalid !== undefined) {\n throw new Error(\n `Invalid filter column ${firstInvalid}: column reference does not match the table columns`,\n );\n }\n}\n\n/** Merge two filter trees into one AND-combined tree. Returns the non-nil one if the other is nil. */\nfunction concatFilters(\n a: Nil | PlDataTableFilters,\n b: Nil | PlDataTableFilters,\n): Nil | PlDataTableFilters {\n if (isNil(a)) return b;\n if (isNil(b)) return a;\n return { ...a, filters: [...a.filters, ...b.filters] };\n}\n\n/** Pick user sorting from state if non-empty, otherwise fall back to options default. */\nfunction resolveSorting(\n userSorting: PTableSorting[],\n defaultSorting: Nil | PTableSorting[],\n): PTableSorting[] {\n return (isEmpty(userSorting) ? defaultSorting : userSorting) ?? [];\n}\n\n/** Validate that all column references in sorting exist in the table. */\nfunction validateSorting(sorting: PTableSorting[], isValidColumnId: (id: string) => boolean): void {\n const firstInvalid = sorting.find(\n (s) => !isValidColumnId(canonicalizeJson<PTableColumnId>(s.column)),\n );\n if (firstInvalid !== undefined) {\n throw new Error(\n `Invalid sorting column ${JSON.stringify(firstInvalid.column)}: column reference does not match the table columns`,\n );\n }\n}\n\n/** Determine which columns should be hidden based on state or optional-column defaults. */\nfunction computeHiddenColumns(\n columns: TableColumn[],\n sorting: Nil | PTableSorting[],\n filters: Nil | PlDataTableFilters,\n hiddenSpecs: Nil | PTableColumnId[],\n): Set<PObjectId> {\n const alwaysHidden = columns.filter((c) => isColumnHidden(c.spec)).map((c) => c.id);\n const optionalHidden = !isNil(hiddenSpecs)\n ? hiddenSpecs.filter((s): s is PTableColumnIdColumn => s.type === \"column\").map((s) => s.id)\n : columns.filter((c) => isColumnOptional(c.spec)).map((c) => c.id);\n const initial = [...alwaysHidden, ...optionalHidden];\n const preserved = collectPreservedColumnIds(sorting, filters);\n\n return new Set(initial.filter((id) => !preserved.has(id)));\n}\n\n/**\n * Build visible linked column groups. Non-hidden groups are included fully;\n * hidden groups are trimmed to only the prefix that brings axes not yet\n * covered by earlier groups (visible or previously trimmed).\n */\nfunction buildVisibleLinkedGroups(\n direct: TableColumn[],\n linked: TableColumn[],\n linkers: Map<PObjectId, TableColumn[]>,\n hiddenSpecs: PTableColumnId[] | null,\n): TableColumn[][] {\n const result: TableColumn[][] = [];\n const coveredAxisIds = new Set<CanonicalizedJson<AxisId>>();\n\n const collectAxes = (group: TableColumn[]) => {\n for (const col of group) {\n for (const as of col.spec.axesSpec) {\n coveredAxisIds.add(canonicalizeJson(getAxisId(as)));\n }\n }\n };\n\n collectAxes(direct);\n\n for (const lc of linked) {\n const group = [...(linkers.get(lc.id) ?? []), lc];\n result.push(group);\n collectAxes(group);\n }\n\n for (const group of linkers.values()) {\n const trimmed = trimGroupByVisibleAxes(group, hiddenSpecs, coveredAxisIds);\n if (trimmed.length > 0) {\n result.push(trimmed);\n collectAxes(trimmed);\n }\n }\n\n return result;\n}\n\n/**\n * For a linked column group [linker1, ..., linkerN, column], find the rightmost\n * element that has at least one non-hidden and not-yet-covered axis.\n * Return the prefix up to and including that element.\n * If no element has such an axis, return empty array.\n */\nfunction trimGroupByVisibleAxes(\n group: TableColumn[],\n hiddenSpecs: PTableColumnId[] | null,\n coveredAxisIds: Set<CanonicalizedJson<AxisId>>,\n): TableColumn[] {\n if (hiddenSpecs === null) return group;\n\n const hiddenAxisIds = new Set(\n hiddenSpecs\n .filter((s): s is PTableColumnIdAxis => s.type === \"axis\")\n .map((s) => canonicalizeJson(s.id)),\n );\n\n const uncoveredAxisIds = new Set(\n group\n .flatMap((c) => c.spec.axesSpec.map((as) => canonicalizeJson(getAxisId(as))))\n .filter((id) => !hiddenAxisIds.has(id) && !coveredAxisIds.has(id)),\n );\n\n let lastNeeded = -1;\n for (let i = 0; i < group.length; i++) {\n const newAxes = group[i].spec.axesSpec\n .map((as) => canonicalizeJson(getAxisId(as)))\n .filter((id) => uncoveredAxisIds.has(id));\n if (newAxes.length > 0) {\n for (const id of newAxes) uncoveredAxisIds.delete(id);\n lastNeeded = i;\n }\n }\n return lastNeeded === -1 ? [] : group.slice(0, lastNeeded + 1);\n}\n\n/** Collect IDs of columns that must remain visible (sorted, filtered). */\nfunction collectPreservedColumnIds(\n sorting: Nil | PTableSorting[],\n filters: Nil | PlDataTableFilters,\n): Set<PObjectId> {\n const sortedIds = (sorting ?? [])\n .map((s) => s.column)\n .filter((c): c is PTableColumnIdColumn => c.type === \"column\")\n .map((c) => c.id);\n\n const filterIds = !isNil(filters)\n ? collectFilterSpecColumns(filters).flatMap((c) => {\n const obj = parseJson(c);\n return obj.type === \"column\" ? [obj.id] : [];\n })\n : [];\n\n return new Set<PObjectId>([...sortedIds, ...filterIds]);\n}\n\n/** Filter annotated columns to only visible ones, re-matching label columns for the visible subset. */\nfunction buildVisibleColumns(\n annotated: AnnotatedColumnGroups,\n hiddenColumns: Set<PObjectId>,\n originalLabelColumns: PColumn<PColumnDataUniversal>[],\n): VisibleColumns {\n const direct = annotated.direct.filter((c) => !hiddenColumns.has(c.id));\n const linked = annotated.linked.filter((c) => !hiddenColumns.has(c.id));\n const labels = getMatchingLabelColumns(\n [...direct, ...linked].map(getColumnIdAndSpec),\n originalLabelColumns,\n );\n return { direct, linked, labels };\n}\n\n/** Resolve a ColumnSnapshot to a PColumn with lazily-evaluated data. */\nfunction resolveSnapshot(\n snap: ColumnSnapshot<PObjectId>,\n): PColumn<undefined | PColumnDataUniversal> {\n return { id: snap.id, spec: snap.spec, data: snap.data?.get() };\n}\n\n/** Remap column references in sorting entries. */\nfunction remapSortingColumnIds(\n sorting: Nil | PTableSorting[],\n columns: TableColumnSnapshot<PObjectId | SUniversalPColumnId>[],\n): Nil | PTableSorting[] {\n return sorting?.map((s) => {\n if (s.column.type === \"axis\") return s; // Axis references are unaffected by column ID remapping\n\n const id = s.column.id;\n const column =\n columns.find((c) => (c.originalId ?? c.id) === id) ??\n throwError(`Column ID \"${id}\" in sorting does not match any discovered column`);\n\n return {\n ...s,\n column: {\n type: \"column\",\n id: column.id,\n },\n };\n });\n}\n\ntype PlDataTableFilterNode = FilterSpecNode<PlDataTableFilterSpecLeaf>;\n\n/** Remap column references in a filter tree. */\nfunction remapFilterColumnIds(\n filters: Nil | PlDataTableFilters,\n columns: TableColumnSnapshot<PObjectId | SUniversalPColumnId>[],\n): Nil | PlDataTableFilters {\n if (isNil(filters)) return filters;\n\n const map = (\n tableColumnId: CanonicalizedJson<PTableColumnId>,\n ): CanonicalizedJson<PTableColumnId> => {\n const parsed = parseJson<PTableColumnId>(tableColumnId);\n if (parsed.type === \"axis\") return tableColumnId; // Axis references are unaffected by column ID remapping\n\n const originalId = parsed.id;\n const column =\n columns.find((c) => (c.originalId ?? c.id) === originalId) ??\n throwError(`Column ID \"${parsed.id}\" in filters does not match any discovered column`);\n\n return canonicalizeJson<PTableColumnId>({\n type: \"column\",\n id: column.id,\n });\n };\n\n return traverseFilterSpec(filters, {\n leaf: (leaf): PlDataTableFilterNode => {\n if (leaf.type === undefined) return leaf;\n const result = { ...leaf };\n if (\"column\" in result) result.column = map(result.column);\n if (\"rhs\" in result) result.rhs = map(result.rhs);\n return result;\n },\n and: (results): PlDataTableFilterNode => ({ type: \"and\", filters: results }),\n or: (results): PlDataTableFilterNode => ({ type: \"or\", filters: results }),\n not: (result): PlDataTableFilterNode => ({ type: \"not\", filter: result }),\n }) as PlDataTableFilters;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"createPlDataTableV3.cjs","names":["upgradePlDataTableStateV2","discoverTableColumnSnaphots","getMatchingLabelColumns","getAllLabelColumns","deriveAllLabels","deriveAllTooltips","createPTableDefV3","evaluateRules","withLabelAnnotations","withInfoAnnotations","withTableVisualAnnotations","withHidenAxesAnnotations","getAxisId","collectFilterSpecColumns","isColumnHidden","isColumnOptional","traverseFilterSpec"],"sources":["../../../../src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts"],"sourcesContent":["import type {\n AxisId,\n CanonicalizedJson,\n FilterSpecNode,\n PColumn,\n PObjectId,\n PTableColumnId,\n PTableColumnIdAxis,\n PTableColumnIdColumn,\n PTableSorting,\n PColumnSpec,\n MultiColumnSelector,\n PFrameSpecDriver,\n DiscoveredPColumnId,\n} from \"@milaboratories/pl-model-common\";\nimport { canonicalizeJson, getAxisId, parseJson, uniqueBy } from \"@milaboratories/pl-model-common\";\nimport { collectFilterSpecColumns, traverseFilterSpec } from \"../../../filters/traverse\";\nimport type { RenderCtxBase, PColumnDataUniversal } from \"../../../render\";\nimport { isEmpty } from \"es-toolkit/compat\";\nimport type { PlDataTableFilters, PlDataTableFilterSpecLeaf, PlDataTableModel } from \"../typesV5\";\nimport { upgradePlDataTableStateV2 } from \"../state-migration\";\nimport type { PlDataTableStateV2 } from \"../state-migration\";\nimport type {\n ColumnSelector,\n ColumnSnapshot,\n MatchingMode,\n MatchQualifications,\n MatchVariant,\n} from \"../../../columns\";\nimport { getAllLabelColumns, getMatchingLabelColumns } from \"../labels\";\nimport type { DeriveLabelsOptions } from \"../../../labels/derive_distinct_labels\";\nimport {\n deriveAllLabels,\n deriveAllTooltips,\n evaluateRules,\n isColumnHidden,\n isColumnOptional,\n withHidenAxesAnnotations,\n withLabelAnnotations,\n withTableVisualAnnotations,\n withInfoAnnotations,\n} from \"./utils\";\nimport type { PrimaryEntry, SecondaryGroup } from \"./createPTableDefV3\";\nimport { createPTableDefV3 } from \"./createPTableDefV3\";\nimport { discoverTableColumnSnaphots, type DiscoverTableColumnOptions } from \"./discoverColumns\";\nimport { isNil, isPlainObject, throwError, type Nil } from \"@milaboratories/helpers\";\n\nexport type createPlDataTableOptionsV3 = {\n tableState?: PlDataTableStateV2;\n\n columns: Nil | DiscoverTableColumnOptions | TableColumnSnapshot[];\n filters?: PlDataTableFilters;\n sorting?: PTableSorting[];\n primaryJoinType?: \"inner\" | \"full\";\n\n labelsOptions?: DeriveLabelsOptions;\n displayOptions?: ColumnsDisplayOptions;\n};\n\n/** Structured source config — selectors/anchors instead of raw ColumnSource. */\nexport type ColumnsSelectorConfig = {\n include?: MultiColumnSelector | MultiColumnSelector[];\n exclude?: MultiColumnSelector | MultiColumnSelector[];\n mode?: MatchingMode;\n maxHops?: number;\n};\n\nexport type ColumnsDisplayOptions = {\n /** Column ordering rules. Higher priority = further left. First matching rule wins. */\n ordering?: ColumnOrderRule[];\n /** Column visibility rules. First matching rule wins. Unmatched columns use default visibility. */\n visibility?: ColumnVisibilityRule[];\n};\n\nexport type ColumnOrderRule = {\n match: ColumnMatcher | ColumnSelector;\n /** Higher number = further left in table */\n priority: number;\n};\n\nexport type ColumnVisibilityRule = {\n match: ColumnMatcher | ColumnSelector;\n visibility: \"default\" | \"optional\" | \"hidden\";\n};\n\nexport type ColumnMatcher = (spec: PColumnSpec) => boolean;\n\n// Main Function\n\nexport function createPlDataTableV3<A, U>(\n ctx: RenderCtxBase<A, U>,\n options: createPlDataTableOptionsV3,\n): PlDataTableModel | undefined {\n const pframeSpec = ctx.getService(\"pframeSpec\");\n const state = upgradePlDataTableStateV2(options.tableState);\n const primaryJoinType = options.primaryJoinType ?? \"full\";\n\n const discovered = isPlainObject(options.columns)\n ? discoverTableColumnSnaphots(ctx, options.columns)\n : options.columns;\n if (isNil(discovered) || discovered.length === 0) return undefined;\n\n const splited = splitDiscoveredColumns(discovered);\n\n const labelColumns = getMatchingLabelColumns(\n [...splited.direct, ...splited.linked],\n getAllLabelColumns(ctx),\n );\n\n const derivedLabels = deriveAllLabels({\n columns: discovered.map((dc) => ({\n id: dc.id,\n spec: dc.spec,\n linkerPath: dc.linkerPath?.map((lp) => ({ spec: lp.linker.spec })),\n })),\n labelColumns,\n deriveLabelsOptions: {\n includeNativeLabel: true,\n ...options.labelsOptions,\n },\n });\n\n const derivedTooltips = deriveAllTooltips({\n columns: discovered.map((dc) => ({\n id: dc.id,\n originalId: dc.originalId,\n spec: dc.spec,\n linkerPath: dc.linkerPath,\n qualifications: dc.qualifications,\n distinctiveQualifications: dc.distinctiveQualifications,\n })),\n });\n\n const annotated = annotateColumnGroups({\n pframeSpec,\n ...splited,\n labelColumns,\n derivedLabels,\n derivedTooltips,\n displayOptions: options.displayOptions,\n });\n\n const primarySnapshots = annotated.direct.filter((c) => c.isPrimary);\n const secondarySnapshots = annotated.direct.filter((c) => !c.isPrimary);\n\n if (primarySnapshots.length === 0) return undefined;\n\n const columnIsAvailable = createColumnValidationById([\n ...annotated.direct,\n ...annotated.linked.flatMap((lc) => [...(lc.linkerPath ?? []).map((s) => s.linker), lc]),\n ...annotated.labels,\n ]);\n\n const remapedDefaultFilters = remapFilterColumnIds(options.filters, discovered);\n const filters = concatFilters(\n state.pTableParams.filters,\n state.pTableParams.defaultFilters ?? remapedDefaultFilters,\n );\n validateFilters(filters, columnIsAvailable);\n\n const sorting = resolveSorting(\n state.pTableParams.sorting,\n remapSortingColumnIds(options.sorting, discovered),\n );\n validateSorting(sorting, columnIsAvailable);\n\n const primaryEntries: PrimaryEntry<undefined | PColumnDataUniversal>[] = primarySnapshots.map(\n (snap) => ({ column: resolveSnapshot(snap) }),\n );\n const fullDef = createPTableDefV3({\n primaryJoinType,\n primary: primaryEntries,\n secondary: buildSecondaryGroups(secondarySnapshots, annotated.linked, annotated.labels),\n filters,\n sorting,\n });\n\n const fullHandle = ctx.createPTableV2(fullDef);\n // TODO: is workaround for dropdown suggestions.\n // Pframe have not equivalent data for columns relativly to Ptable\n const pframeHandle = ctx.createPFrame([\n ...annotated.direct.map(resolveSnapshot),\n ...annotated.linked.map(resolveSnapshot),\n ...annotated.labels,\n ...collectLinkerSnapshots(annotated.linked).map(resolveSnapshot),\n ]);\n\n const hiddenSpecs = state.pTableParams.hiddenColIds;\n const hiddenColumnIds = computeHiddenColumns(\n [...annotated.direct, ...annotated.linked],\n sorting,\n filters,\n hiddenSpecs,\n );\n\n const visible = buildVisibleColumns(annotated, hiddenColumnIds, labelColumns);\n const visibleDef = createPTableDefV3({\n primaryJoinType,\n primary: primaryEntries,\n secondary: buildSecondaryGroups(\n visible.direct.filter((c) => !c.isPrimary),\n visible.linked,\n visible.labels,\n ),\n filters,\n sorting,\n });\n const visibleHandle = ctx.createPTableV2(visibleDef);\n\n return {\n sourceId: state.pTableParams.sourceId,\n fullTableHandle: fullHandle,\n fullPframeHandle: pframeHandle,\n visibleTableHandle: visibleHandle,\n defaultFilters: remapedDefaultFilters,\n } satisfies PlDataTableModel;\n}\n\n/** A single column discovered from sources — normalized from raw ColumnSnapshot/ColumnMatch. */\nexport type TableColumnSnapshot = ColumnSnapshot<DiscoveredPColumnId> & {\n readonly originalId: PObjectId;\n readonly isPrimary?: boolean;\n readonly linkerPath?: MatchVariant[\"path\"];\n readonly qualifications?: MatchQualifications;\n readonly distinctiveQualifications?: MatchQualifications;\n};\n\ntype SplitDiscoveredColumns = {\n readonly direct: TableColumnSnapshot[];\n readonly linked: TableColumnSnapshot[];\n};\n\ntype AnnotatedColumnGroups = {\n readonly direct: TableColumnSnapshot[];\n readonly linked: TableColumnSnapshot[];\n readonly labels: PColumn<PColumnDataUniversal>[];\n};\n\ntype VisibleColumns = {\n readonly direct: TableColumnSnapshot[];\n readonly linked: TableColumnSnapshot[];\n readonly labels: PColumn<PColumnDataUniversal>[];\n};\n\n/** Split discovered columns into direct (no linker path) and linked (with linker path). */\nfunction splitDiscoveredColumns(columns: TableColumnSnapshot[]): SplitDiscoveredColumns {\n const direct = columns.filter((dc) => isNil(dc.linkerPath) || dc.linkerPath.length === 0);\n const linked = columns.filter((dc) => !isNil(dc.linkerPath) && dc.linkerPath.length > 0);\n return { direct, linked };\n}\n\n/** All linker snapshots across the given linked columns, deduped by id. */\nfunction collectLinkerSnapshots(linked: TableColumnSnapshot[]): ColumnSnapshot<PObjectId>[] {\n return uniqueBy(\n linked.flatMap((lc) => (lc.linkerPath ?? []).map((s) => s.linker)),\n (c) => c.id,\n );\n}\n\n/**\n * Annotate all column groups with derived labels and display-rule annotations.\n * Evaluates `displayOptions` rules against all discovered columns (direct,\n * linked, labels, linkers) and writes the winning visibility/priority into\n * column annotations via `withTableVisualAnnotations`.\n */\nfunction annotateColumnGroups(params: {\n direct: TableColumnSnapshot[];\n linked: TableColumnSnapshot[];\n labelColumns: PColumn<PColumnDataUniversal>[];\n derivedLabels: Record<string, string>;\n derivedTooltips: Record<string, string>;\n displayOptions?: ColumnsDisplayOptions;\n pframeSpec: PFrameSpecDriver;\n}): AnnotatedColumnGroups {\n const {\n direct,\n linked,\n labelColumns,\n derivedLabels,\n derivedTooltips,\n displayOptions,\n pframeSpec,\n } = params;\n\n const allColumnsForRules = [\n ...direct,\n ...linked,\n ...labelColumns,\n ...collectLinkerSnapshots(linked),\n ];\n const visibilityByColId = evaluateRules(\n displayOptions?.visibility ?? [],\n allColumnsForRules,\n pframeSpec,\n );\n const orderByColId = evaluateRules(\n displayOptions?.ordering ?? [],\n allColumnsForRules,\n pframeSpec,\n );\n\n const directAnnotated = [\n withLabelAnnotations.bind(null, derivedLabels),\n withInfoAnnotations.bind(null, derivedTooltips),\n withTableVisualAnnotations.bind(null, visibilityByColId, orderByColId),\n ].reduce((cols, fn) => fn(cols) as TableColumnSnapshot[], direct);\n\n const linkedAnnotated = [\n withLabelAnnotations.bind(null, derivedLabels),\n withInfoAnnotations.bind(null, derivedTooltips),\n withTableVisualAnnotations.bind(null, visibilityByColId, orderByColId),\n (cols: TableColumnSnapshot[]) =>\n cols.map((lc) => ({ ...lc, linkerPath: annotateLinkerPath(derivedLabels, lc.linkerPath) })),\n ].reduce((cols, fn) => fn(cols) as TableColumnSnapshot[], linked);\n\n const labelColumnsAnnotated = withLabelAnnotations(derivedLabels, labelColumns);\n\n return {\n direct: directAnnotated,\n linked: linkedAnnotated,\n labels: labelColumnsAnnotated,\n };\n}\nfunction annotateLinkerPath(\n derivedLabels: Record<string, string>,\n path: TableColumnSnapshot[\"linkerPath\"],\n): TableColumnSnapshot[\"linkerPath\"] {\n if (isNil(path) || path.length === 0) return path;\n const annotatedLinkers = withHidenAxesAnnotations(\n withLabelAnnotations(\n derivedLabels,\n path.map((s) => s.linker),\n ),\n );\n return path.map((s, i) => ({ ...s, linker: annotatedLinkers[i] }));\n}\n\n/** Build an index of all valid column IDs (axes + columns) for filter/sorting validation. */\nfunction createColumnValidationById(\n fullColumns: { readonly id: PObjectId; readonly spec: PColumnSpec }[],\n) {\n const axisIds = uniqueBy(\n fullColumns.flatMap((c) => c.spec.axesSpec.map(getAxisId)),\n (a) => canonicalizeJson<AxisId>(a),\n );\n\n const allIds: PTableColumnId[] = [\n ...axisIds.map((a) => ({ type: \"axis\", id: a }) satisfies PTableColumnIdAxis),\n ...fullColumns.map((c) => ({ type: \"column\", id: c.id }) satisfies PTableColumnIdColumn),\n ];\n\n const validIdSet = new Set(allIds.map((c) => canonicalizeJson<PTableColumnId>(c)));\n\n return (id: string): boolean => {\n return validIdSet.has(id as CanonicalizedJson<PTableColumnId>);\n };\n}\n\n/** Validate that all column references in filters exist in the table. */\nfunction validateFilters(\n filters: Nil | PlDataTableFilters,\n isValidColumnId: (id: string) => boolean,\n): void {\n if (filters == null) return;\n const filterColumns = collectFilterSpecColumns(filters);\n const firstInvalid = filterColumns.find((col) => !isValidColumnId(col));\n if (firstInvalid !== undefined) {\n throw new Error(\n `Invalid filter column ${firstInvalid}: column reference does not match the table columns`,\n );\n }\n}\n\n/** Merge two filter trees into one AND-combined tree. Returns the non-nil one if the other is nil. */\nfunction concatFilters(\n a: Nil | PlDataTableFilters,\n b: Nil | PlDataTableFilters,\n): Nil | PlDataTableFilters {\n if (isNil(a)) return b;\n if (isNil(b)) return a;\n return { ...a, filters: [...a.filters, ...b.filters] };\n}\n\n/** Pick user sorting from state if non-empty, otherwise fall back to options default. */\nfunction resolveSorting(\n userSorting: PTableSorting[],\n defaultSorting: Nil | PTableSorting[],\n): PTableSorting[] {\n return (isEmpty(userSorting) ? defaultSorting : userSorting) ?? [];\n}\n\n/** Validate that all column references in sorting exist in the table. */\nfunction validateSorting(sorting: PTableSorting[], isValidColumnId: (id: string) => boolean): void {\n const firstInvalid = sorting.find(\n (s) => !isValidColumnId(canonicalizeJson<PTableColumnId>(s.column)),\n );\n if (firstInvalid !== undefined) {\n throw new Error(\n `Invalid sorting column ${JSON.stringify(firstInvalid.column)}: column reference does not match the table columns`,\n );\n }\n}\n\nfunction buildSecondaryGroups(\n direct: TableColumnSnapshot[],\n linked: TableColumnSnapshot[],\n labels: PColumn<PColumnDataUniversal>[],\n): SecondaryGroup<undefined | PColumnDataUniversal>[] {\n return [\n ...direct.map(\n (c): SecondaryGroup<undefined | PColumnDataUniversal> => ({\n entries: [{ column: resolveSnapshot(c), qualifications: c.qualifications?.forHit }],\n primaryQualifications: c.qualifications?.forQueries,\n }),\n ),\n ...linked.map(\n (lc): SecondaryGroup<undefined | PColumnDataUniversal> => ({\n entries: [\n ...(lc.linkerPath ?? []).map((s) => ({\n column: resolveSnapshot(s.linker),\n qualifications: s.qualifications,\n })),\n { column: resolveSnapshot(lc), qualifications: lc.qualifications?.forHit },\n ],\n primaryQualifications: lc.qualifications?.forQueries,\n }),\n ),\n ...labels.map(\n (c): SecondaryGroup<undefined | PColumnDataUniversal> => ({ entries: [{ column: c }] }),\n ),\n ];\n}\n\n/** Determine which columns should be hidden based on state or optional-column defaults. */\nfunction computeHiddenColumns(\n columns: { readonly id: PObjectId; readonly spec: PColumnSpec }[],\n sorting: Nil | PTableSorting[],\n filters: Nil | PlDataTableFilters,\n hiddenSpecs: Nil | PTableColumnId[],\n): Set<PObjectId> {\n const alwaysHidden = columns.filter((c) => isColumnHidden(c.spec)).map((c) => c.id);\n const optionalHidden = !isNil(hiddenSpecs)\n ? hiddenSpecs.filter((s): s is PTableColumnIdColumn => s.type === \"column\").map((s) => s.id)\n : columns.filter((c) => isColumnOptional(c.spec)).map((c) => c.id);\n const initial = [...alwaysHidden, ...optionalHidden];\n const preserved = collectPreservedColumnIds(sorting, filters);\n\n return new Set(initial.filter((id) => !preserved.has(id)));\n}\n\n/** Collect IDs of columns that must remain visible (sorted, filtered). */\nfunction collectPreservedColumnIds(\n sorting: Nil | PTableSorting[],\n filters: Nil | PlDataTableFilters,\n): Set<PObjectId> {\n const sortedIds = (sorting ?? [])\n .map((s) => s.column)\n .filter((c): c is PTableColumnIdColumn => c.type === \"column\")\n .map((c) => c.id);\n\n const filterIds = !isNil(filters)\n ? collectFilterSpecColumns(filters).flatMap((c) => {\n const obj = parseJson(c);\n return obj.type === \"column\" ? [obj.id] : [];\n })\n : [];\n\n return new Set<PObjectId>([...sortedIds, ...filterIds]);\n}\n\n/** Filter annotated columns to only visible ones, re-matching label columns for the visible subset. */\nfunction buildVisibleColumns(\n annotated: AnnotatedColumnGroups,\n hiddenColumns: Set<PObjectId>,\n originalLabelColumns: PColumn<PColumnDataUniversal>[],\n): VisibleColumns {\n const direct = annotated.direct.filter((c) => !hiddenColumns.has(c.id));\n const linked = annotated.linked.filter((c) => !hiddenColumns.has(c.id));\n const labels = getMatchingLabelColumns([...direct, ...linked], originalLabelColumns);\n return { direct, linked, labels };\n}\n\n/** Resolve a ColumnSnapshot to a PColumn with lazily-evaluated data. */\nfunction resolveSnapshot(\n snap: ColumnSnapshot<PObjectId>,\n): PColumn<undefined | PColumnDataUniversal> {\n return { id: snap.id, spec: snap.spec, data: snap.data?.get() };\n}\n\n/** Remap column references in sorting entries. */\nfunction remapSortingColumnIds(\n sorting: Nil | PTableSorting[],\n columns: TableColumnSnapshot[],\n): Nil | PTableSorting[] {\n return sorting?.map((s) => {\n if (s.column.type === \"axis\") return s; // Axis references are unaffected by column ID remapping\n\n const id = s.column.id;\n const column =\n columns.find((c) => (c.originalId ?? c.id) === id) ??\n throwError(`Column ID \"${id}\" in sorting does not match any discovered column`);\n\n return {\n ...s,\n column: {\n type: \"column\",\n id: column.id,\n },\n };\n });\n}\n\ntype PlDataTableFilterNode = FilterSpecNode<PlDataTableFilterSpecLeaf>;\n\n/** Remap column references in a filter tree. */\nfunction remapFilterColumnIds(\n filters: Nil | PlDataTableFilters,\n columns: TableColumnSnapshot[],\n): Nil | PlDataTableFilters {\n if (isNil(filters)) return filters;\n\n const map = (\n tableColumnId: CanonicalizedJson<PTableColumnId>,\n ): CanonicalizedJson<PTableColumnId> => {\n const parsed = parseJson<PTableColumnId>(tableColumnId);\n if (parsed.type === \"axis\") return tableColumnId; // Axis references are unaffected by column ID remapping\n\n const originalId = parsed.id;\n const column =\n columns.find((c) => (c.originalId ?? c.id) === originalId) ??\n throwError(`Column ID \"${parsed.id}\" in filters does not match any discovered column`);\n\n return canonicalizeJson<PTableColumnId>({\n type: \"column\",\n id: column.id,\n });\n };\n\n return traverseFilterSpec(filters, {\n leaf: (leaf): PlDataTableFilterNode => {\n if (leaf.type === undefined) return leaf;\n const result = { ...leaf };\n if (\"column\" in result) result.column = map(result.column);\n if (\"rhs\" in result) result.rhs = map(result.rhs);\n return result;\n },\n and: (results): PlDataTableFilterNode => ({ type: \"and\", filters: results }),\n or: (results): PlDataTableFilterNode => ({ type: \"or\", filters: results }),\n not: (result): PlDataTableFilterNode => ({ type: \"not\", filter: result }),\n }) as PlDataTableFilters;\n}\n"],"mappings":"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"}
@@ -3,23 +3,21 @@ import { RenderCtxBase } from "../../../render/api.js";
3
3
  import { PlDataTableFilters, PlDataTableModel } from "../typesV5.js";
4
4
  import { PlDataTableStateV2 } from "../state-migration.js";
5
5
  import { ColumnSnapshot } from "../../../columns/column_snapshot.js";
6
- import { ColumnMatch, MatchingMode } from "../../../columns/column_collection_builder.js";
7
- import { DiscoveredTableColumnOptions } from "./discoverColumns.js";
8
- import { MultiColumnSelector, PColumnSpec, PObjectId, PTableSorting, RequireServices, SUniversalPColumnId, Services } from "@milaboratories/pl-model-common";
6
+ import { ColumnSelector } from "../../../columns/column_selector.js";
7
+ import { MatchQualifications, MatchVariant, MatchingMode } from "../../../columns/column_collection_builder.js";
8
+ import { DiscoverTableColumnOptions } from "./discoverColumns.js";
9
+ import { DiscoveredPColumnId, MultiColumnSelector, PColumnSpec, PObjectId, PTableSorting } from "@milaboratories/pl-model-common";
9
10
  import { Nil } from "@milaboratories/helpers";
10
11
 
11
12
  //#region src/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts
12
- type createPlDataTableOptionsV3 = ({
13
- discoverColumnOptions: DiscoveredTableColumnOptions;
14
- } | {
15
- columns: Nil | TableColumnSnapshot<SUniversalPColumnId>[];
16
- }) & {
13
+ type createPlDataTableOptionsV3 = {
14
+ tableState?: PlDataTableStateV2;
15
+ columns: Nil | DiscoverTableColumnOptions | TableColumnSnapshot[];
17
16
  filters?: PlDataTableFilters;
18
17
  sorting?: PTableSorting[];
19
18
  primaryJoinType?: "inner" | "full";
20
- tableState?: PlDataTableStateV2;
21
19
  labelsOptions?: DeriveLabelsOptions;
22
- columnsDisplayOptions?: ColumnsDisplayOptions;
20
+ displayOptions?: ColumnsDisplayOptions;
23
21
  };
24
22
  /** Structured source config — selectors/anchors instead of raw ColumnSource. */
25
23
  type ColumnsSelectorConfig = {
@@ -33,20 +31,22 @@ type ColumnsDisplayOptions = {
33
31
  visibility?: ColumnVisibilityRule[];
34
32
  };
35
33
  type ColumnOrderRule = {
36
- match: ColumnMatcher; /** Higher number = further left in table */
34
+ match: ColumnMatcher | ColumnSelector; /** Higher number = further left in table */
37
35
  priority: number;
38
36
  };
39
37
  type ColumnVisibilityRule = {
40
- match: ColumnMatcher;
38
+ match: ColumnMatcher | ColumnSelector;
41
39
  visibility: "default" | "optional" | "hidden";
42
40
  };
43
41
  type ColumnMatcher = (spec: PColumnSpec) => boolean;
44
- declare function createPlDataTableV3<A, U, S extends RequireServices<typeof Services.PFrameSpec>>(ctx: RenderCtxBase<A, U, S>, options: createPlDataTableOptionsV3): PlDataTableModel | undefined;
42
+ declare function createPlDataTableV3<A, U>(ctx: RenderCtxBase<A, U>, options: createPlDataTableOptionsV3): PlDataTableModel | undefined;
45
43
  /** A single column discovered from sources — normalized from raw ColumnSnapshot/ColumnMatch. */
46
- type TableColumnSnapshot<Id extends PObjectId | SUniversalPColumnId> = ColumnSnapshot<Id> & {
44
+ type TableColumnSnapshot = ColumnSnapshot<DiscoveredPColumnId> & {
45
+ readonly originalId: PObjectId;
47
46
  readonly isPrimary?: boolean;
48
- readonly originalId?: PObjectId;
49
- readonly linkerPath?: ColumnMatch["path"];
47
+ readonly linkerPath?: MatchVariant["path"];
48
+ readonly qualifications?: MatchQualifications;
49
+ readonly distinctiveQualifications?: MatchQualifications;
50
50
  };
51
51
  //#endregion
52
52
  export { ColumnMatcher, ColumnOrderRule, ColumnVisibilityRule, ColumnsDisplayOptions, ColumnsSelectorConfig, TableColumnSnapshot, createPlDataTableOptionsV3, createPlDataTableV3 };