@memberjunction/ng-core-entity-forms 6.2.0-edge.6 → 6.2.0-edge.8

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 (167) hide show
  1. package/dist/lib/custom/AIAgents/ai-agent-form.component.js +1 -1
  2. package/dist/lib/custom/AIAgents/ai-agent-form.component.js.map +1 -1
  3. package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js +2 -2
  4. package/dist/lib/custom/Conversations/conversation-overview.panel.js +1 -1
  5. package/dist/lib/custom/Conversations/conversation-overview.panel.js.map +1 -1
  6. package/dist/lib/custom/DiagnosticSenderRegistrations/sender-registration-toolbar-actions.d.ts +35 -0
  7. package/dist/lib/custom/DiagnosticSenderRegistrations/sender-registration-toolbar-actions.d.ts.map +1 -0
  8. package/dist/lib/custom/DiagnosticSenderRegistrations/sender-registration-toolbar-actions.js +155 -0
  9. package/dist/lib/custom/DiagnosticSenderRegistrations/sender-registration-toolbar-actions.js.map +1 -0
  10. package/dist/lib/custom/Entities/entity-form.component.js +3 -3
  11. package/dist/lib/custom/Entities/entity-form.component.js.map +1 -1
  12. package/dist/lib/custom/Files/file-form.component.d.ts +8 -0
  13. package/dist/lib/custom/Files/file-form.component.d.ts.map +1 -1
  14. package/dist/lib/custom/Files/file-form.component.js +21 -5
  15. package/dist/lib/custom/Files/file-form.component.js.map +1 -1
  16. package/dist/lib/custom/Files/file-form.logic.d.ts +7 -0
  17. package/dist/lib/custom/Files/file-form.logic.d.ts.map +1 -1
  18. package/dist/lib/custom/Files/file-form.logic.js +20 -0
  19. package/dist/lib/custom/Files/file-form.logic.js.map +1 -1
  20. package/dist/lib/custom/Lists/list-form.component.js +5 -5
  21. package/dist/lib/custom/Lists/list-form.component.js.map +1 -1
  22. package/dist/lib/custom/Queries/query-child-labels.d.ts +12 -0
  23. package/dist/lib/custom/Queries/query-child-labels.d.ts.map +1 -0
  24. package/dist/lib/custom/Queries/query-child-labels.js +28 -0
  25. package/dist/lib/custom/Queries/query-child-labels.js.map +1 -0
  26. package/dist/lib/custom/Queries/query-fields-grid.component.d.ts +37 -0
  27. package/dist/lib/custom/Queries/query-fields-grid.component.d.ts.map +1 -0
  28. package/dist/lib/custom/Queries/query-fields-grid.component.js +321 -0
  29. package/dist/lib/custom/Queries/query-fields-grid.component.js.map +1 -0
  30. package/dist/lib/custom/Queries/query-form-logic.d.ts +37 -0
  31. package/dist/lib/custom/Queries/query-form-logic.d.ts.map +1 -0
  32. package/dist/lib/custom/Queries/query-form-logic.js +48 -0
  33. package/dist/lib/custom/Queries/query-form-logic.js.map +1 -0
  34. package/dist/lib/custom/Queries/query-form.component.d.ts +76 -7
  35. package/dist/lib/custom/Queries/query-form.component.d.ts.map +1 -1
  36. package/dist/lib/custom/Queries/query-form.component.js +740 -688
  37. package/dist/lib/custom/Queries/query-form.component.js.map +1 -1
  38. package/dist/lib/custom/Queries/query-parameters-grid.component.d.ts +31 -0
  39. package/dist/lib/custom/Queries/query-parameters-grid.component.d.ts.map +1 -0
  40. package/dist/lib/custom/Queries/query-parameters-grid.component.js +298 -0
  41. package/dist/lib/custom/Queries/query-parameters-grid.component.js.map +1 -0
  42. package/dist/lib/custom/Rubrics/record-forms.component.js +2 -2
  43. package/dist/lib/custom/Rubrics/record-forms.component.js.map +1 -1
  44. package/dist/lib/custom/Rubrics/scale-form.component.d.ts.map +1 -1
  45. package/dist/lib/custom/Rubrics/scale-form.component.js +2 -1
  46. package/dist/lib/custom/Rubrics/scale-form.component.js.map +1 -1
  47. package/dist/lib/custom/SearchScopes/searchscope-form.component.js +1 -1
  48. package/dist/lib/custom/SearchScopes/searchscope-form.component.js.map +1 -1
  49. package/dist/lib/custom/custom-forms.module.d.ts +41 -35
  50. package/dist/lib/custom/custom-forms.module.d.ts.map +1 -1
  51. package/dist/lib/custom/custom-forms.module.js +36 -3
  52. package/dist/lib/custom/custom-forms.module.js.map +1 -1
  53. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.d.ts.map +1 -1
  54. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js +234 -226
  55. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js.map +1 -1
  56. package/dist/lib/generated/Entities/MJAIAgentConfiguration/mjaiagentconfiguration.form.component.d.ts.map +1 -1
  57. package/dist/lib/generated/Entities/MJAIAgentConfiguration/mjaiagentconfiguration.form.component.js +25 -6
  58. package/dist/lib/generated/Entities/MJAIAgentConfiguration/mjaiagentconfiguration.form.component.js.map +1 -1
  59. package/dist/lib/generated/Entities/MJAIAgentRelationship/mjaiagentrelationship.form.component.d.ts.map +1 -1
  60. package/dist/lib/generated/Entities/MJAIAgentRelationship/mjaiagentrelationship.form.component.js +13 -3
  61. package/dist/lib/generated/Entities/MJAIAgentRelationship/mjaiagentrelationship.form.component.js.map +1 -1
  62. package/dist/lib/generated/Entities/MJBrandKit/mjbrandkit.form.component.d.ts +10 -0
  63. package/dist/lib/generated/Entities/MJBrandKit/mjbrandkit.form.component.d.ts.map +1 -0
  64. package/dist/lib/generated/Entities/MJBrandKit/mjbrandkit.form.component.js +91 -0
  65. package/dist/lib/generated/Entities/MJBrandKit/mjbrandkit.form.component.js.map +1 -0
  66. package/dist/lib/generated/Entities/MJBrandKitAsset/mjbrandkitasset.form.component.d.ts +10 -0
  67. package/dist/lib/generated/Entities/MJBrandKitAsset/mjbrandkitasset.form.component.d.ts.map +1 -0
  68. package/dist/lib/generated/Entities/MJBrandKitAsset/mjbrandkitasset.form.component.js +72 -0
  69. package/dist/lib/generated/Entities/MJBrandKitAsset/mjbrandkitasset.form.component.js.map +1 -0
  70. package/dist/lib/generated/Entities/MJCompany/mjcompany.form.component.d.ts.map +1 -1
  71. package/dist/lib/generated/Entities/MJCompany/mjcompany.form.component.js +82 -10
  72. package/dist/lib/generated/Entities/MJCompany/mjcompany.form.component.js.map +1 -1
  73. package/dist/lib/generated/Entities/MJContentSource/mjcontentsource.form.component.d.ts.map +1 -1
  74. package/dist/lib/generated/Entities/MJContentSource/mjcontentsource.form.component.js +39 -31
  75. package/dist/lib/generated/Entities/MJContentSource/mjcontentsource.form.component.js.map +1 -1
  76. package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.js +90 -78
  77. package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.js.map +1 -1
  78. package/dist/lib/generated/Entities/MJDiagnosticBundle/mjdiagnosticbundle.form.component.d.ts +10 -0
  79. package/dist/lib/generated/Entities/MJDiagnosticBundle/mjdiagnosticbundle.form.component.d.ts.map +1 -0
  80. package/dist/lib/generated/Entities/MJDiagnosticBundle/mjdiagnosticbundle.form.component.js +154 -0
  81. package/dist/lib/generated/Entities/MJDiagnosticBundle/mjdiagnosticbundle.form.component.js.map +1 -0
  82. package/dist/lib/generated/Entities/MJDiagnosticSenderRegistration/mjdiagnosticsenderregistration.form.component.d.ts +10 -0
  83. package/dist/lib/generated/Entities/MJDiagnosticSenderRegistration/mjdiagnosticsenderregistration.form.component.d.ts.map +1 -0
  84. package/dist/lib/generated/Entities/MJDiagnosticSenderRegistration/mjdiagnosticsenderregistration.form.component.js +98 -0
  85. package/dist/lib/generated/Entities/MJDiagnosticSenderRegistration/mjdiagnosticsenderregistration.form.component.js.map +1 -0
  86. package/dist/lib/generated/Entities/MJDiagnosticSession/mjdiagnosticsession.form.component.d.ts +10 -0
  87. package/dist/lib/generated/Entities/MJDiagnosticSession/mjdiagnosticsession.form.component.d.ts.map +1 -0
  88. package/dist/lib/generated/Entities/MJDiagnosticSession/mjdiagnosticsession.form.component.js +149 -0
  89. package/dist/lib/generated/Entities/MJDiagnosticSession/mjdiagnosticsession.form.component.js.map +1 -0
  90. package/dist/lib/generated/Entities/MJDiagnosticSessionChunk/mjdiagnosticsessionchunk.form.component.d.ts +10 -0
  91. package/dist/lib/generated/Entities/MJDiagnosticSessionChunk/mjdiagnosticsessionchunk.form.component.d.ts.map +1 -0
  92. package/dist/lib/generated/Entities/MJDiagnosticSessionChunk/mjdiagnosticsessionchunk.form.component.js +88 -0
  93. package/dist/lib/generated/Entities/MJDiagnosticSessionChunk/mjdiagnosticsessionchunk.form.component.js.map +1 -0
  94. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.d.ts.map +1 -1
  95. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js +513 -451
  96. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js.map +1 -1
  97. package/dist/lib/generated/Entities/MJEntityField/mjentityfield.form.component.d.ts.map +1 -1
  98. package/dist/lib/generated/Entities/MJEntityField/mjentityfield.form.component.js +24 -6
  99. package/dist/lib/generated/Entities/MJEntityField/mjentityfield.form.component.js.map +1 -1
  100. package/dist/lib/generated/Entities/MJFile/mjfile.form.component.d.ts.map +1 -1
  101. package/dist/lib/generated/Entities/MJFile/mjfile.form.component.js +51 -15
  102. package/dist/lib/generated/Entities/MJFile/mjfile.form.component.js.map +1 -1
  103. package/dist/lib/generated/Entities/MJGraph/mjgraph.form.component.d.ts +10 -0
  104. package/dist/lib/generated/Entities/MJGraph/mjgraph.form.component.d.ts.map +1 -0
  105. package/dist/lib/generated/Entities/MJGraph/mjgraph.form.component.js +155 -0
  106. package/dist/lib/generated/Entities/MJGraph/mjgraph.form.component.js.map +1 -0
  107. package/dist/lib/generated/Entities/MJGraphAuthorityTier/mjgraphauthoritytier.form.component.d.ts +10 -0
  108. package/dist/lib/generated/Entities/MJGraphAuthorityTier/mjgraphauthoritytier.form.component.d.ts.map +1 -0
  109. package/dist/lib/generated/Entities/MJGraphAuthorityTier/mjgraphauthoritytier.form.component.js +83 -0
  110. package/dist/lib/generated/Entities/MJGraphAuthorityTier/mjgraphauthoritytier.form.component.js.map +1 -0
  111. package/dist/lib/generated/Entities/MJGraphConcept/mjgraphconcept.form.component.d.ts +10 -0
  112. package/dist/lib/generated/Entities/MJGraphConcept/mjgraphconcept.form.component.d.ts.map +1 -0
  113. package/dist/lib/generated/Entities/MJGraphConcept/mjgraphconcept.form.component.js +91 -0
  114. package/dist/lib/generated/Entities/MJGraphConcept/mjgraphconcept.form.component.js.map +1 -0
  115. package/dist/lib/generated/Entities/MJGraphConceptType/mjgraphconcepttype.form.component.d.ts +10 -0
  116. package/dist/lib/generated/Entities/MJGraphConceptType/mjgraphconcepttype.form.component.d.ts.map +1 -0
  117. package/dist/lib/generated/Entities/MJGraphConceptType/mjgraphconcepttype.form.component.js +83 -0
  118. package/dist/lib/generated/Entities/MJGraphConceptType/mjgraphconcepttype.form.component.js.map +1 -0
  119. package/dist/lib/generated/Entities/MJGraphEdge/mjgraphedge.form.component.d.ts +10 -0
  120. package/dist/lib/generated/Entities/MJGraphEdge/mjgraphedge.form.component.d.ts.map +1 -0
  121. package/dist/lib/generated/Entities/MJGraphEdge/mjgraphedge.form.component.js +78 -0
  122. package/dist/lib/generated/Entities/MJGraphEdge/mjgraphedge.form.component.js.map +1 -0
  123. package/dist/lib/generated/Entities/MJGraphEdgeProvider/mjgraphedgeprovider.form.component.d.ts +10 -0
  124. package/dist/lib/generated/Entities/MJGraphEdgeProvider/mjgraphedgeprovider.form.component.d.ts.map +1 -0
  125. package/dist/lib/generated/Entities/MJGraphEdgeProvider/mjgraphedgeprovider.form.component.js +68 -0
  126. package/dist/lib/generated/Entities/MJGraphEdgeProvider/mjgraphedgeprovider.form.component.js.map +1 -0
  127. package/dist/lib/generated/Entities/MJGraphEdgeType/mjgraphedgetype.form.component.d.ts +10 -0
  128. package/dist/lib/generated/Entities/MJGraphEdgeType/mjgraphedgetype.form.component.d.ts.map +1 -0
  129. package/dist/lib/generated/Entities/MJGraphEdgeType/mjgraphedgetype.form.component.js +105 -0
  130. package/dist/lib/generated/Entities/MJGraphEdgeType/mjgraphedgetype.form.component.js.map +1 -0
  131. package/dist/lib/generated/Entities/MJGraphEdgeTypeEndpoint/mjgraphedgetypeendpoint.form.component.d.ts +10 -0
  132. package/dist/lib/generated/Entities/MJGraphEdgeTypeEndpoint/mjgraphedgetypeendpoint.form.component.d.ts.map +1 -0
  133. package/dist/lib/generated/Entities/MJGraphEdgeTypeEndpoint/mjgraphedgetypeendpoint.form.component.js +60 -0
  134. package/dist/lib/generated/Entities/MJGraphEdgeTypeEndpoint/mjgraphedgetypeendpoint.form.component.js.map +1 -0
  135. package/dist/lib/generated/Entities/MJGraphType/mjgraphtype.form.component.d.ts +10 -0
  136. package/dist/lib/generated/Entities/MJGraphType/mjgraphtype.form.component.d.ts.map +1 -0
  137. package/dist/lib/generated/Entities/MJGraphType/mjgraphtype.form.component.js +85 -0
  138. package/dist/lib/generated/Entities/MJGraphType/mjgraphtype.form.component.js.map +1 -0
  139. package/dist/lib/generated/Entities/MJQuery/mjquery.form.component.js +67 -61
  140. package/dist/lib/generated/Entities/MJQuery/mjquery.form.component.js.map +1 -1
  141. package/dist/lib/generated/Entities/MJQueryField/mjqueryfield.form.component.d.ts.map +1 -1
  142. package/dist/lib/generated/Entities/MJQueryField/mjqueryfield.form.component.js +15 -3
  143. package/dist/lib/generated/Entities/MJQueryField/mjqueryfield.form.component.js.map +1 -1
  144. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.d.ts.map +1 -1
  145. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js +207 -135
  146. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js.map +1 -1
  147. package/dist/lib/generated/Entities/MJVideoArchetype/mjvideoarchetype.form.component.d.ts +10 -0
  148. package/dist/lib/generated/Entities/MJVideoArchetype/mjvideoarchetype.form.component.d.ts.map +1 -0
  149. package/dist/lib/generated/Entities/MJVideoArchetype/mjvideoarchetype.form.component.js +80 -0
  150. package/dist/lib/generated/Entities/MJVideoArchetype/mjvideoarchetype.form.component.js.map +1 -0
  151. package/dist/lib/generated/generated-forms.module.d.ts +478 -462
  152. package/dist/lib/generated/generated-forms.module.d.ts.map +1 -1
  153. package/dist/lib/generated/generated-forms.module.js +50 -2
  154. package/dist/lib/generated/generated-forms.module.js.map +1 -1
  155. package/dist/lib/panels/brand-kits/brand-kit-assets.panel.d.ts +15 -0
  156. package/dist/lib/panels/brand-kits/brand-kit-assets.panel.d.ts.map +1 -0
  157. package/dist/lib/panels/brand-kits/brand-kit-assets.panel.js +52 -0
  158. package/dist/lib/panels/brand-kits/brand-kit-assets.panel.js.map +1 -0
  159. package/dist/lib/panels/brand-kits/brand-kit-generation-policy.panel.d.ts +15 -0
  160. package/dist/lib/panels/brand-kits/brand-kit-generation-policy.panel.d.ts.map +1 -0
  161. package/dist/lib/panels/brand-kits/brand-kit-generation-policy.panel.js +52 -0
  162. package/dist/lib/panels/brand-kits/brand-kit-generation-policy.panel.js.map +1 -0
  163. package/dist/public-api.d.ts +2 -0
  164. package/dist/public-api.d.ts.map +1 -1
  165. package/dist/public-api.js +3 -0
  166. package/dist/public-api.js.map +1 -1
  167. package/package.json +50 -48
@@ -0,0 +1,12 @@
1
+ /**
2
+ * How a query field, parameter or entity link was detected, as the query form shows it.
3
+ * `DetectionMethod` values: `Database` (facts from the database server's describe), `Parser`
4
+ * (facts from MJ's reading of the SQL and template), `Manual` (authored by a person or metadata
5
+ * file), `AI` (an LLM wrote the description).
6
+ */
7
+ export type QueryChildDetectionMethod = 'AI' | 'Database' | 'Manual' | 'Parser';
8
+ /** The short label for a detection method; an unknown value is shown as it is. */
9
+ export declare function DetectionMethodLabel(method: string | null | undefined): string;
10
+ /** A sentence explaining a detection method, for a tooltip. */
11
+ export declare function DetectionMethodTitle(method: string | null | undefined): string;
12
+ //# sourceMappingURL=query-child-labels.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-child-labels.d.ts","sourceRoot":"","sources":["../../../../src/lib/custom/Queries/query-child-labels.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,MAAM,yBAAyB,GAAG,IAAI,GAAG,UAAU,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAoBhF,kFAAkF;AAClF,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAG9E;AAED,+DAA+D;AAC/D,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAG9E"}
@@ -0,0 +1,28 @@
1
+ const LABELS = {
2
+ Database: 'Database',
3
+ Parser: 'Parser',
4
+ Manual: 'Manual',
5
+ AI: 'AI',
6
+ };
7
+ const TITLES = {
8
+ Database: 'Facts come from the database server describing the query.',
9
+ Parser: 'Facts come from reading the SQL and its template.',
10
+ Manual: 'Authored by hand or in a metadata file.',
11
+ AI: 'The description was written by AI.',
12
+ };
13
+ function isDetectionMethod(method) {
14
+ return Object.prototype.hasOwnProperty.call(LABELS, method);
15
+ }
16
+ /** The short label for a detection method; an unknown value is shown as it is. */
17
+ export function DetectionMethodLabel(method) {
18
+ if (!method)
19
+ return '—';
20
+ return isDetectionMethod(method) ? LABELS[method] : method;
21
+ }
22
+ /** A sentence explaining a detection method, for a tooltip. */
23
+ export function DetectionMethodTitle(method) {
24
+ if (!method)
25
+ return '';
26
+ return isDetectionMethod(method) ? TITLES[method] : '';
27
+ }
28
+ //# sourceMappingURL=query-child-labels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-child-labels.js","sourceRoot":"","sources":["../../../../src/lib/custom/Queries/query-child-labels.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,GAA8C;IACtD,QAAQ,EAAE,UAAU;IACpB,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,QAAQ;IAChB,EAAE,EAAE,IAAI;CACX,CAAC;AAEF,MAAM,MAAM,GAA8C;IACtD,QAAQ,EAAE,2DAA2D;IACrE,MAAM,EAAE,mDAAmD;IAC3D,MAAM,EAAE,yCAAyC;IACjD,EAAE,EAAE,oCAAoC;CAC3C,CAAC;AAEF,SAAS,iBAAiB,CAAC,MAAc;IACrC,OAAO,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAChE,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,oBAAoB,CAAC,MAAiC;IAClE,IAAI,CAAC,MAAM;QAAE,OAAO,GAAG,CAAC;IACxB,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AAC/D,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,oBAAoB,CAAC,MAAiC;IAClE,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IACvB,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC3D,CAAC","sourcesContent":["/**\n * How a query field, parameter or entity link was detected, as the query form shows it.\n * `DetectionMethod` values: `Database` (facts from the database server's describe), `Parser`\n * (facts from MJ's reading of the SQL and template), `Manual` (authored by a person or metadata\n * file), `AI` (an LLM wrote the description).\n */\nexport type QueryChildDetectionMethod = 'AI' | 'Database' | 'Manual' | 'Parser';\n\nconst LABELS: Record<QueryChildDetectionMethod, string> = {\n Database: 'Database',\n Parser: 'Parser',\n Manual: 'Manual',\n AI: 'AI',\n};\n\nconst TITLES: Record<QueryChildDetectionMethod, string> = {\n Database: 'Facts come from the database server describing the query.',\n Parser: 'Facts come from reading the SQL and its template.',\n Manual: 'Authored by hand or in a metadata file.',\n AI: 'The description was written by AI.',\n};\n\nfunction isDetectionMethod(method: string): method is QueryChildDetectionMethod {\n return Object.prototype.hasOwnProperty.call(LABELS, method);\n}\n\n/** The short label for a detection method; an unknown value is shown as it is. */\nexport function DetectionMethodLabel(method: string | null | undefined): string {\n if (!method) return '—';\n return isDetectionMethod(method) ? LABELS[method] : method;\n}\n\n/** A sentence explaining a detection method, for a tooltip. */\nexport function DetectionMethodTitle(method: string | null | undefined): string {\n if (!method) return '';\n return isDetectionMethod(method) ? TITLES[method] : '';\n}\n"]}
@@ -0,0 +1,37 @@
1
+ import { EventEmitter } from '@angular/core';
2
+ import type { MJQueryFieldEntity } from '@memberjunction/core-entities';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * `<mj-query-fields-grid>` — a query's output fields as a table.
6
+ *
7
+ * Facts come from the SQL and the database server and are read-only here: name (except on a row
8
+ * not saved yet, which declares it), order, type, nullability, source, and how they were detected.
9
+ * Annotations are editable in edit mode: the description, the computation description of a
10
+ * computed column, and the summary flag and description.
11
+ *
12
+ * The source is a button when the column maps to an entity field (`OpenSourceField` carries the
13
+ * field's ID; the host decides where that goes), or the server-reported `schema.object.column`
14
+ * when it maps to no entity.
15
+ */
16
+ export declare class QueryFieldsGridComponent {
17
+ Fields: readonly MJQueryFieldEntity[];
18
+ EditMode: boolean;
19
+ /** The user asked to remove a field (it is removed when the query is saved). */
20
+ Remove: EventEmitter<MJQueryFieldEntity>;
21
+ /** The user asked to open the entity field a column comes from; carries `SourceEntityFieldID`. */
22
+ OpenSourceField: EventEmitter<string>;
23
+ /** An annotation changed, so the host can update its unsaved-changes state. */
24
+ Changed: EventEmitter<void>;
25
+ DetectionLabel(field: MJQueryFieldEntity): string;
26
+ DetectionTitle(field: MJQueryFieldEntity): string;
27
+ /** `Yes`, `No`, or `—` when the server does not report nullability (PostgreSQL). */
28
+ NullableLabel(field: MJQueryFieldEntity): string;
29
+ /** The entity-field source as `Entity.Field`, or `null` when the column maps to no entity field. */
30
+ EntitySource(field: MJQueryFieldEntity): string | null;
31
+ OnOpenSource(field: MJQueryFieldEntity): void;
32
+ TrackField(index: number, field: MJQueryFieldEntity): string;
33
+ OnAnnotationChange(): void;
34
+ static ɵfac: i0.ɵɵFactoryDeclaration<QueryFieldsGridComponent, never>;
35
+ static ɵcmp: i0.ɵɵComponentDeclaration<QueryFieldsGridComponent, "mj-query-fields-grid", never, { "Fields": { "alias": "Fields"; "required": false; }; "EditMode": { "alias": "EditMode"; "required": false; }; }, { "Remove": "Remove"; "OpenSourceField": "OpenSourceField"; "Changed": "Changed"; }, never, never, true, never>;
36
+ }
37
+ //# sourceMappingURL=query-fields-grid.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-fields-grid.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/custom/Queries/query-fields-grid.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,YAAY,EAAiB,MAAM,eAAe,CAAC;AAEhG,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;;AAIxE;;;;;;;;;;;GAWG;AACH,qBAQa,wBAAwB;IACxB,MAAM,EAAE,SAAS,kBAAkB,EAAE,CAAM;IAC3C,QAAQ,UAAS;IAE1B,gFAAgF;IACtE,MAAM,mCAA0C;IAC1D,kGAAkG;IACxF,eAAe,uBAA8B;IACvD,+EAA+E;IACrE,OAAO,qBAA4B;IAEtC,cAAc,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM;IAIjD,cAAc,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM;IAIxD,oFAAoF;IAC7E,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM;IAKvD,oGAAoG;IAC7F,YAAY,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM,GAAG,IAAI;IAOtD,YAAY,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI;IAI7C,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,MAAM;IAI5D,kBAAkB,IAAI,IAAI;yCAzCxB,wBAAwB;2CAAxB,wBAAwB;CA4CpC"}
@@ -0,0 +1,321 @@
1
+ import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
2
+ import { FormsModule } from '@angular/forms';
3
+ import { MJButtonDirective } from '@memberjunction/ng-ui-components';
4
+ import { DetectionMethodLabel, DetectionMethodTitle } from './query-child-labels';
5
+ import * as i0 from "@angular/core";
6
+ import * as i1 from "@angular/forms";
7
+ const _c0 = () => ({ standalone: true });
8
+ function QueryFieldsGridComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
9
+ i0.ɵɵelementStart(0, "th", 4)(1, "span", 6);
10
+ i0.ɵɵtext(2, "Actions");
11
+ i0.ɵɵelementEnd()();
12
+ } }
13
+ function QueryFieldsGridComponent_For_21_Conditional_4_Template(rf, ctx) { if (rf & 1) {
14
+ const _r1 = i0.ɵɵgetCurrentView();
15
+ i0.ɵɵelementStart(0, "input", 18);
16
+ i0.ɵɵtwoWayListener("ngModelChange", function QueryFieldsGridComponent_For_21_Conditional_4_Template_input_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r1); const field_r2 = i0.ɵɵnextContext().$implicit; i0.ɵɵtwoWayBindingSet(field_r2.Name, $event) || (field_r2.Name = $event); return i0.ɵɵresetView($event); });
17
+ i0.ɵɵlistener("ngModelChange", function QueryFieldsGridComponent_For_21_Conditional_4_Template_input_ngModelChange_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnAnnotationChange()); });
18
+ i0.ɵɵelementEnd();
19
+ } if (rf & 2) {
20
+ const field_r2 = i0.ɵɵnextContext().$implicit;
21
+ i0.ɵɵtwoWayProperty("ngModel", field_r2.Name);
22
+ i0.ɵɵproperty("ngModelOptions", i0.ɵɵpureFunction0(2, _c0));
23
+ } }
24
+ function QueryFieldsGridComponent_For_21_Conditional_5_Template(rf, ctx) { if (rf & 1) {
25
+ i0.ɵɵelementStart(0, "code");
26
+ i0.ɵɵtext(1);
27
+ i0.ɵɵelementEnd();
28
+ } if (rf & 2) {
29
+ const field_r2 = i0.ɵɵnextContext().$implicit;
30
+ i0.ɵɵadvance();
31
+ i0.ɵɵtextInterpolate(field_r2.Name);
32
+ } }
33
+ function QueryFieldsGridComponent_For_21_Conditional_6_Template(rf, ctx) { if (rf & 1) {
34
+ i0.ɵɵelementStart(0, "span", 10);
35
+ i0.ɵɵtext(1, "computed");
36
+ i0.ɵɵelementEnd();
37
+ } }
38
+ function QueryFieldsGridComponent_For_21_Conditional_7_Template(rf, ctx) { if (rf & 1) {
39
+ i0.ɵɵelementStart(0, "span", 11);
40
+ i0.ɵɵtext(1, "summary");
41
+ i0.ɵɵelementEnd();
42
+ } }
43
+ function QueryFieldsGridComponent_For_21_Conditional_14_Template(rf, ctx) { if (rf & 1) {
44
+ const _r4 = i0.ɵɵgetCurrentView();
45
+ i0.ɵɵelementStart(0, "button", 19);
46
+ i0.ɵɵlistener("click", function QueryFieldsGridComponent_For_21_Conditional_14_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const field_r2 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnOpenSource(field_r2)); });
47
+ i0.ɵɵelement(1, "i", 20);
48
+ i0.ɵɵtext(2);
49
+ i0.ɵɵelementEnd();
50
+ } if (rf & 2) {
51
+ const source_r5 = ctx;
52
+ i0.ɵɵproperty("title", "Open the entity field " + source_r5);
53
+ i0.ɵɵadvance(2);
54
+ i0.ɵɵtextInterpolate1(" ", source_r5, " ");
55
+ } }
56
+ function QueryFieldsGridComponent_For_21_Conditional_15_Template(rf, ctx) { if (rf & 1) {
57
+ i0.ɵɵelementStart(0, "code", 15);
58
+ i0.ɵɵtext(1);
59
+ i0.ɵɵelementEnd();
60
+ } if (rf & 2) {
61
+ const field_r2 = i0.ɵɵnextContext().$implicit;
62
+ i0.ɵɵadvance();
63
+ i0.ɵɵtextInterpolate(field_r2.SourceObjectName);
64
+ } }
65
+ function QueryFieldsGridComponent_For_21_Conditional_16_Template(rf, ctx) { if (rf & 1) {
66
+ i0.ɵɵelementStart(0, "span", 16);
67
+ i0.ɵɵtext(1, "\u2014");
68
+ i0.ɵɵelementEnd();
69
+ } }
70
+ function QueryFieldsGridComponent_For_21_Conditional_21_Conditional_1_Template(rf, ctx) { if (rf & 1) {
71
+ const _r7 = i0.ɵɵgetCurrentView();
72
+ i0.ɵɵelementStart(0, "textarea", 26);
73
+ i0.ɵɵtwoWayListener("ngModelChange", function QueryFieldsGridComponent_For_21_Conditional_21_Conditional_1_Template_textarea_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r7); const field_r2 = i0.ɵɵnextContext(2).$implicit; i0.ɵɵtwoWayBindingSet(field_r2.ComputationDescription, $event) || (field_r2.ComputationDescription = $event); return i0.ɵɵresetView($event); });
74
+ i0.ɵɵlistener("ngModelChange", function QueryFieldsGridComponent_For_21_Conditional_21_Conditional_1_Template_textarea_ngModelChange_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OnAnnotationChange()); });
75
+ i0.ɵɵelementEnd();
76
+ } if (rf & 2) {
77
+ const field_r2 = i0.ɵɵnextContext(2).$implicit;
78
+ i0.ɵɵtwoWayProperty("ngModel", field_r2.ComputationDescription);
79
+ i0.ɵɵproperty("ngModelOptions", i0.ɵɵpureFunction0(3, _c0));
80
+ i0.ɵɵattribute("aria-label", "How " + field_r2.Name + " is computed");
81
+ } }
82
+ function QueryFieldsGridComponent_For_21_Conditional_21_Conditional_5_Template(rf, ctx) { if (rf & 1) {
83
+ const _r8 = i0.ɵɵgetCurrentView();
84
+ i0.ɵɵelementStart(0, "textarea", 27);
85
+ i0.ɵɵtwoWayListener("ngModelChange", function QueryFieldsGridComponent_For_21_Conditional_21_Conditional_5_Template_textarea_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r8); const field_r2 = i0.ɵɵnextContext(2).$implicit; i0.ɵɵtwoWayBindingSet(field_r2.SummaryDescription, $event) || (field_r2.SummaryDescription = $event); return i0.ɵɵresetView($event); });
86
+ i0.ɵɵlistener("ngModelChange", function QueryFieldsGridComponent_For_21_Conditional_21_Conditional_5_Template_textarea_ngModelChange_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OnAnnotationChange()); });
87
+ i0.ɵɵelementEnd();
88
+ } if (rf & 2) {
89
+ const field_r2 = i0.ɵɵnextContext(2).$implicit;
90
+ i0.ɵɵtwoWayProperty("ngModel", field_r2.SummaryDescription);
91
+ i0.ɵɵproperty("ngModelOptions", i0.ɵɵpureFunction0(3, _c0));
92
+ i0.ɵɵattribute("aria-label", "Summary description of " + field_r2.Name);
93
+ } }
94
+ function QueryFieldsGridComponent_For_21_Conditional_21_Template(rf, ctx) { if (rf & 1) {
95
+ const _r6 = i0.ɵɵgetCurrentView();
96
+ i0.ɵɵelementStart(0, "textarea", 21);
97
+ i0.ɵɵtwoWayListener("ngModelChange", function QueryFieldsGridComponent_For_21_Conditional_21_Template_textarea_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r6); const field_r2 = i0.ɵɵnextContext().$implicit; i0.ɵɵtwoWayBindingSet(field_r2.Description, $event) || (field_r2.Description = $event); return i0.ɵɵresetView($event); });
98
+ i0.ɵɵlistener("ngModelChange", function QueryFieldsGridComponent_For_21_Conditional_21_Template_textarea_ngModelChange_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnAnnotationChange()); });
99
+ i0.ɵɵelementEnd();
100
+ i0.ɵɵconditionalCreate(1, QueryFieldsGridComponent_For_21_Conditional_21_Conditional_1_Template, 1, 4, "textarea", 22);
101
+ i0.ɵɵelementStart(2, "label", 23)(3, "input", 24);
102
+ i0.ɵɵtwoWayListener("ngModelChange", function QueryFieldsGridComponent_For_21_Conditional_21_Template_input_ngModelChange_3_listener($event) { i0.ɵɵrestoreView(_r6); const field_r2 = i0.ɵɵnextContext().$implicit; i0.ɵɵtwoWayBindingSet(field_r2.IsSummary, $event) || (field_r2.IsSummary = $event); return i0.ɵɵresetView($event); });
103
+ i0.ɵɵlistener("ngModelChange", function QueryFieldsGridComponent_For_21_Conditional_21_Template_input_ngModelChange_3_listener() { i0.ɵɵrestoreView(_r6); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnAnnotationChange()); });
104
+ i0.ɵɵelementEnd();
105
+ i0.ɵɵtext(4, " Summary column ");
106
+ i0.ɵɵelementEnd();
107
+ i0.ɵɵconditionalCreate(5, QueryFieldsGridComponent_For_21_Conditional_21_Conditional_5_Template, 1, 4, "textarea", 25);
108
+ } if (rf & 2) {
109
+ const field_r2 = i0.ɵɵnextContext().$implicit;
110
+ i0.ɵɵtwoWayProperty("ngModel", field_r2.Description);
111
+ i0.ɵɵproperty("ngModelOptions", i0.ɵɵpureFunction0(7, _c0));
112
+ i0.ɵɵattribute("aria-label", "Description of " + field_r2.Name);
113
+ i0.ɵɵadvance();
114
+ i0.ɵɵconditional(field_r2.IsComputed ? 1 : -1);
115
+ i0.ɵɵadvance(2);
116
+ i0.ɵɵtwoWayProperty("ngModel", field_r2.IsSummary);
117
+ i0.ɵɵproperty("ngModelOptions", i0.ɵɵpureFunction0(8, _c0));
118
+ i0.ɵɵadvance(2);
119
+ i0.ɵɵconditional(field_r2.IsSummary ? 5 : -1);
120
+ } }
121
+ function QueryFieldsGridComponent_For_21_Conditional_22_Conditional_0_Template(rf, ctx) { if (rf & 1) {
122
+ i0.ɵɵelementStart(0, "span");
123
+ i0.ɵɵtext(1);
124
+ i0.ɵɵelementEnd();
125
+ } if (rf & 2) {
126
+ const field_r2 = i0.ɵɵnextContext(2).$implicit;
127
+ i0.ɵɵadvance();
128
+ i0.ɵɵtextInterpolate(field_r2.Description);
129
+ } }
130
+ function QueryFieldsGridComponent_For_21_Conditional_22_Conditional_1_Template(rf, ctx) { if (rf & 1) {
131
+ i0.ɵɵelementStart(0, "span", 16);
132
+ i0.ɵɵtext(1, "\u2014");
133
+ i0.ɵɵelementEnd();
134
+ } }
135
+ function QueryFieldsGridComponent_For_21_Conditional_22_Conditional_2_Template(rf, ctx) { if (rf & 1) {
136
+ i0.ɵɵelementStart(0, "div", 28);
137
+ i0.ɵɵtext(1);
138
+ i0.ɵɵelementEnd();
139
+ } if (rf & 2) {
140
+ const field_r2 = i0.ɵɵnextContext(2).$implicit;
141
+ i0.ɵɵadvance();
142
+ i0.ɵɵtextInterpolate(field_r2.ComputationDescription);
143
+ } }
144
+ function QueryFieldsGridComponent_For_21_Conditional_22_Template(rf, ctx) { if (rf & 1) {
145
+ i0.ɵɵconditionalCreate(0, QueryFieldsGridComponent_For_21_Conditional_22_Conditional_0_Template, 2, 1, "span")(1, QueryFieldsGridComponent_For_21_Conditional_22_Conditional_1_Template, 2, 0, "span", 16);
146
+ i0.ɵɵconditionalCreate(2, QueryFieldsGridComponent_For_21_Conditional_22_Conditional_2_Template, 2, 1, "div", 28);
147
+ } if (rf & 2) {
148
+ const field_r2 = i0.ɵɵnextContext().$implicit;
149
+ i0.ɵɵconditional(field_r2.Description ? 0 : 1);
150
+ i0.ɵɵadvance(2);
151
+ i0.ɵɵconditional(field_r2.ComputationDescription ? 2 : -1);
152
+ } }
153
+ function QueryFieldsGridComponent_For_21_Conditional_23_Template(rf, ctx) { if (rf & 1) {
154
+ const _r9 = i0.ɵɵgetCurrentView();
155
+ i0.ɵɵelementStart(0, "td", 4)(1, "button", 29);
156
+ i0.ɵɵlistener("click", function QueryFieldsGridComponent_For_21_Conditional_23_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r9); const field_r2 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.Remove.emit(field_r2)); });
157
+ i0.ɵɵelement(2, "i", 30);
158
+ i0.ɵɵelementEnd()();
159
+ } if (rf & 2) {
160
+ const field_r2 = i0.ɵɵnextContext().$implicit;
161
+ i0.ɵɵadvance();
162
+ i0.ɵɵattribute("aria-label", "Remove field " + field_r2.Name);
163
+ } }
164
+ function QueryFieldsGridComponent_For_21_Template(rf, ctx) { if (rf & 1) {
165
+ i0.ɵɵelementStart(0, "tr", 5)(1, "td", 7);
166
+ i0.ɵɵtext(2);
167
+ i0.ɵɵelementEnd();
168
+ i0.ɵɵelementStart(3, "td", 8);
169
+ i0.ɵɵconditionalCreate(4, QueryFieldsGridComponent_For_21_Conditional_4_Template, 1, 3, "input", 9)(5, QueryFieldsGridComponent_For_21_Conditional_5_Template, 2, 1, "code");
170
+ i0.ɵɵconditionalCreate(6, QueryFieldsGridComponent_For_21_Conditional_6_Template, 2, 0, "span", 10);
171
+ i0.ɵɵconditionalCreate(7, QueryFieldsGridComponent_For_21_Conditional_7_Template, 2, 0, "span", 11);
172
+ i0.ɵɵelementEnd();
173
+ i0.ɵɵelementStart(8, "td", 12)(9, "code");
174
+ i0.ɵɵtext(10);
175
+ i0.ɵɵelementEnd()();
176
+ i0.ɵɵelementStart(11, "td", 12);
177
+ i0.ɵɵtext(12);
178
+ i0.ɵɵelementEnd();
179
+ i0.ɵɵelementStart(13, "td", 13);
180
+ i0.ɵɵconditionalCreate(14, QueryFieldsGridComponent_For_21_Conditional_14_Template, 3, 2, "button", 14)(15, QueryFieldsGridComponent_For_21_Conditional_15_Template, 2, 1, "code", 15)(16, QueryFieldsGridComponent_For_21_Conditional_16_Template, 2, 0, "span", 16);
181
+ i0.ɵɵelementEnd();
182
+ i0.ɵɵelementStart(17, "td", 12)(18, "span", 17);
183
+ i0.ɵɵtext(19);
184
+ i0.ɵɵelementEnd()();
185
+ i0.ɵɵelementStart(20, "td", 3);
186
+ i0.ɵɵconditionalCreate(21, QueryFieldsGridComponent_For_21_Conditional_21_Template, 6, 9)(22, QueryFieldsGridComponent_For_21_Conditional_22_Template, 3, 2);
187
+ i0.ɵɵelementEnd();
188
+ i0.ɵɵconditionalCreate(23, QueryFieldsGridComponent_For_21_Conditional_23_Template, 3, 1, "td", 4);
189
+ i0.ɵɵelementEnd();
190
+ } if (rf & 2) {
191
+ let tmp_16_0;
192
+ const field_r2 = ctx.$implicit;
193
+ const ctx_r2 = i0.ɵɵnextContext();
194
+ i0.ɵɵadvance(2);
195
+ i0.ɵɵtextInterpolate(field_r2.Sequence);
196
+ i0.ɵɵadvance(2);
197
+ i0.ɵɵconditional(ctx_r2.EditMode && !field_r2.IsSaved ? 4 : 5);
198
+ i0.ɵɵadvance(2);
199
+ i0.ɵɵconditional(field_r2.IsComputed ? 6 : -1);
200
+ i0.ɵɵadvance();
201
+ i0.ɵɵconditional(field_r2.IsSummary ? 7 : -1);
202
+ i0.ɵɵadvance(3);
203
+ i0.ɵɵtextInterpolate(field_r2.SQLFullType || field_r2.SQLBaseType);
204
+ i0.ɵɵadvance(2);
205
+ i0.ɵɵtextInterpolate(ctx_r2.NullableLabel(field_r2));
206
+ i0.ɵɵadvance(2);
207
+ i0.ɵɵconditional((tmp_16_0 = ctx_r2.EntitySource(field_r2)) ? 14 : field_r2.SourceObjectName ? 15 : 16, tmp_16_0);
208
+ i0.ɵɵadvance(4);
209
+ i0.ɵɵclassMap("qcg-detect qcg-detect--" + (field_r2.DetectionMethod || "none").toLowerCase());
210
+ i0.ɵɵproperty("title", ctx_r2.DetectionTitle(field_r2));
211
+ i0.ɵɵadvance();
212
+ i0.ɵɵtextInterpolate(ctx_r2.DetectionLabel(field_r2));
213
+ i0.ɵɵadvance(2);
214
+ i0.ɵɵconditional(ctx_r2.EditMode ? 21 : 22);
215
+ i0.ɵɵadvance(2);
216
+ i0.ɵɵconditional(ctx_r2.EditMode ? 23 : -1);
217
+ } }
218
+ /**
219
+ * `<mj-query-fields-grid>` — a query's output fields as a table.
220
+ *
221
+ * Facts come from the SQL and the database server and are read-only here: name (except on a row
222
+ * not saved yet, which declares it), order, type, nullability, source, and how they were detected.
223
+ * Annotations are editable in edit mode: the description, the computation description of a
224
+ * computed column, and the summary flag and description.
225
+ *
226
+ * The source is a button when the column maps to an entity field (`OpenSourceField` carries the
227
+ * field's ID; the host decides where that goes), or the server-reported `schema.object.column`
228
+ * when it maps to no entity.
229
+ */
230
+ export class QueryFieldsGridComponent {
231
+ constructor() {
232
+ this.Fields = [];
233
+ this.EditMode = false;
234
+ /** The user asked to remove a field (it is removed when the query is saved). */
235
+ this.Remove = new EventEmitter();
236
+ /** The user asked to open the entity field a column comes from; carries `SourceEntityFieldID`. */
237
+ this.OpenSourceField = new EventEmitter();
238
+ /** An annotation changed, so the host can update its unsaved-changes state. */
239
+ this.Changed = new EventEmitter();
240
+ }
241
+ DetectionLabel(field) {
242
+ return DetectionMethodLabel(field.DetectionMethod);
243
+ }
244
+ DetectionTitle(field) {
245
+ return DetectionMethodTitle(field.DetectionMethod);
246
+ }
247
+ /** `Yes`, `No`, or `—` when the server does not report nullability (PostgreSQL). */
248
+ NullableLabel(field) {
249
+ if (field.IsNullable === null || field.IsNullable === undefined)
250
+ return '—';
251
+ return field.IsNullable ? 'Yes' : 'No';
252
+ }
253
+ /** The entity-field source as `Entity.Field`, or `null` when the column maps to no entity field. */
254
+ EntitySource(field) {
255
+ if (!field.SourceEntityFieldID)
256
+ return null;
257
+ const entity = field.SourceEntity ?? '';
258
+ const name = field.SourceFieldName ?? field.SourceEntityField ?? '';
259
+ return entity ? `${entity}.${name}` : name;
260
+ }
261
+ OnOpenSource(field) {
262
+ if (field.SourceEntityFieldID)
263
+ this.OpenSourceField.emit(field.SourceEntityFieldID);
264
+ }
265
+ TrackField(index, field) {
266
+ return field.ID || `new-${index}`;
267
+ }
268
+ OnAnnotationChange() {
269
+ this.Changed.emit();
270
+ }
271
+ static { this.ɵfac = function QueryFieldsGridComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || QueryFieldsGridComponent)(); }; }
272
+ static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: QueryFieldsGridComponent, selectors: [["mj-query-fields-grid"]], inputs: { Fields: "Fields", EditMode: "EditMode" }, outputs: { Remove: "Remove", OpenSourceField: "OpenSourceField", Changed: "Changed" }, decls: 22, vars: 1, consts: [[1, "qcg-wrap"], [1, "qcg-table"], [1, "qcg-seq"], [1, "qcg-annotation"], [1, "qcg-actions"], [1, "qcg-row"], [1, "qcg-sr-only"], [1, "qcg-seq", "qcg-fact"], [1, "qcg-fact", "qcg-name"], ["aria-label", "Field name", "placeholder", "Column name", 1, "mj-input", "qcg-input", 3, "ngModel", "ngModelOptions"], ["title", "The column has no direct source; the database computes it.", 1, "qcg-tag"], ["title", "A summary column", 1, "qcg-tag"], [1, "qcg-fact"], [1, "qcg-fact", "qcg-source"], ["type", "button", 1, "qcg-link", 3, "title"], ["title", "Reported by the database server; no MJ entity reads this object", 1, "qcg-object"], [1, "qcg-muted"], [1, "qcg-detect", 3, "title"], ["aria-label", "Field name", "placeholder", "Column name", 1, "mj-input", "qcg-input", 3, "ngModelChange", "ngModel", "ngModelOptions"], ["type", "button", 1, "qcg-link", 3, "click", "title"], [1, "fa-solid", "fa-link"], ["rows", "1", "placeholder", "Describe this column", 1, "mj-input", "qcg-textarea", 3, "ngModelChange", "ngModel", "ngModelOptions"], ["rows", "1", "placeholder", "How it is computed", 1, "mj-input", "qcg-textarea", 3, "ngModel", "ngModelOptions"], [1, "qcg-check"], ["type", "checkbox", 3, "ngModelChange", "ngModel", "ngModelOptions"], ["rows", "1", "placeholder", "What it summarizes", 1, "mj-input", "qcg-textarea", 3, "ngModel", "ngModelOptions"], ["rows", "1", "placeholder", "How it is computed", 1, "mj-input", "qcg-textarea", 3, "ngModelChange", "ngModel", "ngModelOptions"], ["rows", "1", "placeholder", "What it summarizes", 1, "mj-input", "qcg-textarea", 3, "ngModelChange", "ngModel", "ngModelOptions"], [1, "qcg-sub"], ["mjButton", "", "Variant", "icon", "type", "button", "title", "Remove field", 3, "click"], [1, "fa-solid", "fa-trash"]], template: function QueryFieldsGridComponent_Template(rf, ctx) { if (rf & 1) {
273
+ i0.ɵɵelementStart(0, "div", 0)(1, "table", 1)(2, "thead")(3, "tr")(4, "th", 2);
274
+ i0.ɵɵtext(5, "#");
275
+ i0.ɵɵelementEnd();
276
+ i0.ɵɵelementStart(6, "th");
277
+ i0.ɵɵtext(7, "Name");
278
+ i0.ɵɵelementEnd();
279
+ i0.ɵɵelementStart(8, "th");
280
+ i0.ɵɵtext(9, "Type");
281
+ i0.ɵɵelementEnd();
282
+ i0.ɵɵelementStart(10, "th");
283
+ i0.ɵɵtext(11, "Nullable");
284
+ i0.ɵɵelementEnd();
285
+ i0.ɵɵelementStart(12, "th");
286
+ i0.ɵɵtext(13, "Source");
287
+ i0.ɵɵelementEnd();
288
+ i0.ɵɵelementStart(14, "th");
289
+ i0.ɵɵtext(15, "Detected by");
290
+ i0.ɵɵelementEnd();
291
+ i0.ɵɵelementStart(16, "th", 3);
292
+ i0.ɵɵtext(17, "Description");
293
+ i0.ɵɵelementEnd();
294
+ i0.ɵɵconditionalCreate(18, QueryFieldsGridComponent_Conditional_18_Template, 3, 0, "th", 4);
295
+ i0.ɵɵelementEnd()();
296
+ i0.ɵɵelementStart(19, "tbody");
297
+ i0.ɵɵrepeaterCreate(20, QueryFieldsGridComponent_For_21_Template, 24, 13, "tr", 5, ctx.TrackField, true);
298
+ i0.ɵɵelementEnd()()();
299
+ } if (rf & 2) {
300
+ i0.ɵɵadvance(18);
301
+ i0.ɵɵconditional(ctx.EditMode ? 18 : -1);
302
+ i0.ɵɵadvance(2);
303
+ i0.ɵɵrepeater(ctx.Fields);
304
+ } }, dependencies: [FormsModule, i1.DefaultValueAccessor, i1.CheckboxControlValueAccessor, i1.NgControlStatus, i1.NgModel, MJButtonDirective], styles: ["[_nghost-%COMP%] {\n display: block;\n}\n\n.qcg-wrap[_ngcontent-%COMP%] {\n overflow-x: auto;\n}\n\n.qcg-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n}\n\n.qcg-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n text-align: left;\n font-weight: var(--mj-font-semibold);\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n padding: var(--mj-space-2);\n border-bottom: 1px solid var(--mj-border-default);\n white-space: nowrap;\n}\n\n.qcg-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: var(--mj-space-2);\n border-bottom: 1px solid var(--mj-border-subtle);\n vertical-align: top;\n}\n\n.qcg-row[_ngcontent-%COMP%]:hover td[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-hover);\n}\n\n\n.qcg-fact[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n}\n\n.qcg-fact[_ngcontent-%COMP%] code[_ngcontent-%COMP%], \n.qcg-object[_ngcontent-%COMP%] {\n font-family: var(--mj-font-family-mono);\n font-size: var(--mj-text-xs);\n}\n\n.qcg-seq[_ngcontent-%COMP%] {\n width: 2.5rem;\n color: var(--mj-text-muted);\n font-variant-numeric: tabular-nums;\n}\n\n.qcg-name[_ngcontent-%COMP%] {\n white-space: nowrap;\n}\n\n.qcg-annotation[_ngcontent-%COMP%] {\n min-width: 14rem;\n}\n\n.qcg-actions[_ngcontent-%COMP%] {\n width: 2.5rem;\n text-align: right;\n}\n\n.qcg-input[_ngcontent-%COMP%], \n.qcg-select[_ngcontent-%COMP%], \n.qcg-textarea[_ngcontent-%COMP%] {\n width: 100%;\n min-width: 6rem;\n font-size: var(--mj-text-sm);\n}\n\n.qcg-textarea[_ngcontent-%COMP%] {\n resize: vertical;\n margin-bottom: var(--mj-space-1);\n}\n\n.qcg-check[_ngcontent-%COMP%] {\n display: flex;\n gap: var(--mj-space-1);\n align-items: center;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n}\n\n.qcg-tag[_ngcontent-%COMP%] {\n margin-left: var(--mj-space-1);\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-sm);\n padding: 0 var(--mj-space-1);\n}\n\n.qcg-link[_ngcontent-%COMP%] {\n background: none;\n border: none;\n padding: 0;\n cursor: pointer;\n font: inherit;\n color: var(--mj-brand-primary);\n text-align: left;\n}\n\n.qcg-link[_ngcontent-%COMP%]:hover {\n text-decoration: underline;\n}\n\n.qcg-link[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.qcg-muted[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n.qcg-sub[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: var(--mj-text-xs);\n margin-top: var(--mj-space-1);\n}\n\n.qcg-detect[_ngcontent-%COMP%] {\n --qcg-accent: var(--mj-text-muted);\n display: inline-block;\n font-size: var(--mj-text-xs);\n border-radius: var(--mj-radius-full);\n padding: 0 var(--mj-space-2);\n color: var(--qcg-accent);\n background: color-mix(in srgb, var(--qcg-accent) 12%, transparent);\n white-space: nowrap;\n}\n\n.qcg-detect--database[_ngcontent-%COMP%] { --qcg-accent: var(--mj-status-info); }\n.qcg-detect--parser[_ngcontent-%COMP%] { --qcg-accent: var(--mj-brand-primary); }\n.qcg-detect--manual[_ngcontent-%COMP%] { --qcg-accent: var(--mj-status-success); }\n.qcg-detect--ai[_ngcontent-%COMP%] { --qcg-accent: var(--mj-status-warning); }\n\n.qcg-sr-only[_ngcontent-%COMP%] {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip: rect(0 0 0 0);\n white-space: nowrap;\n}"] }); }
305
+ }
306
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(QueryFieldsGridComponent, [{
307
+ type: Component,
308
+ args: [{ standalone: true, selector: 'mj-query-fields-grid', changeDetection: ChangeDetectionStrategy.Default, imports: [FormsModule, MJButtonDirective], template: "<div class=\"qcg-wrap\">\n <table class=\"qcg-table\">\n <thead>\n <tr>\n <th class=\"qcg-seq\">#</th>\n <th>Name</th>\n <th>Type</th>\n <th>Nullable</th>\n <th>Source</th>\n <th>Detected by</th>\n <th class=\"qcg-annotation\">Description</th>\n @if (EditMode) {\n <th class=\"qcg-actions\"><span class=\"qcg-sr-only\">Actions</span></th>\n }\n </tr>\n </thead>\n <tbody>\n @for (field of Fields; track TrackField($index, field)) {\n <tr class=\"qcg-row\">\n <td class=\"qcg-seq qcg-fact\">{{ field.Sequence }}</td>\n <td class=\"qcg-fact qcg-name\">\n @if (EditMode && !field.IsSaved) {\n <input class=\"mj-input qcg-input\" [(ngModel)]=\"field.Name\" [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"OnAnnotationChange()\" aria-label=\"Field name\" placeholder=\"Column name\" />\n } @else {\n <code>{{ field.Name }}</code>\n }\n @if (field.IsComputed) {\n <span class=\"qcg-tag\" title=\"The column has no direct source; the database computes it.\">computed</span>\n }\n @if (field.IsSummary) {\n <span class=\"qcg-tag\" title=\"A summary column\">summary</span>\n }\n </td>\n <td class=\"qcg-fact\"><code>{{ field.SQLFullType || field.SQLBaseType }}</code></td>\n <td class=\"qcg-fact\">{{ NullableLabel(field) }}</td>\n <td class=\"qcg-fact qcg-source\">\n @if (EntitySource(field); as source) {\n <button type=\"button\" class=\"qcg-link\" (click)=\"OnOpenSource(field)\"\n [title]=\"'Open the entity field ' + source\">\n <i class=\"fa-solid fa-link\"></i> {{ source }}\n </button>\n } @else if (field.SourceObjectName) {\n <code class=\"qcg-object\" title=\"Reported by the database server; no MJ entity reads this object\">{{ field.SourceObjectName }}</code>\n } @else {\n <span class=\"qcg-muted\">\u2014</span>\n }\n </td>\n <td class=\"qcg-fact\">\n <span class=\"qcg-detect\" [class]=\"'qcg-detect qcg-detect--' + (field.DetectionMethod || 'none').toLowerCase()\" [title]=\"DetectionTitle(field)\">{{ DetectionLabel(field) }}</span>\n </td>\n <td class=\"qcg-annotation\">\n @if (EditMode) {\n <textarea class=\"mj-input qcg-textarea\" rows=\"1\" [(ngModel)]=\"field.Description\" [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"OnAnnotationChange()\" [attr.aria-label]=\"'Description of ' + field.Name\" placeholder=\"Describe this column\"></textarea>\n @if (field.IsComputed) {\n <textarea class=\"mj-input qcg-textarea\" rows=\"1\" [(ngModel)]=\"field.ComputationDescription\" [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"OnAnnotationChange()\" [attr.aria-label]=\"'How ' + field.Name + ' is computed'\" placeholder=\"How it is computed\"></textarea>\n }\n <label class=\"qcg-check\">\n <input type=\"checkbox\" [(ngModel)]=\"field.IsSummary\" [ngModelOptions]=\"{ standalone: true }\" (ngModelChange)=\"OnAnnotationChange()\" />\n Summary column\n </label>\n @if (field.IsSummary) {\n <textarea class=\"mj-input qcg-textarea\" rows=\"1\" [(ngModel)]=\"field.SummaryDescription\" [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"OnAnnotationChange()\" [attr.aria-label]=\"'Summary description of ' + field.Name\" placeholder=\"What it summarizes\"></textarea>\n }\n } @else {\n @if (field.Description) {\n <span>{{ field.Description }}</span>\n } @else {\n <span class=\"qcg-muted\">\u2014</span>\n }\n @if (field.ComputationDescription) {\n <div class=\"qcg-sub\">{{ field.ComputationDescription }}</div>\n }\n }\n </td>\n @if (EditMode) {\n <td class=\"qcg-actions\">\n <button mjButton Variant=\"icon\" type=\"button\" (click)=\"Remove.emit(field)\" [attr.aria-label]=\"'Remove field ' + field.Name\" title=\"Remove field\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n</div>\n", styles: [":host {\n display: block;\n}\n\n.qcg-wrap {\n overflow-x: auto;\n}\n\n.qcg-table {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n}\n\n.qcg-table th {\n text-align: left;\n font-weight: var(--mj-font-semibold);\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n padding: var(--mj-space-2);\n border-bottom: 1px solid var(--mj-border-default);\n white-space: nowrap;\n}\n\n.qcg-table td {\n padding: var(--mj-space-2);\n border-bottom: 1px solid var(--mj-border-subtle);\n vertical-align: top;\n}\n\n.qcg-row:hover td {\n background: var(--mj-bg-surface-hover);\n}\n\n/* Facts come from the SQL and the server: shown plainly, never as inputs. */\n.qcg-fact {\n color: var(--mj-text-primary);\n}\n\n.qcg-fact code,\n.qcg-object {\n font-family: var(--mj-font-family-mono);\n font-size: var(--mj-text-xs);\n}\n\n.qcg-seq {\n width: 2.5rem;\n color: var(--mj-text-muted);\n font-variant-numeric: tabular-nums;\n}\n\n.qcg-name {\n white-space: nowrap;\n}\n\n.qcg-annotation {\n min-width: 14rem;\n}\n\n.qcg-actions {\n width: 2.5rem;\n text-align: right;\n}\n\n.qcg-input,\n.qcg-select,\n.qcg-textarea {\n width: 100%;\n min-width: 6rem;\n font-size: var(--mj-text-sm);\n}\n\n.qcg-textarea {\n resize: vertical;\n margin-bottom: var(--mj-space-1);\n}\n\n.qcg-check {\n display: flex;\n gap: var(--mj-space-1);\n align-items: center;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n}\n\n.qcg-tag {\n margin-left: var(--mj-space-1);\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-sm);\n padding: 0 var(--mj-space-1);\n}\n\n.qcg-link {\n background: none;\n border: none;\n padding: 0;\n cursor: pointer;\n font: inherit;\n color: var(--mj-brand-primary);\n text-align: left;\n}\n\n.qcg-link:hover {\n text-decoration: underline;\n}\n\n.qcg-link:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.qcg-muted {\n color: var(--mj-text-muted);\n}\n\n.qcg-sub {\n color: var(--mj-text-secondary);\n font-size: var(--mj-text-xs);\n margin-top: var(--mj-space-1);\n}\n\n.qcg-detect {\n --qcg-accent: var(--mj-text-muted);\n display: inline-block;\n font-size: var(--mj-text-xs);\n border-radius: var(--mj-radius-full);\n padding: 0 var(--mj-space-2);\n color: var(--qcg-accent);\n background: color-mix(in srgb, var(--qcg-accent) 12%, transparent);\n white-space: nowrap;\n}\n\n.qcg-detect--database { --qcg-accent: var(--mj-status-info); }\n.qcg-detect--parser { --qcg-accent: var(--mj-brand-primary); }\n.qcg-detect--manual { --qcg-accent: var(--mj-status-success); }\n.qcg-detect--ai { --qcg-accent: var(--mj-status-warning); }\n\n.qcg-sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip: rect(0 0 0 0);\n white-space: nowrap;\n}\n"] }]
309
+ }], null, { Fields: [{
310
+ type: Input
311
+ }], EditMode: [{
312
+ type: Input
313
+ }], Remove: [{
314
+ type: Output
315
+ }], OpenSourceField: [{
316
+ type: Output
317
+ }], Changed: [{
318
+ type: Output
319
+ }] }); })();
320
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(QueryFieldsGridComponent, { className: "QueryFieldsGridComponent", filePath: "src/lib/custom/Queries/query-fields-grid.component.ts", lineNumber: 27 }); })();
321
+ //# sourceMappingURL=query-fields-grid.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-fields-grid.component.js","sourceRoot":"","sources":["../../../../src/lib/custom/Queries/query-fields-grid.component.ts","../../../../src/lib/custom/Queries/query-fields-grid.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAChG,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;;;;;ICQhD,AAAxB,6BAAwB,cAA0B;IAAA,uBAAO;IAAO,AAAP,iBAAO,EAAK;;;;IAUjE,iCAC6F;IAD3D,+TAAwB;IACxD,mNAAiB,2BAAoB,KAAC;IADxC,iBAC6F;;;IAD3D,6CAAwB;IAAC,2DAAuC;;;IAGlG,4BAAM;IAAA,YAAgB;IAAA,iBAAO;;;IAAvB,cAAgB;IAAhB,mCAAgB;;;IAGtB,gCAAyF;IAAA,wBAAQ;IAAA,iBAAO;;;IAGxG,gCAA+C;IAAA,uBAAO;IAAA,iBAAO;;;;IAO7D,kCAC8C;IADP,mPAAS,6BAAmB,KAAC;IAElE,wBAAgC;IAAC,YACnC;IAAA,iBAAS;;;IAFP,4DAA2C;IACV,eACnC;IADmC,0CACnC;;;IAEA,gCAAiG;IAAA,YAA4B;IAAA,iBAAO;;;IAAnC,cAA4B;IAA5B,+CAA4B;;;IAE7H,gCAAwB;IAAA,sBAAC;IAAA,iBAAO;;;;IAW9B,oCACmI;IADlF,sXAA0C;IACzF,qOAAiB,2BAAoB,KAAC;IAA2F,iBAAW;;;IAD7F,+DAA0C;IAAC,2DAAuC;;;;;IAQnI,oCACqI;IADpF,8WAAsC;IACrF,qOAAiB,2BAAoB,KAAC;IAA6F,iBAAW;;;IAD/F,2DAAsC;IAAC,2DAAuC;;;;;IAXjI,oCAC+H;IAD9E,iVAA+B;IAC9E,uNAAiB,2BAAoB,KAAC;IAAuF,iBAAW;IAC1I,sHAAwB;IAKtB,AADF,iCAAyB,gBAC+G;IAA/G,0UAA6B;IAAyC,oNAAiB,2BAAoB,KAAC;IAAnI,iBAAsI;IACtI,gCACF;IAAA,iBAAQ;IACR,sHAAuB;;;IAV0B,oDAA+B;IAAC,2DAAuC;;IAExH,cAGC;IAHD,8CAGC;IAEwB,eAA6B;IAA7B,kDAA6B;IAAC,2DAAuC;IAG9F,eAGC;IAHD,6CAGC;;;IAGC,4BAAM;IAAA,YAAuB;IAAA,iBAAO;;;IAA9B,cAAuB;IAAvB,0CAAuB;;;IAE7B,gCAAwB;IAAA,sBAAC;IAAA,iBAAO;;;IAGhC,+BAAqB;IAAA,YAAkC;IAAA,iBAAM;;;IAAxC,cAAkC;IAAlC,qDAAkC;;;IAJvD,AAFF,8GAAyB,4FAEhB;IAGT,iHAAoC;;;IALpC,8CAIC;IACD,eAEC;IAFD,0DAEC;;;;IAKD,AADF,6BAAwB,iBAC2H;IAAnG,mPAAS,4BAAkB,KAAC;IACxE,wBAAiC;IAErC,AADE,iBAAS,EACN;;;IAHwE,cAAgD;;;;IA7D/H,AADF,6BAAoB,YACW;IAAA,YAAoB;IAAA,iBAAK;IACtD,6BAA8B;IAI1B,AAHF,mGAAkC,yEAGzB;IAGT,mGAAwB;IAGxB,mGAAuB;IAGzB,iBAAK;IACgB,AAArB,8BAAqB,WAAM;IAAA,aAA4C;IAAO,AAAP,iBAAO,EAAK;IACnF,+BAAqB;IAAA,aAA0B;IAAA,iBAAK;IACpD,+BAAgC;IAQ5B,AAFA,AALF,uGAAsC,+EAKD,+EAE5B;IAGX,iBAAK;IAEH,AADF,+BAAqB,gBAC4H;IAAA,aAA2B;IAC5K,AAD4K,iBAAO,EAC9K;IACL,8BAA2B;IAgBvB,AAfF,yFAAgB,mEAeP;IAUX,iBAAK;IACL,kGAAgB;IAOlB,iBAAK;;;;;IAlE0B,eAAoB;IAApB,uCAAoB;IAE/C,eAKC;IALD,8DAKC;IACD,eAEC;IAFD,8CAEC;IACD,cAEC;IAFD,6CAEC;IAEwB,eAA4C;IAA5C,kEAA4C;IAClD,eAA0B;IAA1B,oDAA0B;IAE7C,eASC;IATD,iHASC;IAGwB,eAAqF;IAArF,6FAAqF;IAAC,uDAA+B;IAAC,cAA2B;IAA3B,qDAA2B;IAG1K,eAwBC;IAxBD,2CAwBC;IAEH,eAMC;IAND,2CAMC;;AD9EX;;;;;;;;;;;GAWG;AASH,MAAM,OAAO,wBAAwB;IARrC;QASa,WAAM,GAAkC,EAAE,CAAC;QAC3C,aAAQ,GAAG,KAAK,CAAC;QAE1B,gFAAgF;QACtE,WAAM,GAAG,IAAI,YAAY,EAAsB,CAAC;QAC1D,kGAAkG;QACxF,oBAAe,GAAG,IAAI,YAAY,EAAU,CAAC;QACvD,+EAA+E;QACrE,YAAO,GAAG,IAAI,YAAY,EAAQ,CAAC;KAmChD;IAjCU,cAAc,CAAC,KAAyB;QAC3C,OAAO,oBAAoB,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IACvD,CAAC;IAEM,cAAc,CAAC,KAAyB;QAC3C,OAAO,oBAAoB,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IACvD,CAAC;IAED,oFAAoF;IAC7E,aAAa,CAAC,KAAyB;QAC1C,IAAI,KAAK,CAAC,UAAU,KAAK,IAAI,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS;YAAE,OAAO,GAAG,CAAC;QAC5E,OAAO,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3C,CAAC;IAED,oGAAoG;IAC7F,YAAY,CAAC,KAAyB;QACzC,IAAI,CAAC,KAAK,CAAC,mBAAmB;YAAE,OAAO,IAAI,CAAC;QAC5C,MAAM,MAAM,GAAG,KAAK,CAAC,YAAY,IAAI,EAAE,CAAC;QACxC,MAAM,IAAI,GAAG,KAAK,CAAC,eAAe,IAAI,KAAK,CAAC,iBAAiB,IAAI,EAAE,CAAC;QACpE,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/C,CAAC;IAEM,YAAY,CAAC,KAAyB;QACzC,IAAI,KAAK,CAAC,mBAAmB;YAAE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACxF,CAAC;IAEM,UAAU,CAAC,KAAa,EAAE,KAAyB;QACtD,OAAO,KAAK,CAAC,EAAE,IAAI,OAAO,KAAK,EAAE,CAAC;IACtC,CAAC;IAEM,kBAAkB;QACrB,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IACxB,CAAC;yHA3CQ,wBAAwB;oEAAxB,wBAAwB;YCtB7B,AADF,AADF,AADF,AADF,8BAAsB,eACK,YAChB,SACD,YACkB;YAAA,iBAAC;YAAA,iBAAK;YAC1B,0BAAI;YAAA,oBAAI;YAAA,iBAAK;YACb,0BAAI;YAAA,oBAAI;YAAA,iBAAK;YACb,2BAAI;YAAA,yBAAQ;YAAA,iBAAK;YACjB,2BAAI;YAAA,uBAAM;YAAA,iBAAK;YACf,2BAAI;YAAA,4BAAW;YAAA,iBAAK;YACpB,8BAA2B;YAAA,4BAAW;YAAA,iBAAK;YAC3C,2FAAgB;YAIpB,AADE,iBAAK,EACC;YACR,8BAAO;YACL,wGAqEC;YAGP,AADE,AADE,iBAAQ,EACF,EACJ;;YA9EE,gBAEC;YAFD,wCAEC;YAIH,eAqEC;YArED,yBAqEC;4BDhEO,WAAW,4FAAE,iBAAiB;;iFAI/B,wBAAwB;cARpC,SAAS;6BACM,IAAI,YACN,sBAAsB,mBACf,uBAAuB,CAAC,OAAO,WACvC,CAAC,WAAW,EAAE,iBAAiB,CAAC;;kBAKxC,KAAK;;kBACL,KAAK;;kBAGL,MAAM;;kBAEN,MAAM;;kBAEN,MAAM;;kFATE,wBAAwB","sourcesContent":["import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport type { MJQueryFieldEntity } from '@memberjunction/core-entities';\nimport { MJButtonDirective } from '@memberjunction/ng-ui-components';\nimport { DetectionMethodLabel, DetectionMethodTitle } from './query-child-labels';\n\n/**\n * `<mj-query-fields-grid>` — a query's output fields as a table.\n *\n * Facts come from the SQL and the database server and are read-only here: name (except on a row\n * not saved yet, which declares it), order, type, nullability, source, and how they were detected.\n * Annotations are editable in edit mode: the description, the computation description of a\n * computed column, and the summary flag and description.\n *\n * The source is a button when the column maps to an entity field (`OpenSourceField` carries the\n * field's ID; the host decides where that goes), or the server-reported `schema.object.column`\n * when it maps to no entity.\n */\n@Component({\n standalone: true,\n selector: 'mj-query-fields-grid',\n changeDetection: ChangeDetectionStrategy.Default,\n imports: [FormsModule, MJButtonDirective],\n templateUrl: './query-fields-grid.component.html',\n styleUrls: ['./query-child-grids.css'],\n})\nexport class QueryFieldsGridComponent {\n @Input() Fields: readonly MJQueryFieldEntity[] = [];\n @Input() EditMode = false;\n\n /** The user asked to remove a field (it is removed when the query is saved). */\n @Output() Remove = new EventEmitter<MJQueryFieldEntity>();\n /** The user asked to open the entity field a column comes from; carries `SourceEntityFieldID`. */\n @Output() OpenSourceField = new EventEmitter<string>();\n /** An annotation changed, so the host can update its unsaved-changes state. */\n @Output() Changed = new EventEmitter<void>();\n\n public DetectionLabel(field: MJQueryFieldEntity): string {\n return DetectionMethodLabel(field.DetectionMethod);\n }\n\n public DetectionTitle(field: MJQueryFieldEntity): string {\n return DetectionMethodTitle(field.DetectionMethod);\n }\n\n /** `Yes`, `No`, or `—` when the server does not report nullability (PostgreSQL). */\n public NullableLabel(field: MJQueryFieldEntity): string {\n if (field.IsNullable === null || field.IsNullable === undefined) return '—';\n return field.IsNullable ? 'Yes' : 'No';\n }\n\n /** The entity-field source as `Entity.Field`, or `null` when the column maps to no entity field. */\n public EntitySource(field: MJQueryFieldEntity): string | null {\n if (!field.SourceEntityFieldID) return null;\n const entity = field.SourceEntity ?? '';\n const name = field.SourceFieldName ?? field.SourceEntityField ?? '';\n return entity ? `${entity}.${name}` : name;\n }\n\n public OnOpenSource(field: MJQueryFieldEntity): void {\n if (field.SourceEntityFieldID) this.OpenSourceField.emit(field.SourceEntityFieldID);\n }\n\n public TrackField(index: number, field: MJQueryFieldEntity): string {\n return field.ID || `new-${index}`;\n }\n\n public OnAnnotationChange(): void {\n this.Changed.emit();\n }\n}\n","<div class=\"qcg-wrap\">\n <table class=\"qcg-table\">\n <thead>\n <tr>\n <th class=\"qcg-seq\">#</th>\n <th>Name</th>\n <th>Type</th>\n <th>Nullable</th>\n <th>Source</th>\n <th>Detected by</th>\n <th class=\"qcg-annotation\">Description</th>\n @if (EditMode) {\n <th class=\"qcg-actions\"><span class=\"qcg-sr-only\">Actions</span></th>\n }\n </tr>\n </thead>\n <tbody>\n @for (field of Fields; track TrackField($index, field)) {\n <tr class=\"qcg-row\">\n <td class=\"qcg-seq qcg-fact\">{{ field.Sequence }}</td>\n <td class=\"qcg-fact qcg-name\">\n @if (EditMode && !field.IsSaved) {\n <input class=\"mj-input qcg-input\" [(ngModel)]=\"field.Name\" [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"OnAnnotationChange()\" aria-label=\"Field name\" placeholder=\"Column name\" />\n } @else {\n <code>{{ field.Name }}</code>\n }\n @if (field.IsComputed) {\n <span class=\"qcg-tag\" title=\"The column has no direct source; the database computes it.\">computed</span>\n }\n @if (field.IsSummary) {\n <span class=\"qcg-tag\" title=\"A summary column\">summary</span>\n }\n </td>\n <td class=\"qcg-fact\"><code>{{ field.SQLFullType || field.SQLBaseType }}</code></td>\n <td class=\"qcg-fact\">{{ NullableLabel(field) }}</td>\n <td class=\"qcg-fact qcg-source\">\n @if (EntitySource(field); as source) {\n <button type=\"button\" class=\"qcg-link\" (click)=\"OnOpenSource(field)\"\n [title]=\"'Open the entity field ' + source\">\n <i class=\"fa-solid fa-link\"></i> {{ source }}\n </button>\n } @else if (field.SourceObjectName) {\n <code class=\"qcg-object\" title=\"Reported by the database server; no MJ entity reads this object\">{{ field.SourceObjectName }}</code>\n } @else {\n <span class=\"qcg-muted\">—</span>\n }\n </td>\n <td class=\"qcg-fact\">\n <span class=\"qcg-detect\" [class]=\"'qcg-detect qcg-detect--' + (field.DetectionMethod || 'none').toLowerCase()\" [title]=\"DetectionTitle(field)\">{{ DetectionLabel(field) }}</span>\n </td>\n <td class=\"qcg-annotation\">\n @if (EditMode) {\n <textarea class=\"mj-input qcg-textarea\" rows=\"1\" [(ngModel)]=\"field.Description\" [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"OnAnnotationChange()\" [attr.aria-label]=\"'Description of ' + field.Name\" placeholder=\"Describe this column\"></textarea>\n @if (field.IsComputed) {\n <textarea class=\"mj-input qcg-textarea\" rows=\"1\" [(ngModel)]=\"field.ComputationDescription\" [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"OnAnnotationChange()\" [attr.aria-label]=\"'How ' + field.Name + ' is computed'\" placeholder=\"How it is computed\"></textarea>\n }\n <label class=\"qcg-check\">\n <input type=\"checkbox\" [(ngModel)]=\"field.IsSummary\" [ngModelOptions]=\"{ standalone: true }\" (ngModelChange)=\"OnAnnotationChange()\" />\n Summary column\n </label>\n @if (field.IsSummary) {\n <textarea class=\"mj-input qcg-textarea\" rows=\"1\" [(ngModel)]=\"field.SummaryDescription\" [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"OnAnnotationChange()\" [attr.aria-label]=\"'Summary description of ' + field.Name\" placeholder=\"What it summarizes\"></textarea>\n }\n } @else {\n @if (field.Description) {\n <span>{{ field.Description }}</span>\n } @else {\n <span class=\"qcg-muted\">—</span>\n }\n @if (field.ComputationDescription) {\n <div class=\"qcg-sub\">{{ field.ComputationDescription }}</div>\n }\n }\n </td>\n @if (EditMode) {\n <td class=\"qcg-actions\">\n <button mjButton Variant=\"icon\" type=\"button\" (click)=\"Remove.emit(field)\" [attr.aria-label]=\"'Remove field ' + field.Name\" title=\"Remove field\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n</div>\n"]}
@@ -0,0 +1,37 @@
1
+ import type { QueryDiagnosticLine } from '@memberjunction/core-entities';
2
+ import type { DiagnosticMarker, DiagnosticMarkerSeverity } from '@memberjunction/ng-code-editor';
3
+ /**
4
+ * Plain functions behind the query form: reading a refused save, the editor markers, and which
5
+ * field rows the user may see. No Angular, so they are tested on their own.
6
+ */
7
+ /** A refused save's findings, as the form lists them. */
8
+ export interface QuerySaveRefusal {
9
+ readonly Headline: string | null;
10
+ readonly Diagnostics: readonly QueryDiagnosticLine[];
11
+ }
12
+ /** A query's `ExtractionStatus`. */
13
+ export type QueryExtractionStatus = 'OK' | 'Warning' | 'Error' | 'Skipped' | null | undefined;
14
+ /**
15
+ * The findings of a refused save, or `null` when the failure is not a refusal by the query's
16
+ * rules (a network or permission error, which the form's own failure message already reports).
17
+ */
18
+ export declare function SaveRefusalOf(message: string | null | undefined): QuerySaveRefusal | null;
19
+ /** How serious an extraction's findings are. */
20
+ export declare function ExtractionSeverityOf(status: QueryExtractionStatus): DiagnosticMarkerSeverity;
21
+ /**
22
+ * The SQL editor's markers: a refused save's findings as errors while there are any, otherwise
23
+ * the last extraction's findings at its severity. Findings without a location are not marked.
24
+ */
25
+ export declare function EditorMarkersFor(saveFindings: readonly QueryDiagnosticLine[], extractionFindings: readonly QueryDiagnosticLine[], extractionStatus: QueryExtractionStatus): DiagnosticMarker[];
26
+ /** The part of a field row the visibility filter reads. */
27
+ export interface FieldRowIdentity {
28
+ readonly ID: string;
29
+ readonly IsSaved: boolean;
30
+ }
31
+ /**
32
+ * Leaves out the stored field rows the user may not see. `allStored` is every stored field of the
33
+ * query and `visibleStored` the ones the user may see (`QueryFieldsVisibleTo`); a row not saved yet
34
+ * is the user's own and always kept.
35
+ */
36
+ export declare function HideUnreadableFieldRows<T extends FieldRowIdentity>(rows: readonly T[], allStored: readonly FieldRowIdentity[], visibleStored: readonly FieldRowIdentity[]): T[];
37
+ //# sourceMappingURL=query-form-logic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-form-logic.d.ts","sourceRoot":"","sources":["../../../../src/lib/custom/Queries/query-form-logic.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAGjG;;;GAGG;AAEH,yDAAyD;AACzD,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,WAAW,EAAE,SAAS,mBAAmB,EAAE,CAAC;CACxD;AAED,oCAAoC;AACpC,MAAM,MAAM,qBAAqB,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,IAAI,GAAG,SAAS,CAAC;AAE9F;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,gBAAgB,GAAG,IAAI,CAIzF;AAED,gDAAgD;AAChD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,qBAAqB,GAAG,wBAAwB,CAI5F;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC5B,YAAY,EAAE,SAAS,mBAAmB,EAAE,EAC5C,kBAAkB,EAAE,SAAS,mBAAmB,EAAE,EAClD,gBAAgB,EAAE,qBAAqB,GACxC,gBAAgB,EAAE,CAUpB;AAED,2DAA2D;AAC3D,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC7B;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,SAAS,gBAAgB,EAC9D,IAAI,EAAE,SAAS,CAAC,EAAE,EAClB,SAAS,EAAE,SAAS,gBAAgB,EAAE,EACtC,aAAa,EAAE,SAAS,gBAAgB,EAAE,GAC3C,CAAC,EAAE,CAKL"}
@@ -0,0 +1,48 @@
1
+ import { ParseQuerySaveMessage } from '@memberjunction/core-entities';
2
+ import { UUIDSet } from '@memberjunction/global';
3
+ /**
4
+ * The findings of a refused save, or `null` when the failure is not a refusal by the query's
5
+ * rules (a network or permission error, which the form's own failure message already reports).
6
+ */
7
+ export function SaveRefusalOf(message) {
8
+ const parsed = ParseQuerySaveMessage(message);
9
+ const isRuleRefusal = parsed.Diagnostics.some(d => d.Code !== null) || !!parsed.Headline;
10
+ return isRuleRefusal ? { Headline: parsed.Headline, Diagnostics: parsed.Diagnostics } : null;
11
+ }
12
+ /** How serious an extraction's findings are. */
13
+ export function ExtractionSeverityOf(status) {
14
+ if (status === 'Error')
15
+ return 'error';
16
+ if (status === 'Warning')
17
+ return 'warning';
18
+ return 'info';
19
+ }
20
+ /**
21
+ * The SQL editor's markers: a refused save's findings as errors while there are any, otherwise
22
+ * the last extraction's findings at its severity. Findings without a location are not marked.
23
+ */
24
+ export function EditorMarkersFor(saveFindings, extractionFindings, extractionStatus) {
25
+ const fromSave = saveFindings.length > 0;
26
+ const source = fromSave ? saveFindings : extractionFindings;
27
+ const severity = fromSave ? 'error' : ExtractionSeverityOf(extractionStatus);
28
+ const markers = [];
29
+ for (const d of source) {
30
+ if (d.Line === null || d.Column === null)
31
+ continue;
32
+ markers.push({ Line: d.Line, Column: d.Column, Severity: severity, Message: d.FixHint ? `${d.Message} ${d.FixHint}` : d.Message });
33
+ }
34
+ return markers;
35
+ }
36
+ /**
37
+ * Leaves out the stored field rows the user may not see. `allStored` is every stored field of the
38
+ * query and `visibleStored` the ones the user may see (`QueryFieldsVisibleTo`); a row not saved yet
39
+ * is the user's own and always kept.
40
+ */
41
+ export function HideUnreadableFieldRows(rows, allStored, visibleStored) {
42
+ const visible = new UUIDSet(visibleStored.map(v => v.ID));
43
+ const hidden = new UUIDSet(allStored.filter(f => !visible.Has(f.ID)).map(f => f.ID));
44
+ if (hidden.Size === 0)
45
+ return [...rows];
46
+ return rows.filter(r => !r.IsSaved || !hidden.Has(r.ID));
47
+ }
48
+ //# sourceMappingURL=query-form-logic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-form-logic.js","sourceRoot":"","sources":["../../../../src/lib/custom/Queries/query-form-logic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAGtE,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAgBjD;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,OAAkC;IAC5D,MAAM,MAAM,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,aAAa,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;IACzF,OAAO,aAAa,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACjG,CAAC;AAED,gDAAgD;AAChD,MAAM,UAAU,oBAAoB,CAAC,MAA6B;IAC9D,IAAI,MAAM,KAAK,OAAO;QAAE,OAAO,OAAO,CAAC;IACvC,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC3C,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC5B,YAA4C,EAC5C,kBAAkD,EAClD,gBAAuC;IAEvC,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,kBAAkB,CAAC;IAC5D,MAAM,QAAQ,GAA6B,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC,gBAAgB,CAAC,CAAC;IACvG,MAAM,OAAO,GAAuB,EAAE,CAAC;IACvC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACrB,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,MAAM,KAAK,IAAI;YAAE,SAAS;QACnD,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IACvI,CAAC;IACD,OAAO,OAAO,CAAC;AACnB,CAAC;AAQD;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CACnC,IAAkB,EAClB,SAAsC,EACtC,aAA0C;IAE1C,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAG,IAAI,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACrF,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;IACxC,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC7D,CAAC","sourcesContent":["import { ParseQuerySaveMessage } from '@memberjunction/core-entities';\nimport type { QueryDiagnosticLine } from '@memberjunction/core-entities';\nimport type { DiagnosticMarker, DiagnosticMarkerSeverity } from '@memberjunction/ng-code-editor';\nimport { UUIDSet } from '@memberjunction/global';\n\n/**\n * Plain functions behind the query form: reading a refused save, the editor markers, and which\n * field rows the user may see. No Angular, so they are tested on their own.\n */\n\n/** A refused save's findings, as the form lists them. */\nexport interface QuerySaveRefusal {\n readonly Headline: string | null;\n readonly Diagnostics: readonly QueryDiagnosticLine[];\n}\n\n/** A query's `ExtractionStatus`. */\nexport type QueryExtractionStatus = 'OK' | 'Warning' | 'Error' | 'Skipped' | null | undefined;\n\n/**\n * The findings of a refused save, or `null` when the failure is not a refusal by the query's\n * rules (a network or permission error, which the form's own failure message already reports).\n */\nexport function SaveRefusalOf(message: string | null | undefined): QuerySaveRefusal | null {\n const parsed = ParseQuerySaveMessage(message);\n const isRuleRefusal = parsed.Diagnostics.some(d => d.Code !== null) || !!parsed.Headline;\n return isRuleRefusal ? { Headline: parsed.Headline, Diagnostics: parsed.Diagnostics } : null;\n}\n\n/** How serious an extraction's findings are. */\nexport function ExtractionSeverityOf(status: QueryExtractionStatus): DiagnosticMarkerSeverity {\n if (status === 'Error') return 'error';\n if (status === 'Warning') return 'warning';\n return 'info';\n}\n\n/**\n * The SQL editor's markers: a refused save's findings as errors while there are any, otherwise\n * the last extraction's findings at its severity. Findings without a location are not marked.\n */\nexport function EditorMarkersFor(\n saveFindings: readonly QueryDiagnosticLine[],\n extractionFindings: readonly QueryDiagnosticLine[],\n extractionStatus: QueryExtractionStatus,\n): DiagnosticMarker[] {\n const fromSave = saveFindings.length > 0;\n const source = fromSave ? saveFindings : extractionFindings;\n const severity: DiagnosticMarkerSeverity = fromSave ? 'error' : ExtractionSeverityOf(extractionStatus);\n const markers: DiagnosticMarker[] = [];\n for (const d of source) {\n if (d.Line === null || d.Column === null) continue;\n markers.push({ Line: d.Line, Column: d.Column, Severity: severity, Message: d.FixHint ? `${d.Message} ${d.FixHint}` : d.Message });\n }\n return markers;\n}\n\n/** The part of a field row the visibility filter reads. */\nexport interface FieldRowIdentity {\n readonly ID: string;\n readonly IsSaved: boolean;\n}\n\n/**\n * Leaves out the stored field rows the user may not see. `allStored` is every stored field of the\n * query and `visibleStored` the ones the user may see (`QueryFieldsVisibleTo`); a row not saved yet\n * is the user's own and always kept.\n */\nexport function HideUnreadableFieldRows<T extends FieldRowIdentity>(\n rows: readonly T[],\n allStored: readonly FieldRowIdentity[],\n visibleStored: readonly FieldRowIdentity[],\n): T[] {\n const visible = new UUIDSet(visibleStored.map(v => v.ID));\n const hidden = new UUIDSet(allStored.filter(f => !visible.Has(f.ID)).map(f => f.ID));\n if (hidden.Size === 0) return [...rows];\n return rows.filter(r => !r.IsSaved || !hidden.Has(r.ID));\n}\n"]}