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

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 (103) 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/Entities/entity-form.component.js +3 -3
  7. package/dist/lib/custom/Entities/entity-form.component.js.map +1 -1
  8. package/dist/lib/custom/Files/file-form.component.d.ts +8 -0
  9. package/dist/lib/custom/Files/file-form.component.d.ts.map +1 -1
  10. package/dist/lib/custom/Files/file-form.component.js +21 -5
  11. package/dist/lib/custom/Files/file-form.component.js.map +1 -1
  12. package/dist/lib/custom/Files/file-form.logic.d.ts +7 -0
  13. package/dist/lib/custom/Files/file-form.logic.d.ts.map +1 -1
  14. package/dist/lib/custom/Files/file-form.logic.js +20 -0
  15. package/dist/lib/custom/Files/file-form.logic.js.map +1 -1
  16. package/dist/lib/custom/Lists/list-form.component.js +5 -5
  17. package/dist/lib/custom/Lists/list-form.component.js.map +1 -1
  18. package/dist/lib/custom/Queries/query-child-labels.d.ts +12 -0
  19. package/dist/lib/custom/Queries/query-child-labels.d.ts.map +1 -0
  20. package/dist/lib/custom/Queries/query-child-labels.js +28 -0
  21. package/dist/lib/custom/Queries/query-child-labels.js.map +1 -0
  22. package/dist/lib/custom/Queries/query-fields-grid.component.d.ts +37 -0
  23. package/dist/lib/custom/Queries/query-fields-grid.component.d.ts.map +1 -0
  24. package/dist/lib/custom/Queries/query-fields-grid.component.js +321 -0
  25. package/dist/lib/custom/Queries/query-fields-grid.component.js.map +1 -0
  26. package/dist/lib/custom/Queries/query-form-logic.d.ts +37 -0
  27. package/dist/lib/custom/Queries/query-form-logic.d.ts.map +1 -0
  28. package/dist/lib/custom/Queries/query-form-logic.js +48 -0
  29. package/dist/lib/custom/Queries/query-form-logic.js.map +1 -0
  30. package/dist/lib/custom/Queries/query-form.component.d.ts +76 -7
  31. package/dist/lib/custom/Queries/query-form.component.d.ts.map +1 -1
  32. package/dist/lib/custom/Queries/query-form.component.js +740 -688
  33. package/dist/lib/custom/Queries/query-form.component.js.map +1 -1
  34. package/dist/lib/custom/Queries/query-parameters-grid.component.d.ts +31 -0
  35. package/dist/lib/custom/Queries/query-parameters-grid.component.d.ts.map +1 -0
  36. package/dist/lib/custom/Queries/query-parameters-grid.component.js +298 -0
  37. package/dist/lib/custom/Queries/query-parameters-grid.component.js.map +1 -0
  38. package/dist/lib/custom/Rubrics/record-forms.component.js +2 -2
  39. package/dist/lib/custom/Rubrics/record-forms.component.js.map +1 -1
  40. package/dist/lib/custom/Rubrics/scale-form.component.d.ts.map +1 -1
  41. package/dist/lib/custom/Rubrics/scale-form.component.js +2 -1
  42. package/dist/lib/custom/Rubrics/scale-form.component.js.map +1 -1
  43. package/dist/lib/custom/SearchScopes/searchscope-form.component.js +1 -1
  44. package/dist/lib/custom/SearchScopes/searchscope-form.component.js.map +1 -1
  45. package/dist/lib/custom/custom-forms.module.d.ts +41 -35
  46. package/dist/lib/custom/custom-forms.module.d.ts.map +1 -1
  47. package/dist/lib/custom/custom-forms.module.js +32 -3
  48. package/dist/lib/custom/custom-forms.module.js.map +1 -1
  49. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.d.ts.map +1 -1
  50. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js +234 -226
  51. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js.map +1 -1
  52. package/dist/lib/generated/Entities/MJAIAgentConfiguration/mjaiagentconfiguration.form.component.d.ts.map +1 -1
  53. package/dist/lib/generated/Entities/MJAIAgentConfiguration/mjaiagentconfiguration.form.component.js +25 -6
  54. package/dist/lib/generated/Entities/MJAIAgentConfiguration/mjaiagentconfiguration.form.component.js.map +1 -1
  55. package/dist/lib/generated/Entities/MJAIAgentRelationship/mjaiagentrelationship.form.component.d.ts.map +1 -1
  56. package/dist/lib/generated/Entities/MJAIAgentRelationship/mjaiagentrelationship.form.component.js +13 -3
  57. package/dist/lib/generated/Entities/MJAIAgentRelationship/mjaiagentrelationship.form.component.js.map +1 -1
  58. package/dist/lib/generated/Entities/MJBrandKit/mjbrandkit.form.component.d.ts +10 -0
  59. package/dist/lib/generated/Entities/MJBrandKit/mjbrandkit.form.component.d.ts.map +1 -0
  60. package/dist/lib/generated/Entities/MJBrandKit/mjbrandkit.form.component.js +91 -0
  61. package/dist/lib/generated/Entities/MJBrandKit/mjbrandkit.form.component.js.map +1 -0
  62. package/dist/lib/generated/Entities/MJBrandKitAsset/mjbrandkitasset.form.component.d.ts +10 -0
  63. package/dist/lib/generated/Entities/MJBrandKitAsset/mjbrandkitasset.form.component.d.ts.map +1 -0
  64. package/dist/lib/generated/Entities/MJBrandKitAsset/mjbrandkitasset.form.component.js +72 -0
  65. package/dist/lib/generated/Entities/MJBrandKitAsset/mjbrandkitasset.form.component.js.map +1 -0
  66. package/dist/lib/generated/Entities/MJCompany/mjcompany.form.component.d.ts.map +1 -1
  67. package/dist/lib/generated/Entities/MJCompany/mjcompany.form.component.js +46 -10
  68. package/dist/lib/generated/Entities/MJCompany/mjcompany.form.component.js.map +1 -1
  69. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.d.ts.map +1 -1
  70. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js +459 -451
  71. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js.map +1 -1
  72. package/dist/lib/generated/Entities/MJEntityField/mjentityfield.form.component.d.ts.map +1 -1
  73. package/dist/lib/generated/Entities/MJEntityField/mjentityfield.form.component.js +24 -6
  74. package/dist/lib/generated/Entities/MJEntityField/mjentityfield.form.component.js.map +1 -1
  75. package/dist/lib/generated/Entities/MJFile/mjfile.form.component.d.ts.map +1 -1
  76. package/dist/lib/generated/Entities/MJFile/mjfile.form.component.js +32 -14
  77. package/dist/lib/generated/Entities/MJFile/mjfile.form.component.js.map +1 -1
  78. package/dist/lib/generated/Entities/MJQuery/mjquery.form.component.js +67 -61
  79. package/dist/lib/generated/Entities/MJQuery/mjquery.form.component.js.map +1 -1
  80. package/dist/lib/generated/Entities/MJQueryField/mjqueryfield.form.component.d.ts.map +1 -1
  81. package/dist/lib/generated/Entities/MJQueryField/mjqueryfield.form.component.js +15 -3
  82. package/dist/lib/generated/Entities/MJQueryField/mjqueryfield.form.component.js.map +1 -1
  83. package/dist/lib/generated/Entities/MJVideoArchetype/mjvideoarchetype.form.component.d.ts +10 -0
  84. package/dist/lib/generated/Entities/MJVideoArchetype/mjvideoarchetype.form.component.d.ts.map +1 -0
  85. package/dist/lib/generated/Entities/MJVideoArchetype/mjvideoarchetype.form.component.js +80 -0
  86. package/dist/lib/generated/Entities/MJVideoArchetype/mjvideoarchetype.form.component.js.map +1 -0
  87. package/dist/lib/generated/generated-forms.module.d.ts +334 -331
  88. package/dist/lib/generated/generated-forms.module.d.ts.map +1 -1
  89. package/dist/lib/generated/generated-forms.module.js +11 -2
  90. package/dist/lib/generated/generated-forms.module.js.map +1 -1
  91. package/dist/lib/panels/brand-kits/brand-kit-assets.panel.d.ts +15 -0
  92. package/dist/lib/panels/brand-kits/brand-kit-assets.panel.d.ts.map +1 -0
  93. package/dist/lib/panels/brand-kits/brand-kit-assets.panel.js +52 -0
  94. package/dist/lib/panels/brand-kits/brand-kit-assets.panel.js.map +1 -0
  95. package/dist/lib/panels/brand-kits/brand-kit-generation-policy.panel.d.ts +15 -0
  96. package/dist/lib/panels/brand-kits/brand-kit-generation-policy.panel.d.ts.map +1 -0
  97. package/dist/lib/panels/brand-kits/brand-kit-generation-policy.panel.js +52 -0
  98. package/dist/lib/panels/brand-kits/brand-kit-generation-policy.panel.js.map +1 -0
  99. package/dist/public-api.d.ts +2 -0
  100. package/dist/public-api.d.ts.map +1 -1
  101. package/dist/public-api.js +3 -0
  102. package/dist/public-api.js.map +1 -1
  103. package/package.json +50 -48
@@ -200,7 +200,7 @@ let ConversationOverviewPanel = class ConversationOverviewPanel extends BaseForm
200
200
  this.AgentMessageCount = agent?.TotalRowCount ?? 0;
201
201
  this.Messages = recent?.Results ?? [];
202
202
  }
203
- this.ForkCount = forks?.Success ? forks.TotalRowCount : 0;
203
+ this.ForkCount = forks?.Success ? forks.TotalRowCount ?? 0 : 0;
204
204
  }
205
205
  catch (e) {
206
206
  const message = e instanceof Error ? e.message : String(e);
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-overview.panel.js","sourceRoot":"","sources":["../../../../src/lib/custom/Conversations/conversation-overview.panel.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, ChangeDetectionStrategy, OnInit, inject, ChangeDetectorRef } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { IMetadataProvider, LogError, Metadata, RunView } from '@memberjunction/core';\nimport { EscapeSQLString, RegisterClassEx } from '@memberjunction/global';\nimport { BaseFormPanel } from '@memberjunction/ng-base-forms';\nimport { ConversationEngine, MJConversationDetailEntity, MJConversationEntity } from '@memberjunction/core-entities';\n\ninterface ConversationDetailRow {\n ID: string;\n Role: MJConversationDetailEntity['Role'];\n Message: string;\n CreatedAt: string;\n}\n\n/** Number of newest messages the Recent Turns card shows. */\nconst RECENT_MESSAGE_COUNT = 4;\n\n@RegisterClassEx(BaseFormPanel, {\n key: 'form-panel:MJ: Conversations:overview',\n metadata: {\n entity: 'MJ: Conversations',\n slot: 'before-fields',\n sortKey: 10,\n },\n})\n@Component({\n selector: 'mj-conversation-overview-panel',\n standalone: true,\n imports: [CommonModule],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"mj-convo-overview-grid\">\n <!-- Card 1: Message Flow Metrics -->\n <div class=\"mj-overview-card\">\n <div class=\"mj-card-header\">\n <div class=\"mj-card-title\"><i class=\"fa-solid fa-comments\" style=\"color: var(--mj-brand-primary, #38bdf8);\"></i> Turn Summary</div>\n @if (!LoadError) {\n <span class=\"mj-card-badge\">{{ TotalMessageCount }} Turns</span>\n }\n </div>\n <div class=\"mj-card-body\">\n @if (LoadError) {\n <span class=\"mj-load-error\">{{ LoadError }}</span>\n } @else {\n <div class=\"mj-metric-row\">\n <span class=\"mj-metric-label\">Total Messages</span>\n <span class=\"mj-metric-val\">{{ TotalMessageCount }}</span>\n </div>\n @if (ForkCount > 0) {\n <div class=\"mj-fork-note\">plus {{ ForkCount }} {{ ForkCount === 1 ? 'fork' : 'forks' }}</div>\n }\n <div class=\"mj-metric-row\">\n <span class=\"mj-metric-label\">User Prompts</span>\n <span class=\"mj-metric-val\">{{ UserMessageCount }}</span>\n </div>\n <div class=\"mj-metric-row\">\n <span class=\"mj-metric-label\">Agent Responses</span>\n <span class=\"mj-metric-val\">{{ AgentMessageCount }}</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Card 2: Recent Activity Stream -->\n <div class=\"mj-overview-card\">\n <div class=\"mj-card-header\">\n <div class=\"mj-card-title\"><i class=\"fa-solid fa-clock-rotate-left\" style=\"color: #10b981;\"></i> Recent Turns</div>\n <span class=\"mj-card-badge\">History</span>\n </div>\n <div class=\"mj-card-body\">\n @if (LoadError) {\n <span class=\"mj-load-error\">{{ LoadError }}</span>\n } @else if (Messages.length === 0) {\n <span style=\"font-size: 12px; color: var(--mj-text-muted);\">No messages in this conversation yet.</span>\n } @else {\n @for (msg of RecentMessages; track msg.ID) {\n <div class=\"mj-metric-row\">\n <span class=\"mj-metric-label\" style=\"text-overflow: ellipsis; overflow: hidden; white-space: nowrap; max-width: 200px;\">\n <strong>{{ msg.Role }}:</strong> {{ msg.Message }}\n </span>\n <span class=\"mj-pill\" [class.mj-pill-blue]=\"IsUserTurn(msg)\" [class.mj-pill-green]=\"IsAgentTurn(msg)\">\n {{ msg.Role }}\n </span>\n </div>\n }\n }\n </div>\n </div>\n </div>\n `,\n styles: [`\n :host { display: block; width: 100%; margin-bottom: 20px; }\n .mj-convo-overview-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));\n gap: 16px;\n }\n .mj-overview-card {\n background: var(--mj-bg-surface-card, #141f36);\n border: 1px solid var(--mj-border-default, #223254);\n border-radius: 10px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n .mj-card-header {\n padding: 10px 14px;\n background: var(--mj-bg-surface, #111a2e);\n border-bottom: 1px solid var(--mj-border-default, #223254);\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n .mj-card-title {\n font-size: 12.5px;\n font-weight: 700;\n color: var(--mj-text-primary, #f8fafc);\n display: flex;\n align-items: center;\n gap: 8px;\n }\n .mj-card-badge {\n font-size: 11px;\n padding: 2px 7px;\n border-radius: 9999px;\n background: var(--mj-bg-surface-elevated, #1a2744);\n color: var(--mj-text-secondary, #94a3b8);\n border: 1px solid var(--mj-border-default, #223254);\n }\n .mj-card-body {\n padding: 14px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n }\n .mj-metric-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n font-size: 12px;\n }\n .mj-metric-label { color: var(--mj-text-secondary, #94a3b8); }\n .mj-fork-note { font-size: 11px; color: var(--mj-text-muted); margin-top: -6px; }\n .mj-metric-val { font-weight: 600; color: var(--mj-text-primary, #f8fafc); font-family: monospace; }\n .mj-load-error { font-size: 12px; color: var(--mj-status-error); }\n .mj-pill { font-size: 10.5px; font-weight: 700; padding: 2px 6px; border-radius: 4px; }\n .mj-pill-green { background: rgba(16, 185, 129, 0.15); color: #10b981; }\n .mj-pill-blue { background: rgba(56, 189, 248, 0.15); color: #38bdf8; }\n `]\n})\nexport class ConversationOverviewPanel extends BaseFormPanel<MJConversationEntity> implements OnInit {\n private cdr = inject(ChangeDetectorRef);\n /** The newest messages in Main, newest first. */\n public Messages: ConversationDetailRow[] = [];\n /** Messages in Main. */\n public TotalMessageCount = 0;\n /** User messages in Main. */\n public UserMessageCount = 0;\n /** AI messages in Main. */\n public AgentMessageCount = 0;\n /** Forks of the conversation. */\n public ForkCount = 0;\n /** Set when a read fails, so the cards show the failure instead of zero messages. */\n public LoadError: string | null = null;\n\n public ngOnInit(): void {\n this.loadConversationMessages();\n }\n\n /** A turn the user sent. `Role` is stored as 'User', 'AI' or 'Error'. */\n protected IsUserTurn(detail: ConversationDetailRow): boolean {\n return detail.Role === 'User';\n }\n\n /** A turn an agent sent. An 'Error' turn is neither a user turn nor an agent turn. */\n protected IsAgentTurn(detail: ConversationDetailRow): boolean {\n return detail.Role === 'AI';\n }\n\n public get RecentMessages(): ConversationDetailRow[] {\n return this.Messages.slice(0, RECENT_MESSAGE_COUNT);\n }\n\n /** The host form's provider, or the default provider when the panel has no host form. */\n private get providerToUse(): IMetadataProvider {\n return this.FormComponent?.ProviderToUse ?? Metadata.Provider; // global-provider-ok: BaseFormPanel has no Provider input; a panel without a host form uses the default provider\n }\n\n /**\n * Loads the counts and newest messages in Main, and the conversation's fork count, in one\n * batch. When a detail read fails, the cards show the failure.\n */\n private async loadConversationMessages(): Promise<void> {\n if (!this.Record?.ID) return;\n const provider = this.providerToUse;\n const scope = ConversationEngine.TrunkScope(this.Record.ID);\n try {\n const rv = RunView.FromMetadataProvider(provider);\n const [total, user, agent, recent, forks] = await rv.RunViews<ConversationDetailRow>([\n {\n EntityName: 'MJ: Conversation Details',\n ExtraFilter: ConversationEngine.ScopeFilter(scope),\n ResultType: 'count_only',\n },\n {\n EntityName: 'MJ: Conversation Details',\n ExtraFilter: `${ConversationEngine.ScopeFilter(scope)} AND [Role]='User'`,\n ResultType: 'count_only',\n },\n {\n EntityName: 'MJ: Conversation Details',\n ExtraFilter: `${ConversationEngine.ScopeFilter(scope)} AND [Role]='AI'`,\n ResultType: 'count_only',\n },\n {\n EntityName: 'MJ: Conversation Details',\n ExtraFilter: ConversationEngine.ScopeFilter(scope),\n Fields: ['ID', 'Role', 'Message', '__mj_CreatedAt'],\n OrderBy: 'Sequence DESC',\n MaxRows: RECENT_MESSAGE_COUNT,\n ResultType: 'simple',\n },\n {\n EntityName: 'MJ: Conversation Branches',\n ExtraFilter: `ConversationID='${EscapeSQLString(this.Record.ID)}'`,\n ResultType: 'count_only',\n },\n ], provider.CurrentUser);\n const detailReads = [total, user, agent, recent];\n const failed = detailReads.findIndex(r => !r?.Success);\n if (failed >= 0) {\n this.showLoadError(detailReads[failed]?.ErrorMessage);\n } else {\n this.TotalMessageCount = total?.TotalRowCount ?? 0;\n this.UserMessageCount = user?.TotalRowCount ?? 0;\n this.AgentMessageCount = agent?.TotalRowCount ?? 0;\n this.Messages = recent?.Results ?? [];\n }\n this.ForkCount = forks?.Success ? forks.TotalRowCount : 0;\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n LogError(`Conversation overview: could not load the details of conversation ${this.Record.ID}: ${message}`);\n this.showLoadError(message);\n }\n this.cdr.markForCheck();\n }\n\n /** Shows a short \"could not load\" line, with the underlying message when there is one. */\n private showLoadError(detail: string | undefined): void {\n this.LoadError = detail ? `Could not load messages: ${detail}` : 'Could not load messages.';\n }\n}\n"]}
1
+ {"version":3,"file":"conversation-overview.panel.js","sourceRoot":"","sources":["../../../../src/lib/custom/Conversations/conversation-overview.panel.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, ChangeDetectionStrategy, OnInit, inject, ChangeDetectorRef } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { IMetadataProvider, LogError, Metadata, RunView } from '@memberjunction/core';\nimport { EscapeSQLString, RegisterClassEx } from '@memberjunction/global';\nimport { BaseFormPanel } from '@memberjunction/ng-base-forms';\nimport { ConversationEngine, MJConversationDetailEntity, MJConversationEntity } from '@memberjunction/core-entities';\n\ninterface ConversationDetailRow {\n ID: string;\n Role: MJConversationDetailEntity['Role'];\n Message: string;\n CreatedAt: string;\n}\n\n/** Number of newest messages the Recent Turns card shows. */\nconst RECENT_MESSAGE_COUNT = 4;\n\n@RegisterClassEx(BaseFormPanel, {\n key: 'form-panel:MJ: Conversations:overview',\n metadata: {\n entity: 'MJ: Conversations',\n slot: 'before-fields',\n sortKey: 10,\n },\n})\n@Component({\n selector: 'mj-conversation-overview-panel',\n standalone: true,\n imports: [CommonModule],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"mj-convo-overview-grid\">\n <!-- Card 1: Message Flow Metrics -->\n <div class=\"mj-overview-card\">\n <div class=\"mj-card-header\">\n <div class=\"mj-card-title\"><i class=\"fa-solid fa-comments\" style=\"color: var(--mj-brand-primary, #38bdf8);\"></i> Turn Summary</div>\n @if (!LoadError) {\n <span class=\"mj-card-badge\">{{ TotalMessageCount }} Turns</span>\n }\n </div>\n <div class=\"mj-card-body\">\n @if (LoadError) {\n <span class=\"mj-load-error\">{{ LoadError }}</span>\n } @else {\n <div class=\"mj-metric-row\">\n <span class=\"mj-metric-label\">Total Messages</span>\n <span class=\"mj-metric-val\">{{ TotalMessageCount }}</span>\n </div>\n @if (ForkCount > 0) {\n <div class=\"mj-fork-note\">plus {{ ForkCount }} {{ ForkCount === 1 ? 'fork' : 'forks' }}</div>\n }\n <div class=\"mj-metric-row\">\n <span class=\"mj-metric-label\">User Prompts</span>\n <span class=\"mj-metric-val\">{{ UserMessageCount }}</span>\n </div>\n <div class=\"mj-metric-row\">\n <span class=\"mj-metric-label\">Agent Responses</span>\n <span class=\"mj-metric-val\">{{ AgentMessageCount }}</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Card 2: Recent Activity Stream -->\n <div class=\"mj-overview-card\">\n <div class=\"mj-card-header\">\n <div class=\"mj-card-title\"><i class=\"fa-solid fa-clock-rotate-left\" style=\"color: #10b981;\"></i> Recent Turns</div>\n <span class=\"mj-card-badge\">History</span>\n </div>\n <div class=\"mj-card-body\">\n @if (LoadError) {\n <span class=\"mj-load-error\">{{ LoadError }}</span>\n } @else if (Messages.length === 0) {\n <span style=\"font-size: 12px; color: var(--mj-text-muted);\">No messages in this conversation yet.</span>\n } @else {\n @for (msg of RecentMessages; track msg.ID) {\n <div class=\"mj-metric-row\">\n <span class=\"mj-metric-label\" style=\"text-overflow: ellipsis; overflow: hidden; white-space: nowrap; max-width: 200px;\">\n <strong>{{ msg.Role }}:</strong> {{ msg.Message }}\n </span>\n <span class=\"mj-pill\" [class.mj-pill-blue]=\"IsUserTurn(msg)\" [class.mj-pill-green]=\"IsAgentTurn(msg)\">\n {{ msg.Role }}\n </span>\n </div>\n }\n }\n </div>\n </div>\n </div>\n `,\n styles: [`\n :host { display: block; width: 100%; margin-bottom: 20px; }\n .mj-convo-overview-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));\n gap: 16px;\n }\n .mj-overview-card {\n background: var(--mj-bg-surface-card, #141f36);\n border: 1px solid var(--mj-border-default, #223254);\n border-radius: 10px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n .mj-card-header {\n padding: 10px 14px;\n background: var(--mj-bg-surface, #111a2e);\n border-bottom: 1px solid var(--mj-border-default, #223254);\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n .mj-card-title {\n font-size: 12.5px;\n font-weight: 700;\n color: var(--mj-text-primary, #f8fafc);\n display: flex;\n align-items: center;\n gap: 8px;\n }\n .mj-card-badge {\n font-size: 11px;\n padding: 2px 7px;\n border-radius: 9999px;\n background: var(--mj-bg-surface-elevated, #1a2744);\n color: var(--mj-text-secondary, #94a3b8);\n border: 1px solid var(--mj-border-default, #223254);\n }\n .mj-card-body {\n padding: 14px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n }\n .mj-metric-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n font-size: 12px;\n }\n .mj-metric-label { color: var(--mj-text-secondary, #94a3b8); }\n .mj-fork-note { font-size: 11px; color: var(--mj-text-muted); margin-top: -6px; }\n .mj-metric-val { font-weight: 600; color: var(--mj-text-primary, #f8fafc); font-family: monospace; }\n .mj-load-error { font-size: 12px; color: var(--mj-status-error); }\n .mj-pill { font-size: 10.5px; font-weight: 700; padding: 2px 6px; border-radius: 4px; }\n .mj-pill-green { background: rgba(16, 185, 129, 0.15); color: #10b981; }\n .mj-pill-blue { background: rgba(56, 189, 248, 0.15); color: #38bdf8; }\n `]\n})\nexport class ConversationOverviewPanel extends BaseFormPanel<MJConversationEntity> implements OnInit {\n private cdr = inject(ChangeDetectorRef);\n /** The newest messages in Main, newest first. */\n public Messages: ConversationDetailRow[] = [];\n /** Messages in Main. */\n public TotalMessageCount = 0;\n /** User messages in Main. */\n public UserMessageCount = 0;\n /** AI messages in Main. */\n public AgentMessageCount = 0;\n /** Forks of the conversation. */\n public ForkCount = 0;\n /** Set when a read fails, so the cards show the failure instead of zero messages. */\n public LoadError: string | null = null;\n\n public ngOnInit(): void {\n this.loadConversationMessages();\n }\n\n /** A turn the user sent. `Role` is stored as 'User', 'AI' or 'Error'. */\n protected IsUserTurn(detail: ConversationDetailRow): boolean {\n return detail.Role === 'User';\n }\n\n /** A turn an agent sent. An 'Error' turn is neither a user turn nor an agent turn. */\n protected IsAgentTurn(detail: ConversationDetailRow): boolean {\n return detail.Role === 'AI';\n }\n\n public get RecentMessages(): ConversationDetailRow[] {\n return this.Messages.slice(0, RECENT_MESSAGE_COUNT);\n }\n\n /** The host form's provider, or the default provider when the panel has no host form. */\n private get providerToUse(): IMetadataProvider {\n return this.FormComponent?.ProviderToUse ?? Metadata.Provider; // global-provider-ok: BaseFormPanel has no Provider input; a panel without a host form uses the default provider\n }\n\n /**\n * Loads the counts and newest messages in Main, and the conversation's fork count, in one\n * batch. When a detail read fails, the cards show the failure.\n */\n private async loadConversationMessages(): Promise<void> {\n if (!this.Record?.ID) return;\n const provider = this.providerToUse;\n const scope = ConversationEngine.TrunkScope(this.Record.ID);\n try {\n const rv = RunView.FromMetadataProvider(provider);\n const [total, user, agent, recent, forks] = await rv.RunViews<ConversationDetailRow>([\n {\n EntityName: 'MJ: Conversation Details',\n ExtraFilter: ConversationEngine.ScopeFilter(scope),\n ResultType: 'count_only',\n },\n {\n EntityName: 'MJ: Conversation Details',\n ExtraFilter: `${ConversationEngine.ScopeFilter(scope)} AND [Role]='User'`,\n ResultType: 'count_only',\n },\n {\n EntityName: 'MJ: Conversation Details',\n ExtraFilter: `${ConversationEngine.ScopeFilter(scope)} AND [Role]='AI'`,\n ResultType: 'count_only',\n },\n {\n EntityName: 'MJ: Conversation Details',\n ExtraFilter: ConversationEngine.ScopeFilter(scope),\n Fields: ['ID', 'Role', 'Message', '__mj_CreatedAt'],\n OrderBy: 'Sequence DESC',\n MaxRows: RECENT_MESSAGE_COUNT,\n ResultType: 'simple',\n },\n {\n EntityName: 'MJ: Conversation Branches',\n ExtraFilter: `ConversationID='${EscapeSQLString(this.Record.ID)}'`,\n ResultType: 'count_only',\n },\n ], provider.CurrentUser);\n const detailReads = [total, user, agent, recent];\n const failed = detailReads.findIndex(r => !r?.Success);\n if (failed >= 0) {\n this.showLoadError(detailReads[failed]?.ErrorMessage);\n } else {\n this.TotalMessageCount = total?.TotalRowCount ?? 0;\n this.UserMessageCount = user?.TotalRowCount ?? 0;\n this.AgentMessageCount = agent?.TotalRowCount ?? 0;\n this.Messages = recent?.Results ?? [];\n }\n this.ForkCount = forks?.Success ? forks.TotalRowCount ?? 0 : 0;\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n LogError(`Conversation overview: could not load the details of conversation ${this.Record.ID}: ${message}`);\n this.showLoadError(message);\n }\n this.cdr.markForCheck();\n }\n\n /** Shows a short \"could not load\" line, with the underlying message when there is one. */\n private showLoadError(detail: string | undefined): void {\n this.LoadError = detail ? `Could not load messages: ${detail}` : 'Could not load messages.';\n }\n}\n"]}