@memberjunction/ng-core-entity-forms 6.2.0-edge.2 → 6.2.0-edge.3
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.
- package/dist/lib/custom/AIAgentCategories/ai-agent-category-header.panel.d.ts.map +1 -1
- package/dist/lib/custom/AIAgentCategories/ai-agent-category-header.panel.js +9 -5
- package/dist/lib/custom/AIAgentCategories/ai-agent-category-header.panel.js.map +1 -1
- package/dist/lib/custom/AIAgentCategories/ai-agent-category-overview.panel.d.ts +4 -0
- package/dist/lib/custom/AIAgentCategories/ai-agent-category-overview.panel.d.ts.map +1 -1
- package/dist/lib/custom/AIAgentCategories/ai-agent-category-overview.panel.js +67 -36
- package/dist/lib/custom/AIAgentCategories/ai-agent-category-overview.panel.js.map +1 -1
- package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/ai-agent-form.component.js +1 -0
- package/dist/lib/custom/AIAgents/ai-agent-form.component.js.map +1 -1
- package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.d.ts.map +1 -1
- package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js +1 -0
- package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js.map +1 -1
- package/dist/lib/custom/Companies/company-header.panel.d.ts.map +1 -1
- package/dist/lib/custom/Companies/company-header.panel.js +9 -5
- package/dist/lib/custom/Companies/company-header.panel.js.map +1 -1
- package/dist/lib/custom/Companies/company-overview.panel.d.ts +4 -0
- package/dist/lib/custom/Companies/company-overview.panel.d.ts.map +1 -1
- package/dist/lib/custom/Companies/company-overview.panel.js +68 -37
- package/dist/lib/custom/Companies/company-overview.panel.js.map +1 -1
- package/dist/lib/custom/Conversations/conversation-header.panel.d.ts.map +1 -1
- package/dist/lib/custom/Conversations/conversation-header.panel.js +9 -5
- package/dist/lib/custom/Conversations/conversation-header.panel.js.map +1 -1
- package/dist/lib/custom/Conversations/conversation-overview.panel.d.ts +10 -2
- package/dist/lib/custom/Conversations/conversation-overview.panel.d.ts.map +1 -1
- package/dist/lib/custom/Conversations/conversation-overview.panel.js +138 -76
- package/dist/lib/custom/Conversations/conversation-overview.panel.js.map +1 -1
- package/dist/lib/custom/Employees/employee-header.panel.d.ts.map +1 -1
- package/dist/lib/custom/Employees/employee-header.panel.js +9 -5
- package/dist/lib/custom/Employees/employee-header.panel.js.map +1 -1
- package/dist/lib/custom/Employees/employee-overview.panel.d.ts +4 -0
- package/dist/lib/custom/Employees/employee-overview.panel.d.ts.map +1 -1
- package/dist/lib/custom/Employees/employee-overview.panel.js +68 -37
- package/dist/lib/custom/Employees/employee-overview.panel.js.map +1 -1
- package/dist/lib/custom/Entities/entity-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Entities/entity-form.component.js +1 -0
- package/dist/lib/custom/Entities/entity-form.component.js.map +1 -1
- package/dist/lib/custom/HierarchyPanels/hierarchy-form-panels.d.ts.map +1 -1
- package/dist/lib/custom/HierarchyPanels/hierarchy-form-panels.js +60 -45
- package/dist/lib/custom/HierarchyPanels/hierarchy-form-panels.js.map +1 -1
- package/dist/lib/custom/Lists/list-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Lists/list-form.component.js +1 -0
- package/dist/lib/custom/Lists/list-form.component.js.map +1 -1
- package/dist/lib/custom/Queries/query-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Queries/query-form.component.js +1 -0
- package/dist/lib/custom/Queries/query-form.component.js.map +1 -1
- package/dist/lib/custom/Rubrics/rubric-form.component.js +1 -1
- package/dist/lib/custom/Rubrics/rubric-form.component.js.map +1 -1
- package/dist/lib/custom/SearchScopes/searchscope-form.component.d.ts.map +1 -1
- package/dist/lib/custom/SearchScopes/searchscope-form.component.js +1 -0
- package/dist/lib/custom/SearchScopes/searchscope-form.component.js.map +1 -1
- package/dist/lib/custom/Templates/templates-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Templates/templates-form.component.js +1 -0
- package/dist/lib/custom/Templates/templates-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Tests/test-form.component.js +1 -0
- package/dist/lib/custom/Tests/test-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-run-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Tests/test-run-form.component.js +1 -0
- package/dist/lib/custom/Tests/test-run-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-suite-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Tests/test-suite-form.component.js +1 -0
- package/dist/lib/custom/Tests/test-suite-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-suite-run-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Tests/test-suite-run-form.component.js +1 -0
- package/dist/lib/custom/Tests/test-suite-run-form.component.js.map +1 -1
- package/dist/lib/custom/Users/user-header.panel.d.ts.map +1 -1
- package/dist/lib/custom/Users/user-header.panel.js +9 -5
- package/dist/lib/custom/Users/user-header.panel.js.map +1 -1
- package/dist/lib/custom/Users/user-overview.panel.d.ts +4 -0
- package/dist/lib/custom/Users/user-overview.panel.d.ts.map +1 -1
- package/dist/lib/custom/Users/user-overview.panel.js +64 -33
- package/dist/lib/custom/Users/user-overview.panel.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js +1 -0
- package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js +98 -44
- package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentArtifactType/mjaiagentartifacttype.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentArtifactType/mjaiagentartifacttype.form.component.js +5 -9
- package/dist/lib/generated/Entities/MJAIAgentArtifactType/mjaiagentartifacttype.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentNoteType/mjaiagentnotetype.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentNoteType/mjaiagentnotetype.form.component.js +15 -18
- package/dist/lib/generated/Entities/MJAIAgentNoteType/mjaiagentnotetype.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentPrompt/mjaiagentprompt.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentPrompt/mjaiagentprompt.form.component.js +5 -9
- package/dist/lib/generated/Entities/MJAIAgentPrompt/mjaiagentprompt.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentSession/mjaiagentsession.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentSession/mjaiagentsession.form.component.js +27 -9
- package/dist/lib/generated/Entities/MJAIAgentSession/mjaiagentsession.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentSessionBridge/mjaiagentsessionbridge.form.component.js +17 -15
- package/dist/lib/generated/Entities/MJAIAgentSessionBridge/mjaiagentsessionbridge.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIBridgeProvider/mjaibridgeprovider.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAIBridgeProvider/mjaibridgeprovider.form.component.js +25 -7
- package/dist/lib/generated/Entities/MJAIBridgeProvider/mjaibridgeprovider.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIResultCache/mjairesultcache.form.component.js +12 -14
- package/dist/lib/generated/Entities/MJAIResultCache/mjairesultcache.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJCommunicationLog/mjcommunicationlog.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJCommunicationLog/mjcommunicationlog.form.component.js +5 -9
- package/dist/lib/generated/Entities/MJCommunicationLog/mjcommunicationlog.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJCompanyIntegrationRunAPILog/mjcompanyintegrationrunapilog.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJCompanyIntegrationRunAPILog/mjcompanyintegrationrunapilog.form.component.js +5 -9
- package/dist/lib/generated/Entities/MJCompanyIntegrationRunAPILog/mjcompanyintegrationrunapilog.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJComponent/mjcomponent.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJComponent/mjcomponent.form.component.js +26 -8
- package/dist/lib/generated/Entities/MJComponent/mjcomponent.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJContentItemAttribute/mjcontentitemattribute.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJContentItemAttribute/mjcontentitemattribute.form.component.js +4 -7
- package/dist/lib/generated/Entities/MJContentItemAttribute/mjcontentitemattribute.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJContentSourceParam/mjcontentsourceparam.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJContentSourceParam/mjcontentsourceparam.form.component.js +4 -7
- package/dist/lib/generated/Entities/MJContentSourceParam/mjcontentsourceparam.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.js +31 -13
- package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJConversationArtifactPermission/mjconversationartifactpermission.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJConversationArtifactPermission/mjconversationartifactpermission.form.component.js +5 -9
- package/dist/lib/generated/Entities/MJConversationArtifactPermission/mjconversationartifactpermission.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJCredential/mjcredential.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJCredential/mjcredential.form.component.js +34 -16
- package/dist/lib/generated/Entities/MJCredential/mjcredential.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJEmployeeRole/mjemployeerole.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJEmployeeRole/mjemployeerole.form.component.js +5 -9
- package/dist/lib/generated/Entities/MJEmployeeRole/mjemployeerole.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js +151 -97
- package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJEntityCommunicationField/mjentitycommunicationfield.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJEntityCommunicationField/mjentitycommunicationfield.form.component.js +8 -11
- package/dist/lib/generated/Entities/MJEntityCommunicationField/mjentitycommunicationfield.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJEntityDocumentType/mjentitydocumenttype.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJEntityDocumentType/mjentitydocumenttype.form.component.js +15 -18
- package/dist/lib/generated/Entities/MJEntityDocumentType/mjentitydocumenttype.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJEntityFormContribution/mjentityformcontribution.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJEntityFormContribution/mjentityformcontribution.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJEntityFormContribution/mjentityformcontribution.form.component.js +148 -0
- package/dist/lib/generated/Entities/MJEntityFormContribution/mjentityformcontribution.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJEnvironment/mjenvironment.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJEnvironment/mjenvironment.form.component.js +53 -56
- package/dist/lib/generated/Entities/MJEnvironment/mjenvironment.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJInteraction/mjinteraction.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJInteraction/mjinteraction.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJInteraction/mjinteraction.form.component.js +161 -0
- package/dist/lib/generated/Entities/MJInteraction/mjinteraction.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJInteractionEvent/mjinteractionevent.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJInteractionEvent/mjinteractionevent.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJInteractionEvent/mjinteractionevent.form.component.js +78 -0
- package/dist/lib/generated/Entities/MJInteractionEvent/mjinteractionevent.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJInteractionLink/mjinteractionlink.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJInteractionLink/mjinteractionlink.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJInteractionLink/mjinteractionlink.form.component.js +68 -0
- package/dist/lib/generated/Entities/MJInteractionLink/mjinteractionlink.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJInteractionOffer/mjinteractionoffer.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJInteractionOffer/mjinteractionoffer.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJInteractionOffer/mjinteractionoffer.form.component.js +100 -0
- package/dist/lib/generated/Entities/MJInteractionOffer/mjinteractionoffer.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJMeeting/mjmeeting.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJMeeting/mjmeeting.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJMeeting/mjmeeting.form.component.js +119 -0
- package/dist/lib/generated/Entities/MJMeeting/mjmeeting.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJMeetingParticipant/mjmeetingparticipant.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJMeetingParticipant/mjmeetingparticipant.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJMeetingParticipant/mjmeetingparticipant.form.component.js +92 -0
- package/dist/lib/generated/Entities/MJMeetingParticipant/mjmeetingparticipant.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJNumberPool/mjnumberpool.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJNumberPool/mjnumberpool.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJNumberPool/mjnumberpool.form.component.js +87 -0
- package/dist/lib/generated/Entities/MJNumberPool/mjnumberpool.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJPhoneNumber/mjphonenumber.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJPhoneNumber/mjphonenumber.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJPhoneNumber/mjphonenumber.form.component.js +129 -0
- package/dist/lib/generated/Entities/MJPhoneNumber/mjphonenumber.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJQueryPermission/mjquerypermission.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJQueryPermission/mjquerypermission.form.component.js +5 -9
- package/dist/lib/generated/Entities/MJQueryPermission/mjquerypermission.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJRecommendationItem/mjrecommendationitem.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJRecommendationItem/mjrecommendationitem.form.component.js +8 -11
- package/dist/lib/generated/Entities/MJRecommendationItem/mjrecommendationitem.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJResourceType/mjresourcetype.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJResourceType/mjresourcetype.form.component.js +36 -40
- package/dist/lib/generated/Entities/MJResourceType/mjresourcetype.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJRole/mjrole.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJRole/mjrole.form.component.js +39 -21
- package/dist/lib/generated/Entities/MJRole/mjrole.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJRowLevelSecurityFilter/mjrowlevelsecurityfilter.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJRowLevelSecurityFilter/mjrowlevelsecurityfilter.form.component.js +45 -48
- package/dist/lib/generated/Entities/MJRowLevelSecurityFilter/mjrowlevelsecurityfilter.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJTemplateContentType/mjtemplatecontenttype.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJTemplateContentType/mjtemplatecontenttype.form.component.js +15 -18
- package/dist/lib/generated/Entities/MJTemplateContentType/mjtemplatecontenttype.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJUser/mjuser.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js +254 -128
- package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJVersionLabelItem/mjversionlabelitem.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJVersionLabelItem/mjversionlabelitem.form.component.js +5 -9
- package/dist/lib/generated/Entities/MJVersionLabelItem/mjversionlabelitem.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJWorkQueueDeduplication/mjworkqueuededuplication.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJWorkQueueDeduplication/mjworkqueuededuplication.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJWorkQueueDeduplication/mjworkqueuededuplication.form.component.js +64 -0
- package/dist/lib/generated/Entities/MJWorkQueueDeduplication/mjworkqueuededuplication.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJWorkQueueDelivery/mjworkqueuedelivery.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJWorkQueueDelivery/mjworkqueuedelivery.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJWorkQueueDelivery/mjworkqueuedelivery.form.component.js +94 -0
- package/dist/lib/generated/Entities/MJWorkQueueDelivery/mjworkqueuedelivery.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJWorkQueueMessage/mjworkqueuemessage.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJWorkQueueMessage/mjworkqueuemessage.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJWorkQueueMessage/mjworkqueuemessage.form.component.js +91 -0
- package/dist/lib/generated/Entities/MJWorkQueueMessage/mjworkqueuemessage.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJWorkQueueSubscription/mjworkqueuesubscription.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJWorkQueueSubscription/mjworkqueuesubscription.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJWorkQueueSubscription/mjworkqueuesubscription.form.component.js +105 -0
- package/dist/lib/generated/Entities/MJWorkQueueSubscription/mjworkqueuesubscription.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJWorkQueueTopic/mjworkqueuetopic.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJWorkQueueTopic/mjworkqueuetopic.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJWorkQueueTopic/mjworkqueuetopic.form.component.js +129 -0
- package/dist/lib/generated/Entities/MJWorkQueueTopic/mjworkqueuetopic.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJWorkQueueTransport/mjworkqueuetransport.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJWorkQueueTransport/mjworkqueuetransport.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJWorkQueueTransport/mjworkqueuetransport.form.component.js +85 -0
- package/dist/lib/generated/Entities/MJWorkQueueTransport/mjworkqueuetransport.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJWorkspace/mjworkspace.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJWorkspace/mjworkspace.form.component.js +17 -20
- package/dist/lib/generated/Entities/MJWorkspace/mjworkspace.form.component.js.map +1 -1
- package/dist/lib/generated/generated-forms.module.d.ts +446 -431
- package/dist/lib/generated/generated-forms.module.d.ts.map +1 -1
- package/dist/lib/generated/generated-forms.module.js +57 -12
- package/dist/lib/generated/generated-forms.module.js.map +1 -1
- package/dist/lib/panels/ai-agents/agent-realtime.panel.d.ts +7 -1
- package/dist/lib/panels/ai-agents/agent-realtime.panel.d.ts.map +1 -1
- package/dist/lib/panels/ai-agents/agent-realtime.panel.js +89 -43
- package/dist/lib/panels/ai-agents/agent-realtime.panel.js.map +1 -1
- package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.js +3 -3
- package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.js.map +1 -1
- package/dist/lib/panels/content-sources/tag-pipeline-configuration.panel.js +5 -5
- package/dist/lib/panels/content-sources/tag-pipeline-configuration.panel.js.map +1 -1
- package/dist/lib/panels/content-sources/website-crawler-settings.panel.js +4 -4
- package/dist/lib/panels/content-sources/website-crawler-settings.panel.js.map +1 -1
- package/dist/lib/panels/form-chrome/entity-relationship-form-role.panel.js +3 -3
- package/dist/lib/panels/form-chrome/entity-relationship-form-role.panel.js.map +1 -1
- package/dist/lib/panels/model-predictions/model-prediction.panel.js +4 -4
- package/dist/lib/panels/model-predictions/model-prediction.panel.js.map +1 -1
- package/package.json +47 -47
|
@@ -203,7 +203,7 @@ let TagPipelineConfigurationPanel = class TagPipelineConfigurationPanel extends
|
|
|
203
203
|
return Number.isFinite(v) ? v : undefined;
|
|
204
204
|
}
|
|
205
205
|
static { this.ɵfac = /*@__PURE__*/ (() => { let ɵTagPipelineConfigurationPanel_BaseFactory; return function TagPipelineConfigurationPanel_Factory(__ngFactoryType__) { return (ɵTagPipelineConfigurationPanel_BaseFactory || (ɵTagPipelineConfigurationPanel_BaseFactory = i0.ɵɵgetInheritedFactory(TagPipelineConfigurationPanel)))(__ngFactoryType__ || TagPipelineConfigurationPanel); }; })(); }
|
|
206
|
-
static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TagPipelineConfigurationPanel, selectors: [["mj-tag-pipeline-configuration-panel"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 101, vars:
|
|
206
|
+
static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TagPipelineConfigurationPanel, selectors: [["mj-tag-pipeline-configuration-panel"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 101, vars: 33, consts: [["SectionKey", "tagPipelineConfiguration", "SectionName", "Tag Pipeline Configuration", "Icon", "fa fa-sliders-h", 3, "Order", "Form", "FormContext"], [1, "cs-section-header"], [1, "cs-mode-grid"], [1, "cs-mode-card", 3, "selected"], [1, "cs-grid"], [1, "cs-field"], [1, "cs-input", 3, "ngModelChange", "disabled", "ngModel"], [1, "hint"], ["disabled", "", 1, "cs-input", 3, "value"], [1, "cs-toggle-row"], [1, "label"], [1, "t"], [1, "d"], [1, "cs-switch", 3, "click"], [1, "cs-threshold-pair"], ["type", "range", "min", "0.50", "max", "1.00", "step", "0.01", 1, "cs-slider", 3, "ngModelChange", "disabled", "ngModel"], [1, "cs-slider-row"], [1, "cur"], [1, "cs-validation"], [1, "cs-nudge"], [1, "cs-section-header-note"], [1, "cs-primary-budget"], [1, "cs-field", "cs-field-primary"], ["type", "number", "min", "0", "placeholder", "unlimited", 1, "cs-input", 3, "ngModelChange", "disabled", "ngModel"], [1, "cs-grid", "four"], ["type", "number", "min", "0", "step", "0.01", "placeholder", "unlimited", 1, "cs-input", 3, "ngModelChange", "disabled", "ngModel"], [1, "cs-mode-card", 3, "click"], [1, "nm"], [1, "desc"], [1, "fa-solid", "fa-circle-exclamation"]], template: function TagPipelineConfigurationPanel_Template(rf, ctx) { if (rf & 1) {
|
|
207
207
|
i0.ɵɵelementStart(0, "mj-collapsible-panel", 0)(1, "h4", 1);
|
|
208
208
|
i0.ɵɵtext(2, "Taxonomy mode");
|
|
209
209
|
i0.ɵɵelementEnd();
|
|
@@ -335,7 +335,7 @@ let TagPipelineConfigurationPanel = class TagPipelineConfigurationPanel extends
|
|
|
335
335
|
i0.ɵɵtext(100, "$ stops the run");
|
|
336
336
|
i0.ɵɵelementEnd()()()();
|
|
337
337
|
} if (rf & 2) {
|
|
338
|
-
i0.ɵɵproperty("Form", ctx.FormComponent)("FormContext", ctx.FormContext);
|
|
338
|
+
i0.ɵɵproperty("Order", ctx.DisplayOrder)("Form", ctx.FormComponent)("FormContext", ctx.FormContext);
|
|
339
339
|
i0.ɵɵadvance(4);
|
|
340
340
|
i0.ɵɵrepeater(ctx.TaxonomyModes);
|
|
341
341
|
i0.ɵɵadvance(8);
|
|
@@ -349,11 +349,11 @@ let TagPipelineConfigurationPanel = class TagPipelineConfigurationPanel extends
|
|
|
349
349
|
i0.ɵɵadvance(8);
|
|
350
350
|
i0.ɵɵproperty("disabled", !ctx.EditMode)("ngModel", ctx.MatchThresholdValue);
|
|
351
351
|
i0.ɵɵadvance(5);
|
|
352
|
-
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(48,
|
|
352
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(48, 27, ctx.MatchThresholdValue, "1.2-2"));
|
|
353
353
|
i0.ɵɵadvance(7);
|
|
354
354
|
i0.ɵɵproperty("disabled", !ctx.EditMode)("ngModel", ctx.SuggestThresholdValue);
|
|
355
355
|
i0.ɵɵadvance(5);
|
|
356
|
-
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(60,
|
|
356
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(60, 30, ctx.SuggestThresholdValue, "1.2-2"));
|
|
357
357
|
i0.ɵɵadvance(4);
|
|
358
358
|
i0.ɵɵconditional(ctx.ThresholdValidationMessage ? 63 : 64);
|
|
359
359
|
i0.ɵɵadvance(10);
|
|
@@ -382,7 +382,7 @@ TagPipelineConfigurationPanel = __decorate([
|
|
|
382
382
|
export { TagPipelineConfigurationPanel };
|
|
383
383
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TagPipelineConfigurationPanel, [{
|
|
384
384
|
type: Component,
|
|
385
|
-
args: [{ standalone: false, selector: 'mj-tag-pipeline-configuration-panel', template: "<mj-collapsible-panel\n SectionKey=\"tagPipelineConfiguration\"\n SectionName=\"Tag Pipeline Configuration\"\n Icon=\"fa fa-sliders-h\"\n [Form]=\"FormComponent\"\n [FormContext]=\"FormContext\">\n\n <!-- 1. Taxonomy mode -->\n <h4 class=\"cs-section-header\">Taxonomy mode</h4>\n <div class=\"cs-mode-grid\">\n @for (m of TaxonomyModes; track m.value) {\n <div class=\"cs-mode-card\"\n [class.selected]=\"CurrentMode === m.value\"\n (click)=\"EditMode ? SetMode(m.value) : null\">\n <i class=\"fa-solid {{ m.icon }} ic\"></i>\n <div class=\"nm\">{{ m.label }}</div>\n <div class=\"desc\">{{ m.desc }}</div>\n </div>\n }\n </div>\n\n <!-- 2. Scope & root -->\n <h4 class=\"cs-section-header\">Scope & tag root</h4>\n <div class=\"cs-grid\">\n <div class=\"cs-field\">\n <label>Tag root (TagRootID)</label>\n <input class=\"cs-input\" [disabled]=\"!EditMode\"\n [ngModel]=\"TagRootIDValue\"\n (ngModelChange)=\"TagRootIDValue = $event\" />\n <span class=\"hint\">Restricts the LLM's visible taxonomy + auto-grow target. Leave blank for full taxonomy.</span>\n </div>\n <div class=\"cs-field\">\n <label>Embedding model (legacy ContentSource field)</label>\n <input class=\"cs-input\" disabled [value]=\"Record?.EmbeddingModelID || '\u2014'\" />\n <span class=\"hint\">Set in the AI & Indexing section above.</span>\n </div>\n </div>\n\n <div class=\"cs-toggle-row\">\n <div class=\"label\">\n <span class=\"t\">Share full taxonomy with the LLM</span>\n <span class=\"d\">When on, the LLM prompt includes the visible (scope-filtered) taxonomy. Larger taxonomies \u2192 higher token cost.</span>\n </div>\n <div class=\"cs-switch\" [class.on]=\"ShareTaxonomyValue\"\n (click)=\"EditMode ? (ShareTaxonomyValue = !ShareTaxonomyValue) : null\"></div>\n </div>\n <div class=\"cs-toggle-row\">\n <div class=\"label\">\n <span class=\"t\">Vectorize new content</span>\n <span class=\"d\">When off, this source skips vectorization (autotagger still runs).</span>\n </div>\n <div class=\"cs-switch\" [class.on]=\"EnableVectorizationValue\"\n (click)=\"EditMode ? (EnableVectorizationValue = !EnableVectorizationValue) : null\"></div>\n </div>\n\n <!-- 3. Thresholds -->\n <h4 class=\"cs-section-header\">Thresholds</h4>\n <div class=\"cs-threshold-pair\">\n <div class=\"cs-grid\">\n <div class=\"cs-field\">\n <label>MatchThreshold (auto-apply)</label>\n <input type=\"range\" class=\"cs-slider\" min=\"0.50\" max=\"1.00\" step=\"0.01\"\n [disabled]=\"!EditMode\"\n [ngModel]=\"MatchThresholdValue\"\n (ngModelChange)=\"MatchThresholdValue = $event\" />\n <div class=\"cs-slider-row\"><span>0.50</span><span class=\"cur\">{{ MatchThresholdValue | number: '1.2-2' }}</span><span>1.00</span></div>\n </div>\n <div class=\"cs-field\">\n <label>SuggestThreshold (route to inbox)</label>\n <input type=\"range\" class=\"cs-slider\" min=\"0.50\" max=\"1.00\" step=\"0.01\"\n [disabled]=\"!EditMode\"\n [ngModel]=\"SuggestThresholdValue\"\n (ngModelChange)=\"SuggestThresholdValue = $event\" />\n <div class=\"cs-slider-row\"><span>0.50</span><span class=\"cur\">{{ SuggestThresholdValue | number: '1.2-2' }}</span><span>1.00</span></div>\n </div>\n </div>\n @if (ThresholdValidationMessage) {\n <div class=\"cs-validation\"><i class=\"fa-solid fa-circle-exclamation\"></i> {{ ThresholdValidationMessage }}</div>\n } @else {\n <div class=\"cs-nudge\">\n Scores \u2265 <strong>{{ MatchThresholdValue | number: '1.2-2' }}</strong> auto-apply.\n Scores in <strong>[{{ SuggestThresholdValue | number: '1.2-2' }}, {{ MatchThresholdValue | number: '1.2-2' }})</strong> route to the suggestion inbox.\n Below that, the run falls through to handleNoMatch.\n </div>\n }\n </div>\n\n <!-- 4. Volume + cost budgets -->\n <h4 class=\"cs-section-header\">\n Volume & cost budgets\n <span class=\"cs-section-header-note\">When a budget is hit the run pauses (resumes on next start).</span>\n </h4>\n\n <div class=\"cs-primary-budget\">\n <div class=\"cs-field cs-field-primary\">\n <label>Max items / run</label>\n <input class=\"cs-input\" type=\"number\" min=\"0\" [disabled]=\"!EditMode\"\n [ngModel]=\"MaxItemsPerRunValue ?? ''\"\n (ngModelChange)=\"MaxItemsPerRunValue = $event\"\n placeholder=\"unlimited\" />\n <span class=\"hint\">Caps the number of content items handed to the LLM. Skipped (unchanged) items don't count. Paused work resumes on the next run \u2014 the change-detection short-circuit skips already-tagged pages, so re-crawl only wastes HTTP, not LLM cycles.</span>\n </div>\n </div>\n\n <div class=\"cs-grid four\">\n <div class=\"cs-field\">\n <label>Max new tags / run</label>\n <input class=\"cs-input\" type=\"number\" min=\"0\" [disabled]=\"!EditMode\"\n [ngModel]=\"MaxNewTagsPerRunValue ?? ''\"\n (ngModelChange)=\"MaxNewTagsPerRunValue = $event\"\n placeholder=\"unlimited\" />\n <span class=\"hint\">across all items</span>\n </div>\n <div class=\"cs-field\">\n <label>Max new tags / item</label>\n <input class=\"cs-input\" type=\"number\" min=\"0\" [disabled]=\"!EditMode\"\n [ngModel]=\"MaxNewTagsPerItemValue ?? ''\"\n (ngModelChange)=\"MaxNewTagsPerItemValue = $event\"\n placeholder=\"unlimited\" />\n <span class=\"hint\">extras \u2192 suggestions</span>\n </div>\n <div class=\"cs-field\">\n <label>Max tokens / run</label>\n <input class=\"cs-input\" type=\"number\" min=\"0\" [disabled]=\"!EditMode\"\n [ngModel]=\"MaxTokensPerRunValue ?? ''\"\n (ngModelChange)=\"MaxTokensPerRunValue = $event\"\n placeholder=\"unlimited\" />\n <span class=\"hint\">across all LLM calls</span>\n </div>\n <div class=\"cs-field\">\n <label>Max cost / run (USD)</label>\n <input class=\"cs-input\" type=\"number\" min=\"0\" step=\"0.01\" [disabled]=\"!EditMode\"\n [ngModel]=\"MaxCostPerRunValue ?? ''\"\n (ngModelChange)=\"MaxCostPerRunValue = $event\"\n placeholder=\"unlimited\" />\n <span class=\"hint\">$ stops the run</span>\n </div>\n </div>\n</mj-collapsible-panel>\n", styles: ["/* Tag Pipeline Configuration panel \u2014 dense form for the typed\n IContentSourceConfiguration knobs. The class names are shared with the\n Website Crawler Settings panel (same `cs-*` prefix family) so future\n ContentSource panels stay visually consistent without duplicating styles. */\n\n.cs-section-header {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--mj-text-muted);\n margin: 4px 0 8px;\n font-weight: 700;\n}\n.cs-section-header:not(:first-child) {\n margin-top: 16px;\n}\n.cs-section-header-note {\n text-transform: none;\n letter-spacing: 0;\n color: var(--mj-text-muted);\n font-weight: 400;\n margin-left: 8px;\n}\n\n.cs-mode-grid {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 8px;\n margin: 4px 0 12px;\n}\n.cs-mode-card {\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n border-radius: 8px;\n padding: 10px 12px;\n cursor: pointer;\n text-align: center;\n transition: background 0.12s, border-color 0.12s, box-shadow 0.12s;\n user-select: none;\n}\n.cs-mode-card:hover { background: var(--mj-bg-surface-hover); }\n.cs-mode-card.selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n border-color: var(--mj-brand-primary);\n box-shadow: inset 0 0 0 1px var(--mj-brand-primary);\n}\n.cs-mode-card .ic { font-size: 18px; color: var(--mj-text-secondary); }\n.cs-mode-card.selected .ic { color: var(--mj-brand-primary); }\n.cs-mode-card .nm { font-size: 13px; font-weight: 700; color: var(--mj-text-primary); margin: 4px 0 2px; }\n.cs-mode-card .desc { font-size: 11px; color: var(--mj-text-muted); line-height: 1.3; }\n\n.cs-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 14px 16px;\n margin: 4px 0 12px;\n}\n.cs-grid.four { grid-template-columns: repeat(4, 1fr); }\n.cs-grid.three { grid-template-columns: repeat(3, 1fr); }\n\n/* Primary budget row \u2014 MaxItemsPerRun gets its own emphasized row above\n the dense 4-col grid because it's the most user-intuitive cap. */\n.cs-primary-budget {\n margin: 4px 0 10px;\n padding: 10px 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 4%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 20%, var(--mj-border-default));\n border-radius: 6px;\n}\n.cs-field-primary label { font-size: 13px; color: var(--mj-text-primary); }\n.cs-field-primary .hint { line-height: 1.45; max-width: 78ch; }\n\n.cs-field { display: flex; flex-direction: column; gap: 4px; }\n.cs-field label { font-size: 12px; font-weight: 600; color: var(--mj-text-secondary); }\n.cs-field .hint { font-size: 11px; color: var(--mj-text-muted); }\n\n.cs-input {\n width: 100%;\n box-sizing: border-box;\n padding: 7px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n}\n.cs-input:focus {\n outline: none;\n border-color: var(--mj-border-focus, var(--mj-brand-primary));\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n.cs-input:disabled { opacity: 0.55; cursor: not-allowed; }\n\n.cs-threshold-pair {\n background: var(--mj-bg-surface-card);\n padding: 14px 16px;\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n}\n.cs-slider {\n appearance: none;\n -webkit-appearance: none;\n width: 100%;\n height: 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n margin: 8px 0 4px;\n}\n.cs-slider::-webkit-slider-thumb {\n appearance: none;\n -webkit-appearance: none;\n width: 16px; height: 16px; border-radius: 50%;\n background: var(--mj-brand-primary);\n cursor: pointer;\n border: 2px solid var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0,0,0,0.2);\n}\n.cs-slider::-moz-range-thumb {\n width: 16px; height: 16px; border-radius: 50%;\n background: var(--mj-brand-primary);\n cursor: pointer;\n border: 2px solid var(--mj-bg-surface);\n}\n.cs-slider-row {\n display: flex;\n justify-content: space-between;\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n.cs-slider-row .cur {\n font-family: ui-monospace, monospace;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.cs-validation {\n font-size: 12px;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-status-error) 12%, transparent);\n color: var(--mj-status-error-text, var(--mj-status-error));\n border-radius: 4px;\n margin-top: 8px;\n}\n.cs-nudge {\n font-size: 12px;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, transparent);\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n border-radius: 4px;\n margin-top: 8px;\n line-height: 1.4;\n}\n\n.cs-toggle-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 0;\n border-top: 1px dashed var(--mj-border-subtle);\n}\n.cs-toggle-row:first-child { border-top: 0; padding-top: 0; }\n.cs-toggle-row .label .t { font-size: 13px; font-weight: 600; }\n.cs-toggle-row .label .d { font-size: 11px; color: var(--mj-text-muted); }\n.cs-switch {\n position: relative;\n width: 36px; height: 20px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 10px;\n cursor: pointer;\n}\n.cs-switch::after {\n content: \"\";\n position: absolute;\n top: 2px; left: 2px;\n width: 16px; height: 16px;\n border-radius: 50%;\n background: var(--mj-bg-surface);\n transition: left 0.15s;\n box-shadow: 0 1px 2px rgba(0,0,0,0.2);\n}\n.cs-switch.on { background: var(--mj-brand-primary); }\n.cs-switch.on::after { left: 18px; }\n"] }]
|
|
385
|
+
args: [{ standalone: false, selector: 'mj-tag-pipeline-configuration-panel', template: "<mj-collapsible-panel\n SectionKey=\"tagPipelineConfiguration\"\n [Order]=\"DisplayOrder\"\n SectionName=\"Tag Pipeline Configuration\"\n Icon=\"fa fa-sliders-h\"\n [Form]=\"FormComponent\"\n [FormContext]=\"FormContext\">\n\n <!-- 1. Taxonomy mode -->\n <h4 class=\"cs-section-header\">Taxonomy mode</h4>\n <div class=\"cs-mode-grid\">\n @for (m of TaxonomyModes; track m.value) {\n <div class=\"cs-mode-card\"\n [class.selected]=\"CurrentMode === m.value\"\n (click)=\"EditMode ? SetMode(m.value) : null\">\n <i class=\"fa-solid {{ m.icon }} ic\"></i>\n <div class=\"nm\">{{ m.label }}</div>\n <div class=\"desc\">{{ m.desc }}</div>\n </div>\n }\n </div>\n\n <!-- 2. Scope & root -->\n <h4 class=\"cs-section-header\">Scope & tag root</h4>\n <div class=\"cs-grid\">\n <div class=\"cs-field\">\n <label>Tag root (TagRootID)</label>\n <input class=\"cs-input\" [disabled]=\"!EditMode\"\n [ngModel]=\"TagRootIDValue\"\n (ngModelChange)=\"TagRootIDValue = $event\" />\n <span class=\"hint\">Restricts the LLM's visible taxonomy + auto-grow target. Leave blank for full taxonomy.</span>\n </div>\n <div class=\"cs-field\">\n <label>Embedding model (legacy ContentSource field)</label>\n <input class=\"cs-input\" disabled [value]=\"Record?.EmbeddingModelID || '\u2014'\" />\n <span class=\"hint\">Set in the AI & Indexing section above.</span>\n </div>\n </div>\n\n <div class=\"cs-toggle-row\">\n <div class=\"label\">\n <span class=\"t\">Share full taxonomy with the LLM</span>\n <span class=\"d\">When on, the LLM prompt includes the visible (scope-filtered) taxonomy. Larger taxonomies \u2192 higher token cost.</span>\n </div>\n <div class=\"cs-switch\" [class.on]=\"ShareTaxonomyValue\"\n (click)=\"EditMode ? (ShareTaxonomyValue = !ShareTaxonomyValue) : null\"></div>\n </div>\n <div class=\"cs-toggle-row\">\n <div class=\"label\">\n <span class=\"t\">Vectorize new content</span>\n <span class=\"d\">When off, this source skips vectorization (autotagger still runs).</span>\n </div>\n <div class=\"cs-switch\" [class.on]=\"EnableVectorizationValue\"\n (click)=\"EditMode ? (EnableVectorizationValue = !EnableVectorizationValue) : null\"></div>\n </div>\n\n <!-- 3. Thresholds -->\n <h4 class=\"cs-section-header\">Thresholds</h4>\n <div class=\"cs-threshold-pair\">\n <div class=\"cs-grid\">\n <div class=\"cs-field\">\n <label>MatchThreshold (auto-apply)</label>\n <input type=\"range\" class=\"cs-slider\" min=\"0.50\" max=\"1.00\" step=\"0.01\"\n [disabled]=\"!EditMode\"\n [ngModel]=\"MatchThresholdValue\"\n (ngModelChange)=\"MatchThresholdValue = $event\" />\n <div class=\"cs-slider-row\"><span>0.50</span><span class=\"cur\">{{ MatchThresholdValue | number: '1.2-2' }}</span><span>1.00</span></div>\n </div>\n <div class=\"cs-field\">\n <label>SuggestThreshold (route to inbox)</label>\n <input type=\"range\" class=\"cs-slider\" min=\"0.50\" max=\"1.00\" step=\"0.01\"\n [disabled]=\"!EditMode\"\n [ngModel]=\"SuggestThresholdValue\"\n (ngModelChange)=\"SuggestThresholdValue = $event\" />\n <div class=\"cs-slider-row\"><span>0.50</span><span class=\"cur\">{{ SuggestThresholdValue | number: '1.2-2' }}</span><span>1.00</span></div>\n </div>\n </div>\n @if (ThresholdValidationMessage) {\n <div class=\"cs-validation\"><i class=\"fa-solid fa-circle-exclamation\"></i> {{ ThresholdValidationMessage }}</div>\n } @else {\n <div class=\"cs-nudge\">\n Scores \u2265 <strong>{{ MatchThresholdValue | number: '1.2-2' }}</strong> auto-apply.\n Scores in <strong>[{{ SuggestThresholdValue | number: '1.2-2' }}, {{ MatchThresholdValue | number: '1.2-2' }})</strong> route to the suggestion inbox.\n Below that, the run falls through to handleNoMatch.\n </div>\n }\n </div>\n\n <!-- 4. Volume + cost budgets -->\n <h4 class=\"cs-section-header\">\n Volume & cost budgets\n <span class=\"cs-section-header-note\">When a budget is hit the run pauses (resumes on next start).</span>\n </h4>\n\n <div class=\"cs-primary-budget\">\n <div class=\"cs-field cs-field-primary\">\n <label>Max items / run</label>\n <input class=\"cs-input\" type=\"number\" min=\"0\" [disabled]=\"!EditMode\"\n [ngModel]=\"MaxItemsPerRunValue ?? ''\"\n (ngModelChange)=\"MaxItemsPerRunValue = $event\"\n placeholder=\"unlimited\" />\n <span class=\"hint\">Caps the number of content items handed to the LLM. Skipped (unchanged) items don't count. Paused work resumes on the next run \u2014 the change-detection short-circuit skips already-tagged pages, so re-crawl only wastes HTTP, not LLM cycles.</span>\n </div>\n </div>\n\n <div class=\"cs-grid four\">\n <div class=\"cs-field\">\n <label>Max new tags / run</label>\n <input class=\"cs-input\" type=\"number\" min=\"0\" [disabled]=\"!EditMode\"\n [ngModel]=\"MaxNewTagsPerRunValue ?? ''\"\n (ngModelChange)=\"MaxNewTagsPerRunValue = $event\"\n placeholder=\"unlimited\" />\n <span class=\"hint\">across all items</span>\n </div>\n <div class=\"cs-field\">\n <label>Max new tags / item</label>\n <input class=\"cs-input\" type=\"number\" min=\"0\" [disabled]=\"!EditMode\"\n [ngModel]=\"MaxNewTagsPerItemValue ?? ''\"\n (ngModelChange)=\"MaxNewTagsPerItemValue = $event\"\n placeholder=\"unlimited\" />\n <span class=\"hint\">extras \u2192 suggestions</span>\n </div>\n <div class=\"cs-field\">\n <label>Max tokens / run</label>\n <input class=\"cs-input\" type=\"number\" min=\"0\" [disabled]=\"!EditMode\"\n [ngModel]=\"MaxTokensPerRunValue ?? ''\"\n (ngModelChange)=\"MaxTokensPerRunValue = $event\"\n placeholder=\"unlimited\" />\n <span class=\"hint\">across all LLM calls</span>\n </div>\n <div class=\"cs-field\">\n <label>Max cost / run (USD)</label>\n <input class=\"cs-input\" type=\"number\" min=\"0\" step=\"0.01\" [disabled]=\"!EditMode\"\n [ngModel]=\"MaxCostPerRunValue ?? ''\"\n (ngModelChange)=\"MaxCostPerRunValue = $event\"\n placeholder=\"unlimited\" />\n <span class=\"hint\">$ stops the run</span>\n </div>\n </div>\n</mj-collapsible-panel>\n", styles: ["/* Tag Pipeline Configuration panel \u2014 dense form for the typed\n IContentSourceConfiguration knobs. The class names are shared with the\n Website Crawler Settings panel (same `cs-*` prefix family) so future\n ContentSource panels stay visually consistent without duplicating styles. */\n\n.cs-section-header {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--mj-text-muted);\n margin: 4px 0 8px;\n font-weight: 700;\n}\n.cs-section-header:not(:first-child) {\n margin-top: 16px;\n}\n.cs-section-header-note {\n text-transform: none;\n letter-spacing: 0;\n color: var(--mj-text-muted);\n font-weight: 400;\n margin-left: 8px;\n}\n\n.cs-mode-grid {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 8px;\n margin: 4px 0 12px;\n}\n.cs-mode-card {\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n border-radius: 8px;\n padding: 10px 12px;\n cursor: pointer;\n text-align: center;\n transition: background 0.12s, border-color 0.12s, box-shadow 0.12s;\n user-select: none;\n}\n.cs-mode-card:hover { background: var(--mj-bg-surface-hover); }\n.cs-mode-card.selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n border-color: var(--mj-brand-primary);\n box-shadow: inset 0 0 0 1px var(--mj-brand-primary);\n}\n.cs-mode-card .ic { font-size: 18px; color: var(--mj-text-secondary); }\n.cs-mode-card.selected .ic { color: var(--mj-brand-primary); }\n.cs-mode-card .nm { font-size: 13px; font-weight: 700; color: var(--mj-text-primary); margin: 4px 0 2px; }\n.cs-mode-card .desc { font-size: 11px; color: var(--mj-text-muted); line-height: 1.3; }\n\n.cs-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 14px 16px;\n margin: 4px 0 12px;\n}\n.cs-grid.four { grid-template-columns: repeat(4, 1fr); }\n.cs-grid.three { grid-template-columns: repeat(3, 1fr); }\n\n/* Primary budget row \u2014 MaxItemsPerRun gets its own emphasized row above\n the dense 4-col grid because it's the most user-intuitive cap. */\n.cs-primary-budget {\n margin: 4px 0 10px;\n padding: 10px 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 4%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 20%, var(--mj-border-default));\n border-radius: 6px;\n}\n.cs-field-primary label { font-size: 13px; color: var(--mj-text-primary); }\n.cs-field-primary .hint { line-height: 1.45; max-width: 78ch; }\n\n.cs-field { display: flex; flex-direction: column; gap: 4px; }\n.cs-field label { font-size: 12px; font-weight: 600; color: var(--mj-text-secondary); }\n.cs-field .hint { font-size: 11px; color: var(--mj-text-muted); }\n\n.cs-input {\n width: 100%;\n box-sizing: border-box;\n padding: 7px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n}\n.cs-input:focus {\n outline: none;\n border-color: var(--mj-border-focus, var(--mj-brand-primary));\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n.cs-input:disabled { opacity: 0.55; cursor: not-allowed; }\n\n.cs-threshold-pair {\n background: var(--mj-bg-surface-card);\n padding: 14px 16px;\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n}\n.cs-slider {\n appearance: none;\n -webkit-appearance: none;\n width: 100%;\n height: 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n margin: 8px 0 4px;\n}\n.cs-slider::-webkit-slider-thumb {\n appearance: none;\n -webkit-appearance: none;\n width: 16px; height: 16px; border-radius: 50%;\n background: var(--mj-brand-primary);\n cursor: pointer;\n border: 2px solid var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0,0,0,0.2);\n}\n.cs-slider::-moz-range-thumb {\n width: 16px; height: 16px; border-radius: 50%;\n background: var(--mj-brand-primary);\n cursor: pointer;\n border: 2px solid var(--mj-bg-surface);\n}\n.cs-slider-row {\n display: flex;\n justify-content: space-between;\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n.cs-slider-row .cur {\n font-family: ui-monospace, monospace;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.cs-validation {\n font-size: 12px;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-status-error) 12%, transparent);\n color: var(--mj-status-error-text, var(--mj-status-error));\n border-radius: 4px;\n margin-top: 8px;\n}\n.cs-nudge {\n font-size: 12px;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, transparent);\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n border-radius: 4px;\n margin-top: 8px;\n line-height: 1.4;\n}\n\n.cs-toggle-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 0;\n border-top: 1px dashed var(--mj-border-subtle);\n}\n.cs-toggle-row:first-child { border-top: 0; padding-top: 0; }\n.cs-toggle-row .label .t { font-size: 13px; font-weight: 600; }\n.cs-toggle-row .label .d { font-size: 11px; color: var(--mj-text-muted); }\n.cs-switch {\n position: relative;\n width: 36px; height: 20px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 10px;\n cursor: pointer;\n}\n.cs-switch::after {\n content: \"\";\n position: absolute;\n top: 2px; left: 2px;\n width: 16px; height: 16px;\n border-radius: 50%;\n background: var(--mj-bg-surface);\n transition: left 0.15s;\n box-shadow: 0 1px 2px rgba(0,0,0,0.2);\n}\n.cs-switch.on { background: var(--mj-brand-primary); }\n.cs-switch.on::after { left: 18px; }\n"] }]
|
|
386
386
|
}], null, null); })();
|
|
387
387
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TagPipelineConfigurationPanel, { className: "TagPipelineConfigurationPanel", filePath: "src/lib/panels/content-sources/tag-pipeline-configuration.panel.ts", lineNumber: 42 }); })();
|
|
388
388
|
/** Tree-shake guard — call this from the consuming module's loader. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tag-pipeline-configuration.panel.js","sourceRoot":"","sources":["../../../../src/lib/panels/content-sources/tag-pipeline-configuration.panel.ts","../../../../src/lib/panels/content-sources/tag-pipeline-configuration.panel.html"],"names":[],"mappings":"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","sourcesContent":["import { Component } from '@angular/core';\nimport { RegisterClassEx } from '@memberjunction/global';\nimport { BaseFormPanel } from '@memberjunction/ng-base-forms';\nimport { MJContentSourceEntity, MJContentSourceEntity_IContentSourceConfiguration } from '@memberjunction/core-entities';\n\ntype TaxonomyModeJson = NonNullable<MJContentSourceEntity_IContentSourceConfiguration['TagTaxonomyMode']>;\n\ninterface TaxonomyModeOption {\n value: TaxonomyModeJson;\n label: string;\n icon: string;\n desc: string;\n}\n\n/**\n * Tag Pipeline Configuration panel — the typed `IContentSourceConfiguration`\n * knobs (mode, thresholds, scope, taxonomy sharing, vectorization toggle, and\n * the five run-budget caps) surfaced as a dense form.\n *\n * Self-registers against the `after-fields` slot for `MJ: Content Sources`.\n * The slot host mounts it dynamically — no consumer template edits required.\n *\n * Also usable as a plain Angular component (composition pattern) — embed\n * directly in any custom UI (e.g. a dashboard quick-edit dialog) by binding\n * `[Record]` to the entity record and (optionally) `[FormComponent]`.\n */\n@RegisterClassEx(BaseFormPanel, {\n key: 'content-sources:tag-pipeline-configuration',\n skipNullKeyWarning: true,\n metadata: {\n entity: 'MJ: Content Sources',\n slot: 'after-fields',\n sortKey: 100,\n },\n})\n@Component({\n standalone: false,\n selector: 'mj-tag-pipeline-configuration-panel',\n templateUrl: './tag-pipeline-configuration.panel.html',\n styleUrls: ['./tag-pipeline-configuration.panel.css'],\n})\nexport class TagPipelineConfigurationPanel extends BaseFormPanel<MJContentSourceEntity> {\n public readonly TaxonomyModes: TaxonomyModeOption[] = [\n { value: 'constrained', label: 'Constrained', icon: 'fa-lock', desc: 'Curated only — every novel name → suggestion queue.' },\n { value: 'auto-grow', label: 'AutoGrow', icon: 'fa-seedling', desc: 'Bounded auto-creation under TagRoot, gated by per-tag governance.' },\n { value: 'free-flow', label: 'FreeFlow', icon: 'fa-water', desc: 'Anything goes — auto-create root-level tags as needed.' },\n ];\n\n /** Read the typed Configuration object — never null, defaults applied where the JSON didn't supply them. */\n public get Config(): MJContentSourceEntity_IContentSourceConfiguration {\n return this.Record?.ConfigurationObject ?? {};\n }\n\n public SetConfig(patch: Partial<MJContentSourceEntity_IContentSourceConfiguration>): void {\n if (!this.Record) return;\n const current = this.Record.ConfigurationObject ?? {};\n const merged: MJContentSourceEntity_IContentSourceConfiguration = { ...current, ...patch };\n this.Record.ConfigurationObject = merged;\n }\n\n /** @deprecated Use {@link SetConfig}. */\n public setConfig(patch: Partial<MJContentSourceEntity_IContentSourceConfiguration>): void {\n return this.SetConfig(patch);\n }\n\n // ---------- Mode -------------------------------------------------------\n\n public get CurrentMode(): TaxonomyModeJson {\n return this.Config.TagTaxonomyMode ?? 'auto-grow';\n }\n public SetMode(mode: TaxonomyModeJson): void {\n this.SetConfig({ TagTaxonomyMode: mode });\n }\n\n // ---------- Thresholds -------------------------------------------------\n\n public get MatchThresholdValue(): number {\n return this.Config.TagMatchThreshold ?? 0.85;\n }\n public set MatchThresholdValue(v: number) {\n const clamped = Math.max(0, Math.min(1, Number(v) || 0));\n const cur = this.Config.SuggestThreshold;\n const patch: Partial<MJContentSourceEntity_IContentSourceConfiguration> = { TagMatchThreshold: clamped };\n if (cur == null || cur >= clamped) patch.SuggestThreshold = Math.max(0, clamped - 0.05);\n this.SetConfig(patch);\n }\n public get SuggestThresholdValue(): number {\n return this.Config.SuggestThreshold ?? Math.max(0, this.MatchThresholdValue - 0.05);\n }\n public set SuggestThresholdValue(v: number) {\n const clamped = Math.max(0, Math.min(this.MatchThresholdValue, Number(v) || 0));\n this.SetConfig({ SuggestThreshold: clamped });\n }\n public get ThresholdValidationMessage(): string | null {\n const m = this.Config.TagMatchThreshold;\n const s = this.Config.SuggestThreshold;\n if (m != null && s != null && s >= m) {\n return 'SuggestThreshold must be lower than MatchThreshold.';\n }\n return null;\n }\n\n // ---------- Tag root + share-with-LLM ----------------------------------\n\n public get TagRootIDValue(): string | null {\n return this.Config.TagRootID ?? null;\n }\n public set TagRootIDValue(v: string | null) {\n this.SetConfig({ TagRootID: v ?? null });\n }\n public get ShareTaxonomyValue(): boolean {\n return this.Config.ShareTaxonomyWithLLM !== false; // default true\n }\n public set ShareTaxonomyValue(v: boolean) {\n this.SetConfig({ ShareTaxonomyWithLLM: v });\n }\n public get EnableVectorizationValue(): boolean {\n return this.Config.EnableVectorization !== false; // default true\n }\n public set EnableVectorizationValue(v: boolean) {\n this.SetConfig({ EnableVectorization: v });\n }\n\n // ---------- Budgets ----------------------------------------------------\n\n public get MaxItemsPerRunValue(): number | null {\n return this.Config.MaxItemsPerRun ?? null;\n }\n public set MaxItemsPerRunValue(v: number | string | null) {\n this.SetConfig({ MaxItemsPerRun: this.normalizeNullableNumber(v) });\n }\n public get MaxNewTagsPerRunValue(): number | null {\n return this.Config.MaxNewTagsPerRun ?? null;\n }\n public set MaxNewTagsPerRunValue(v: number | string | null) {\n this.SetConfig({ MaxNewTagsPerRun: this.normalizeNullableNumber(v) });\n }\n public get MaxNewTagsPerItemValue(): number | null {\n return this.Config.MaxNewTagsPerItem ?? null;\n }\n public set MaxNewTagsPerItemValue(v: number | string | null) {\n this.SetConfig({ MaxNewTagsPerItem: this.normalizeNullableNumber(v) });\n }\n public get MaxTokensPerRunValue(): number | null {\n return this.Config.MaxTokensPerRun ?? null;\n }\n public set MaxTokensPerRunValue(v: number | string | null) {\n this.SetConfig({ MaxTokensPerRun: this.normalizeNullableNumber(v) });\n }\n public get MaxCostPerRunValue(): number | null {\n return this.Config.MaxCostPerRun ?? null;\n }\n public set MaxCostPerRunValue(v: number | string | null) {\n this.SetConfig({ MaxCostPerRun: this.normalizeNullableNumber(v) });\n }\n\n /**\n * Coerce a possibly-blank input into a typed number. Returning undefined\n * deletes the key from the persisted JSON when the setConfig spread is applied.\n */\n private normalizeNullableNumber(v: number | string | null | undefined): number | undefined {\n if (v == null) return undefined;\n if (typeof v === 'string') {\n const trimmed = v.trim();\n if (trimmed === '') return undefined;\n const n = Number(trimmed);\n return Number.isFinite(n) ? n : undefined;\n }\n return Number.isFinite(v) ? v : undefined;\n }\n}\n\n/** Tree-shake guard — call this from the consuming module's loader. */\nexport function LoadTagPipelineConfigurationPanel(): void { /* no-op marker */ }\n","<mj-collapsible-panel\n SectionKey=\"tagPipelineConfiguration\"\n SectionName=\"Tag Pipeline Configuration\"\n Icon=\"fa fa-sliders-h\"\n [Form]=\"FormComponent\"\n [FormContext]=\"FormContext\">\n\n <!-- 1. Taxonomy mode -->\n <h4 class=\"cs-section-header\">Taxonomy mode</h4>\n <div class=\"cs-mode-grid\">\n @for (m of TaxonomyModes; track m.value) {\n <div class=\"cs-mode-card\"\n [class.selected]=\"CurrentMode === m.value\"\n (click)=\"EditMode ? SetMode(m.value) : null\">\n <i class=\"fa-solid {{ m.icon }} ic\"></i>\n <div class=\"nm\">{{ m.label }}</div>\n <div class=\"desc\">{{ m.desc }}</div>\n </div>\n }\n </div>\n\n <!-- 2. Scope & root -->\n <h4 class=\"cs-section-header\">Scope & tag root</h4>\n <div class=\"cs-grid\">\n <div class=\"cs-field\">\n <label>Tag root (TagRootID)</label>\n <input class=\"cs-input\" [disabled]=\"!EditMode\"\n [ngModel]=\"TagRootIDValue\"\n (ngModelChange)=\"TagRootIDValue = $event\" />\n <span class=\"hint\">Restricts the LLM's visible taxonomy + auto-grow target. Leave blank for full taxonomy.</span>\n </div>\n <div class=\"cs-field\">\n <label>Embedding model (legacy ContentSource field)</label>\n <input class=\"cs-input\" disabled [value]=\"Record?.EmbeddingModelID || '—'\" />\n <span class=\"hint\">Set in the AI & Indexing section above.</span>\n </div>\n </div>\n\n <div class=\"cs-toggle-row\">\n <div class=\"label\">\n <span class=\"t\">Share full taxonomy with the LLM</span>\n <span class=\"d\">When on, the LLM prompt includes the visible (scope-filtered) taxonomy. Larger taxonomies → higher token cost.</span>\n </div>\n <div class=\"cs-switch\" [class.on]=\"ShareTaxonomyValue\"\n (click)=\"EditMode ? (ShareTaxonomyValue = !ShareTaxonomyValue) : null\"></div>\n </div>\n <div class=\"cs-toggle-row\">\n <div class=\"label\">\n <span class=\"t\">Vectorize new content</span>\n <span class=\"d\">When off, this source skips vectorization (autotagger still runs).</span>\n </div>\n <div class=\"cs-switch\" [class.on]=\"EnableVectorizationValue\"\n (click)=\"EditMode ? (EnableVectorizationValue = !EnableVectorizationValue) : null\"></div>\n </div>\n\n <!-- 3. Thresholds -->\n <h4 class=\"cs-section-header\">Thresholds</h4>\n <div class=\"cs-threshold-pair\">\n <div class=\"cs-grid\">\n <div class=\"cs-field\">\n <label>MatchThreshold (auto-apply)</label>\n <input type=\"range\" class=\"cs-slider\" min=\"0.50\" max=\"1.00\" step=\"0.01\"\n [disabled]=\"!EditMode\"\n [ngModel]=\"MatchThresholdValue\"\n (ngModelChange)=\"MatchThresholdValue = $event\" />\n <div class=\"cs-slider-row\"><span>0.50</span><span class=\"cur\">{{ MatchThresholdValue | number: '1.2-2' }}</span><span>1.00</span></div>\n </div>\n <div class=\"cs-field\">\n <label>SuggestThreshold (route to inbox)</label>\n <input type=\"range\" class=\"cs-slider\" min=\"0.50\" max=\"1.00\" step=\"0.01\"\n [disabled]=\"!EditMode\"\n [ngModel]=\"SuggestThresholdValue\"\n (ngModelChange)=\"SuggestThresholdValue = $event\" />\n <div class=\"cs-slider-row\"><span>0.50</span><span class=\"cur\">{{ SuggestThresholdValue | number: '1.2-2' }}</span><span>1.00</span></div>\n </div>\n </div>\n @if (ThresholdValidationMessage) {\n <div class=\"cs-validation\"><i class=\"fa-solid fa-circle-exclamation\"></i> {{ ThresholdValidationMessage }}</div>\n } @else {\n <div class=\"cs-nudge\">\n Scores ≥ <strong>{{ MatchThresholdValue | number: '1.2-2' }}</strong> auto-apply.\n Scores in <strong>[{{ SuggestThresholdValue | number: '1.2-2' }}, {{ MatchThresholdValue | number: '1.2-2' }})</strong> route to the suggestion inbox.\n Below that, the run falls through to handleNoMatch.\n </div>\n }\n </div>\n\n <!-- 4. Volume + cost budgets -->\n <h4 class=\"cs-section-header\">\n Volume & cost budgets\n <span class=\"cs-section-header-note\">When a budget is hit the run pauses (resumes on next start).</span>\n </h4>\n\n <div class=\"cs-primary-budget\">\n <div class=\"cs-field cs-field-primary\">\n <label>Max items / run</label>\n <input class=\"cs-input\" type=\"number\" min=\"0\" [disabled]=\"!EditMode\"\n [ngModel]=\"MaxItemsPerRunValue ?? ''\"\n (ngModelChange)=\"MaxItemsPerRunValue = $event\"\n placeholder=\"unlimited\" />\n <span class=\"hint\">Caps the number of content items handed to the LLM. Skipped (unchanged) items don't count. Paused work resumes on the next run — the change-detection short-circuit skips already-tagged pages, so re-crawl only wastes HTTP, not LLM cycles.</span>\n </div>\n </div>\n\n <div class=\"cs-grid four\">\n <div class=\"cs-field\">\n <label>Max new tags / run</label>\n <input class=\"cs-input\" type=\"number\" min=\"0\" [disabled]=\"!EditMode\"\n [ngModel]=\"MaxNewTagsPerRunValue ?? ''\"\n (ngModelChange)=\"MaxNewTagsPerRunValue = $event\"\n placeholder=\"unlimited\" />\n <span class=\"hint\">across all items</span>\n </div>\n <div class=\"cs-field\">\n <label>Max new tags / item</label>\n <input class=\"cs-input\" type=\"number\" min=\"0\" [disabled]=\"!EditMode\"\n [ngModel]=\"MaxNewTagsPerItemValue ?? ''\"\n (ngModelChange)=\"MaxNewTagsPerItemValue = $event\"\n placeholder=\"unlimited\" />\n <span class=\"hint\">extras → suggestions</span>\n </div>\n <div class=\"cs-field\">\n <label>Max tokens / run</label>\n <input class=\"cs-input\" type=\"number\" min=\"0\" [disabled]=\"!EditMode\"\n [ngModel]=\"MaxTokensPerRunValue ?? ''\"\n (ngModelChange)=\"MaxTokensPerRunValue = $event\"\n placeholder=\"unlimited\" />\n <span class=\"hint\">across all LLM calls</span>\n </div>\n <div class=\"cs-field\">\n <label>Max cost / run (USD)</label>\n <input class=\"cs-input\" type=\"number\" min=\"0\" step=\"0.01\" [disabled]=\"!EditMode\"\n [ngModel]=\"MaxCostPerRunValue ?? ''\"\n (ngModelChange)=\"MaxCostPerRunValue = $event\"\n placeholder=\"unlimited\" />\n <span class=\"hint\">$ stops the run</span>\n </div>\n </div>\n</mj-collapsible-panel>\n"]}
|
|
1
|
+
{"version":3,"file":"tag-pipeline-configuration.panel.js","sourceRoot":"","sources":["../../../../src/lib/panels/content-sources/tag-pipeline-configuration.panel.ts","../../../../src/lib/panels/content-sources/tag-pipeline-configuration.panel.html"],"names":[],"mappings":"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","sourcesContent":["import { Component } from '@angular/core';\nimport { RegisterClassEx } from '@memberjunction/global';\nimport { BaseFormPanel } from '@memberjunction/ng-base-forms';\nimport { MJContentSourceEntity, MJContentSourceEntity_IContentSourceConfiguration } from '@memberjunction/core-entities';\n\ntype TaxonomyModeJson = NonNullable<MJContentSourceEntity_IContentSourceConfiguration['TagTaxonomyMode']>;\n\ninterface TaxonomyModeOption {\n value: TaxonomyModeJson;\n label: string;\n icon: string;\n desc: string;\n}\n\n/**\n * Tag Pipeline Configuration panel — the typed `IContentSourceConfiguration`\n * knobs (mode, thresholds, scope, taxonomy sharing, vectorization toggle, and\n * the five run-budget caps) surfaced as a dense form.\n *\n * Self-registers against the `after-fields` slot for `MJ: Content Sources`.\n * The slot host mounts it dynamically — no consumer template edits required.\n *\n * Also usable as a plain Angular component (composition pattern) — embed\n * directly in any custom UI (e.g. a dashboard quick-edit dialog) by binding\n * `[Record]` to the entity record and (optionally) `[FormComponent]`.\n */\n@RegisterClassEx(BaseFormPanel, {\n key: 'content-sources:tag-pipeline-configuration',\n skipNullKeyWarning: true,\n metadata: {\n entity: 'MJ: Content Sources',\n slot: 'after-fields',\n sortKey: 100,\n },\n})\n@Component({\n standalone: false,\n selector: 'mj-tag-pipeline-configuration-panel',\n templateUrl: './tag-pipeline-configuration.panel.html',\n styleUrls: ['./tag-pipeline-configuration.panel.css'],\n})\nexport class TagPipelineConfigurationPanel extends BaseFormPanel<MJContentSourceEntity> {\n public readonly TaxonomyModes: TaxonomyModeOption[] = [\n { value: 'constrained', label: 'Constrained', icon: 'fa-lock', desc: 'Curated only — every novel name → suggestion queue.' },\n { value: 'auto-grow', label: 'AutoGrow', icon: 'fa-seedling', desc: 'Bounded auto-creation under TagRoot, gated by per-tag governance.' },\n { value: 'free-flow', label: 'FreeFlow', icon: 'fa-water', desc: 'Anything goes — auto-create root-level tags as needed.' },\n ];\n\n /** Read the typed Configuration object — never null, defaults applied where the JSON didn't supply them. */\n public get Config(): MJContentSourceEntity_IContentSourceConfiguration {\n return this.Record?.ConfigurationObject ?? {};\n }\n\n public SetConfig(patch: Partial<MJContentSourceEntity_IContentSourceConfiguration>): void {\n if (!this.Record) return;\n const current = this.Record.ConfigurationObject ?? {};\n const merged: MJContentSourceEntity_IContentSourceConfiguration = { ...current, ...patch };\n this.Record.ConfigurationObject = merged;\n }\n\n /** @deprecated Use {@link SetConfig}. */\n public setConfig(patch: Partial<MJContentSourceEntity_IContentSourceConfiguration>): void {\n return this.SetConfig(patch);\n }\n\n // ---------- Mode -------------------------------------------------------\n\n public get CurrentMode(): TaxonomyModeJson {\n return this.Config.TagTaxonomyMode ?? 'auto-grow';\n }\n public SetMode(mode: TaxonomyModeJson): void {\n this.SetConfig({ TagTaxonomyMode: mode });\n }\n\n // ---------- Thresholds -------------------------------------------------\n\n public get MatchThresholdValue(): number {\n return this.Config.TagMatchThreshold ?? 0.85;\n }\n public set MatchThresholdValue(v: number) {\n const clamped = Math.max(0, Math.min(1, Number(v) || 0));\n const cur = this.Config.SuggestThreshold;\n const patch: Partial<MJContentSourceEntity_IContentSourceConfiguration> = { TagMatchThreshold: clamped };\n if (cur == null || cur >= clamped) patch.SuggestThreshold = Math.max(0, clamped - 0.05);\n this.SetConfig(patch);\n }\n public get SuggestThresholdValue(): number {\n return this.Config.SuggestThreshold ?? Math.max(0, this.MatchThresholdValue - 0.05);\n }\n public set SuggestThresholdValue(v: number) {\n const clamped = Math.max(0, Math.min(this.MatchThresholdValue, Number(v) || 0));\n this.SetConfig({ SuggestThreshold: clamped });\n }\n public get ThresholdValidationMessage(): string | null {\n const m = this.Config.TagMatchThreshold;\n const s = this.Config.SuggestThreshold;\n if (m != null && s != null && s >= m) {\n return 'SuggestThreshold must be lower than MatchThreshold.';\n }\n return null;\n }\n\n // ---------- Tag root + share-with-LLM ----------------------------------\n\n public get TagRootIDValue(): string | null {\n return this.Config.TagRootID ?? null;\n }\n public set TagRootIDValue(v: string | null) {\n this.SetConfig({ TagRootID: v ?? null });\n }\n public get ShareTaxonomyValue(): boolean {\n return this.Config.ShareTaxonomyWithLLM !== false; // default true\n }\n public set ShareTaxonomyValue(v: boolean) {\n this.SetConfig({ ShareTaxonomyWithLLM: v });\n }\n public get EnableVectorizationValue(): boolean {\n return this.Config.EnableVectorization !== false; // default true\n }\n public set EnableVectorizationValue(v: boolean) {\n this.SetConfig({ EnableVectorization: v });\n }\n\n // ---------- Budgets ----------------------------------------------------\n\n public get MaxItemsPerRunValue(): number | null {\n return this.Config.MaxItemsPerRun ?? null;\n }\n public set MaxItemsPerRunValue(v: number | string | null) {\n this.SetConfig({ MaxItemsPerRun: this.normalizeNullableNumber(v) });\n }\n public get MaxNewTagsPerRunValue(): number | null {\n return this.Config.MaxNewTagsPerRun ?? null;\n }\n public set MaxNewTagsPerRunValue(v: number | string | null) {\n this.SetConfig({ MaxNewTagsPerRun: this.normalizeNullableNumber(v) });\n }\n public get MaxNewTagsPerItemValue(): number | null {\n return this.Config.MaxNewTagsPerItem ?? null;\n }\n public set MaxNewTagsPerItemValue(v: number | string | null) {\n this.SetConfig({ MaxNewTagsPerItem: this.normalizeNullableNumber(v) });\n }\n public get MaxTokensPerRunValue(): number | null {\n return this.Config.MaxTokensPerRun ?? null;\n }\n public set MaxTokensPerRunValue(v: number | string | null) {\n this.SetConfig({ MaxTokensPerRun: this.normalizeNullableNumber(v) });\n }\n public get MaxCostPerRunValue(): number | null {\n return this.Config.MaxCostPerRun ?? null;\n }\n public set MaxCostPerRunValue(v: number | string | null) {\n this.SetConfig({ MaxCostPerRun: this.normalizeNullableNumber(v) });\n }\n\n /**\n * Coerce a possibly-blank input into a typed number. Returning undefined\n * deletes the key from the persisted JSON when the setConfig spread is applied.\n */\n private normalizeNullableNumber(v: number | string | null | undefined): number | undefined {\n if (v == null) return undefined;\n if (typeof v === 'string') {\n const trimmed = v.trim();\n if (trimmed === '') return undefined;\n const n = Number(trimmed);\n return Number.isFinite(n) ? n : undefined;\n }\n return Number.isFinite(v) ? v : undefined;\n }\n}\n\n/** Tree-shake guard — call this from the consuming module's loader. */\nexport function LoadTagPipelineConfigurationPanel(): void { /* no-op marker */ }\n","<mj-collapsible-panel\n SectionKey=\"tagPipelineConfiguration\"\n [Order]=\"DisplayOrder\"\n SectionName=\"Tag Pipeline Configuration\"\n Icon=\"fa fa-sliders-h\"\n [Form]=\"FormComponent\"\n [FormContext]=\"FormContext\">\n\n <!-- 1. Taxonomy mode -->\n <h4 class=\"cs-section-header\">Taxonomy mode</h4>\n <div class=\"cs-mode-grid\">\n @for (m of TaxonomyModes; track m.value) {\n <div class=\"cs-mode-card\"\n [class.selected]=\"CurrentMode === m.value\"\n (click)=\"EditMode ? SetMode(m.value) : null\">\n <i class=\"fa-solid {{ m.icon }} ic\"></i>\n <div class=\"nm\">{{ m.label }}</div>\n <div class=\"desc\">{{ m.desc }}</div>\n </div>\n }\n </div>\n\n <!-- 2. Scope & root -->\n <h4 class=\"cs-section-header\">Scope & tag root</h4>\n <div class=\"cs-grid\">\n <div class=\"cs-field\">\n <label>Tag root (TagRootID)</label>\n <input class=\"cs-input\" [disabled]=\"!EditMode\"\n [ngModel]=\"TagRootIDValue\"\n (ngModelChange)=\"TagRootIDValue = $event\" />\n <span class=\"hint\">Restricts the LLM's visible taxonomy + auto-grow target. Leave blank for full taxonomy.</span>\n </div>\n <div class=\"cs-field\">\n <label>Embedding model (legacy ContentSource field)</label>\n <input class=\"cs-input\" disabled [value]=\"Record?.EmbeddingModelID || '—'\" />\n <span class=\"hint\">Set in the AI & Indexing section above.</span>\n </div>\n </div>\n\n <div class=\"cs-toggle-row\">\n <div class=\"label\">\n <span class=\"t\">Share full taxonomy with the LLM</span>\n <span class=\"d\">When on, the LLM prompt includes the visible (scope-filtered) taxonomy. Larger taxonomies → higher token cost.</span>\n </div>\n <div class=\"cs-switch\" [class.on]=\"ShareTaxonomyValue\"\n (click)=\"EditMode ? (ShareTaxonomyValue = !ShareTaxonomyValue) : null\"></div>\n </div>\n <div class=\"cs-toggle-row\">\n <div class=\"label\">\n <span class=\"t\">Vectorize new content</span>\n <span class=\"d\">When off, this source skips vectorization (autotagger still runs).</span>\n </div>\n <div class=\"cs-switch\" [class.on]=\"EnableVectorizationValue\"\n (click)=\"EditMode ? (EnableVectorizationValue = !EnableVectorizationValue) : null\"></div>\n </div>\n\n <!-- 3. Thresholds -->\n <h4 class=\"cs-section-header\">Thresholds</h4>\n <div class=\"cs-threshold-pair\">\n <div class=\"cs-grid\">\n <div class=\"cs-field\">\n <label>MatchThreshold (auto-apply)</label>\n <input type=\"range\" class=\"cs-slider\" min=\"0.50\" max=\"1.00\" step=\"0.01\"\n [disabled]=\"!EditMode\"\n [ngModel]=\"MatchThresholdValue\"\n (ngModelChange)=\"MatchThresholdValue = $event\" />\n <div class=\"cs-slider-row\"><span>0.50</span><span class=\"cur\">{{ MatchThresholdValue | number: '1.2-2' }}</span><span>1.00</span></div>\n </div>\n <div class=\"cs-field\">\n <label>SuggestThreshold (route to inbox)</label>\n <input type=\"range\" class=\"cs-slider\" min=\"0.50\" max=\"1.00\" step=\"0.01\"\n [disabled]=\"!EditMode\"\n [ngModel]=\"SuggestThresholdValue\"\n (ngModelChange)=\"SuggestThresholdValue = $event\" />\n <div class=\"cs-slider-row\"><span>0.50</span><span class=\"cur\">{{ SuggestThresholdValue | number: '1.2-2' }}</span><span>1.00</span></div>\n </div>\n </div>\n @if (ThresholdValidationMessage) {\n <div class=\"cs-validation\"><i class=\"fa-solid fa-circle-exclamation\"></i> {{ ThresholdValidationMessage }}</div>\n } @else {\n <div class=\"cs-nudge\">\n Scores ≥ <strong>{{ MatchThresholdValue | number: '1.2-2' }}</strong> auto-apply.\n Scores in <strong>[{{ SuggestThresholdValue | number: '1.2-2' }}, {{ MatchThresholdValue | number: '1.2-2' }})</strong> route to the suggestion inbox.\n Below that, the run falls through to handleNoMatch.\n </div>\n }\n </div>\n\n <!-- 4. Volume + cost budgets -->\n <h4 class=\"cs-section-header\">\n Volume & cost budgets\n <span class=\"cs-section-header-note\">When a budget is hit the run pauses (resumes on next start).</span>\n </h4>\n\n <div class=\"cs-primary-budget\">\n <div class=\"cs-field cs-field-primary\">\n <label>Max items / run</label>\n <input class=\"cs-input\" type=\"number\" min=\"0\" [disabled]=\"!EditMode\"\n [ngModel]=\"MaxItemsPerRunValue ?? ''\"\n (ngModelChange)=\"MaxItemsPerRunValue = $event\"\n placeholder=\"unlimited\" />\n <span class=\"hint\">Caps the number of content items handed to the LLM. Skipped (unchanged) items don't count. Paused work resumes on the next run — the change-detection short-circuit skips already-tagged pages, so re-crawl only wastes HTTP, not LLM cycles.</span>\n </div>\n </div>\n\n <div class=\"cs-grid four\">\n <div class=\"cs-field\">\n <label>Max new tags / run</label>\n <input class=\"cs-input\" type=\"number\" min=\"0\" [disabled]=\"!EditMode\"\n [ngModel]=\"MaxNewTagsPerRunValue ?? ''\"\n (ngModelChange)=\"MaxNewTagsPerRunValue = $event\"\n placeholder=\"unlimited\" />\n <span class=\"hint\">across all items</span>\n </div>\n <div class=\"cs-field\">\n <label>Max new tags / item</label>\n <input class=\"cs-input\" type=\"number\" min=\"0\" [disabled]=\"!EditMode\"\n [ngModel]=\"MaxNewTagsPerItemValue ?? ''\"\n (ngModelChange)=\"MaxNewTagsPerItemValue = $event\"\n placeholder=\"unlimited\" />\n <span class=\"hint\">extras → suggestions</span>\n </div>\n <div class=\"cs-field\">\n <label>Max tokens / run</label>\n <input class=\"cs-input\" type=\"number\" min=\"0\" [disabled]=\"!EditMode\"\n [ngModel]=\"MaxTokensPerRunValue ?? ''\"\n (ngModelChange)=\"MaxTokensPerRunValue = $event\"\n placeholder=\"unlimited\" />\n <span class=\"hint\">across all LLM calls</span>\n </div>\n <div class=\"cs-field\">\n <label>Max cost / run (USD)</label>\n <input class=\"cs-input\" type=\"number\" min=\"0\" step=\"0.01\" [disabled]=\"!EditMode\"\n [ngModel]=\"MaxCostPerRunValue ?? ''\"\n (ngModelChange)=\"MaxCostPerRunValue = $event\"\n placeholder=\"unlimited\" />\n <span class=\"hint\">$ stops the run</span>\n </div>\n </div>\n</mj-collapsible-panel>\n"]}
|
|
@@ -81,7 +81,7 @@ function WebsiteCrawlerSettingsPanel_Conditional_0_Template(rf, ctx) { if (rf &
|
|
|
81
81
|
i0.ɵɵelementEnd()()();
|
|
82
82
|
} if (rf & 2) {
|
|
83
83
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
84
|
-
i0.ɵɵproperty("Form", ctx_r1.FormComponent)("FormContext", ctx_r1.FormContext);
|
|
84
|
+
i0.ɵɵproperty("Order", ctx_r1.DisplayOrder)("Form", ctx_r1.FormComponent)("FormContext", ctx_r1.FormContext);
|
|
85
85
|
i0.ɵɵadvance(5);
|
|
86
86
|
i0.ɵɵproperty("disabled", !ctx_r1.EditMode)("ngModel", ctx_r1.MaxDepthValue ?? "");
|
|
87
87
|
i0.ɵɵadvance(12);
|
|
@@ -197,8 +197,8 @@ let WebsiteCrawlerSettingsPanel = class WebsiteCrawlerSettingsPanel extends Base
|
|
|
197
197
|
return Number.isFinite(v) ? v : undefined;
|
|
198
198
|
}
|
|
199
199
|
static { this.ɵfac = /*@__PURE__*/ (() => { let ɵWebsiteCrawlerSettingsPanel_BaseFactory; return function WebsiteCrawlerSettingsPanel_Factory(__ngFactoryType__) { return (ɵWebsiteCrawlerSettingsPanel_BaseFactory || (ɵWebsiteCrawlerSettingsPanel_BaseFactory = i0.ɵɵgetInheritedFactory(WebsiteCrawlerSettingsPanel)))(__ngFactoryType__ || WebsiteCrawlerSettingsPanel); }; })(); }
|
|
200
|
-
static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: WebsiteCrawlerSettingsPanel, selectors: [["mj-website-crawler-settings-panel"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 1, vars: 1, consts: [["SectionKey", "websiteCrawlerSettings", "SectionName", "Website Crawler Settings", "Icon", "fa fa-globe", 3, "Form", "FormContext"], [1, "cs-grid"], [1, "cs-field"], ["type", "number", "min", "0", "max", "10", "step", "1", "placeholder", "2 (default)", 1, "cs-input", 3, "ngModelChange", "disabled", "ngModel"], [1, "hint"], ["type", "text", "placeholder", "derived from start URL", 1, "cs-input", 3, "ngModelChange", "disabled", "ngModel"], [1, "cs-field", 2, "margin-top", "8px"], ["type", "text", "placeholder", "e.g. ^https://example\\.com/blog/.*", 1, "cs-input", 3, "ngModelChange", "disabled", "ngModel"], [1, "cs-validation"], [1, "cs-toggle-row", 2, "margin-top", "12px"], [1, "label"], [1, "t"], [1, "d"], [1, "cs-switch", 3, "click"], [1, "cs-toggle-row"], [1, "fa-solid", "fa-circle-exclamation"]], template: function WebsiteCrawlerSettingsPanel_Template(rf, ctx) { if (rf & 1) {
|
|
201
|
-
i0.ɵɵconditionalCreate(0, WebsiteCrawlerSettingsPanel_Conditional_0_Template, 40,
|
|
200
|
+
static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: WebsiteCrawlerSettingsPanel, selectors: [["mj-website-crawler-settings-panel"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 1, vars: 1, consts: [["SectionKey", "websiteCrawlerSettings", "SectionName", "Website Crawler Settings", "Icon", "fa fa-globe", 3, "Order", "Form", "FormContext"], [1, "cs-grid"], [1, "cs-field"], ["type", "number", "min", "0", "max", "10", "step", "1", "placeholder", "2 (default)", 1, "cs-input", 3, "ngModelChange", "disabled", "ngModel"], [1, "hint"], ["type", "text", "placeholder", "derived from start URL", 1, "cs-input", 3, "ngModelChange", "disabled", "ngModel"], [1, "cs-field", 2, "margin-top", "8px"], ["type", "text", "placeholder", "e.g. ^https://example\\.com/blog/.*", 1, "cs-input", 3, "ngModelChange", "disabled", "ngModel"], [1, "cs-validation"], [1, "cs-toggle-row", 2, "margin-top", "12px"], [1, "label"], [1, "t"], [1, "d"], [1, "cs-switch", 3, "click"], [1, "cs-toggle-row"], [1, "fa-solid", "fa-circle-exclamation"]], template: function WebsiteCrawlerSettingsPanel_Template(rf, ctx) { if (rf & 1) {
|
|
201
|
+
i0.ɵɵconditionalCreate(0, WebsiteCrawlerSettingsPanel_Conditional_0_Template, 40, 14, "mj-collapsible-panel", 0);
|
|
202
202
|
} if (rf & 2) {
|
|
203
203
|
i0.ɵɵconditional(ctx.IsWebsiteSourceType ? 0 : -1);
|
|
204
204
|
} }, dependencies: [i1.DefaultValueAccessor, i1.NumberValueAccessor, i1.NgControlStatus, i1.MinValidator, i1.MaxValidator, i1.NgModel, i2.MjCollapsiblePanelComponent], styles: ["\n\n\n\n\n.cs-section-header[_ngcontent-%COMP%] {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--mj-text-muted);\n margin: 4px 0 8px;\n font-weight: 700;\n}\n.cs-section-header[_ngcontent-%COMP%]:not(:first-child) {\n margin-top: 16px;\n}\n.cs-section-header-note[_ngcontent-%COMP%] {\n text-transform: none;\n letter-spacing: 0;\n color: var(--mj-text-muted);\n font-weight: 400;\n margin-left: 8px;\n}\n\n.cs-mode-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 8px;\n margin: 4px 0 12px;\n}\n.cs-mode-card[_ngcontent-%COMP%] {\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n border-radius: 8px;\n padding: 10px 12px;\n cursor: pointer;\n text-align: center;\n transition: background 0.12s, border-color 0.12s, box-shadow 0.12s;\n user-select: none;\n}\n.cs-mode-card[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); }\n.cs-mode-card.selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n border-color: var(--mj-brand-primary);\n box-shadow: inset 0 0 0 1px var(--mj-brand-primary);\n}\n.cs-mode-card[_ngcontent-%COMP%] .ic[_ngcontent-%COMP%] { font-size: 18px; color: var(--mj-text-secondary); }\n.cs-mode-card.selected[_ngcontent-%COMP%] .ic[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n.cs-mode-card[_ngcontent-%COMP%] .nm[_ngcontent-%COMP%] { font-size: 13px; font-weight: 700; color: var(--mj-text-primary); margin: 4px 0 2px; }\n.cs-mode-card[_ngcontent-%COMP%] .desc[_ngcontent-%COMP%] { font-size: 11px; color: var(--mj-text-muted); line-height: 1.3; }\n\n.cs-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 14px 16px;\n margin: 4px 0 12px;\n}\n.cs-grid.four[_ngcontent-%COMP%] { grid-template-columns: repeat(4, 1fr); }\n.cs-grid.three[_ngcontent-%COMP%] { grid-template-columns: repeat(3, 1fr); }\n\n\n\n.cs-primary-budget[_ngcontent-%COMP%] {\n margin: 4px 0 10px;\n padding: 10px 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 4%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 20%, var(--mj-border-default));\n border-radius: 6px;\n}\n.cs-field-primary[_ngcontent-%COMP%] label[_ngcontent-%COMP%] { font-size: 13px; color: var(--mj-text-primary); }\n.cs-field-primary[_ngcontent-%COMP%] .hint[_ngcontent-%COMP%] { line-height: 1.45; max-width: 78ch; }\n\n.cs-field[_ngcontent-%COMP%] { display: flex; flex-direction: column; gap: 4px; }\n.cs-field[_ngcontent-%COMP%] label[_ngcontent-%COMP%] { font-size: 12px; font-weight: 600; color: var(--mj-text-secondary); }\n.cs-field[_ngcontent-%COMP%] .hint[_ngcontent-%COMP%] { font-size: 11px; color: var(--mj-text-muted); }\n\n.cs-input[_ngcontent-%COMP%] {\n width: 100%;\n box-sizing: border-box;\n padding: 7px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n}\n.cs-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-border-focus, var(--mj-brand-primary));\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n.cs-input[_ngcontent-%COMP%]:disabled { opacity: 0.55; cursor: not-allowed; }\n\n.cs-threshold-pair[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n padding: 14px 16px;\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n}\n.cs-slider[_ngcontent-%COMP%] {\n appearance: none;\n -webkit-appearance: none;\n width: 100%;\n height: 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n margin: 8px 0 4px;\n}\n.cs-slider[_ngcontent-%COMP%]::-webkit-slider-thumb {\n appearance: none;\n -webkit-appearance: none;\n width: 16px; height: 16px; border-radius: 50%;\n background: var(--mj-brand-primary);\n cursor: pointer;\n border: 2px solid var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0,0,0,0.2);\n}\n.cs-slider[_ngcontent-%COMP%]::-moz-range-thumb {\n width: 16px; height: 16px; border-radius: 50%;\n background: var(--mj-brand-primary);\n cursor: pointer;\n border: 2px solid var(--mj-bg-surface);\n}\n.cs-slider-row[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n.cs-slider-row[_ngcontent-%COMP%] .cur[_ngcontent-%COMP%] {\n font-family: ui-monospace, monospace;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.cs-validation[_ngcontent-%COMP%] {\n font-size: 12px;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-status-error) 12%, transparent);\n color: var(--mj-status-error-text, var(--mj-status-error));\n border-radius: 4px;\n margin-top: 8px;\n}\n.cs-nudge[_ngcontent-%COMP%] {\n font-size: 12px;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, transparent);\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n border-radius: 4px;\n margin-top: 8px;\n line-height: 1.4;\n}\n\n.cs-toggle-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 0;\n border-top: 1px dashed var(--mj-border-subtle);\n}\n.cs-toggle-row[_ngcontent-%COMP%]:first-child { border-top: 0; padding-top: 0; }\n.cs-toggle-row[_ngcontent-%COMP%] .label[_ngcontent-%COMP%] .t[_ngcontent-%COMP%] { font-size: 13px; font-weight: 600; }\n.cs-toggle-row[_ngcontent-%COMP%] .label[_ngcontent-%COMP%] .d[_ngcontent-%COMP%] { font-size: 11px; color: var(--mj-text-muted); }\n.cs-switch[_ngcontent-%COMP%] {\n position: relative;\n width: 36px; height: 20px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 10px;\n cursor: pointer;\n}\n.cs-switch[_ngcontent-%COMP%]::after {\n content: \"\";\n position: absolute;\n top: 2px; left: 2px;\n width: 16px; height: 16px;\n border-radius: 50%;\n background: var(--mj-bg-surface);\n transition: left 0.15s;\n box-shadow: 0 1px 2px rgba(0,0,0,0.2);\n}\n.cs-switch.on[_ngcontent-%COMP%] { background: var(--mj-brand-primary); }\n.cs-switch.on[_ngcontent-%COMP%]::after { left: 18px; }"] }); }
|
|
@@ -219,7 +219,7 @@ WebsiteCrawlerSettingsPanel = __decorate([
|
|
|
219
219
|
export { WebsiteCrawlerSettingsPanel };
|
|
220
220
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(WebsiteCrawlerSettingsPanel, [{
|
|
221
221
|
type: Component,
|
|
222
|
-
args: [{ standalone: false, selector: 'mj-website-crawler-settings-panel', template: "@if (IsWebsiteSourceType) {\n<mj-collapsible-panel\n SectionKey=\"websiteCrawlerSettings\"\n SectionName=\"Website Crawler Settings\"\n Icon=\"fa fa-globe\"\n [Form]=\"FormComponent\"\n [FormContext]=\"FormContext\">\n\n <div class=\"cs-grid\">\n <div class=\"cs-field\">\n <label>Max depth</label>\n <input class=\"cs-input\" type=\"number\" min=\"0\" max=\"10\" step=\"1\" [disabled]=\"!EditMode\"\n [ngModel]=\"MaxDepthValue ?? ''\"\n (ngModelChange)=\"MaxDepthValue = $event\"\n placeholder=\"2 (default)\" />\n <span class=\"hint\">Recursion ceiling for in-domain links. <code>0</code> = just the start URL. <code>2</code> (default) = root + sections + content pages. Higher values multiply with the 1-second per-page delay.</span>\n </div>\n <div class=\"cs-field\">\n <label>Root URL</label>\n <input class=\"cs-input\" type=\"text\" [disabled]=\"!EditMode\"\n [ngModel]=\"RootURLValue\"\n (ngModelChange)=\"RootURLValue = $event\"\n placeholder=\"derived from start URL\" />\n <span class=\"hint\">URL prefix used for the in-domain check. Leave blank to derive from the parent directory of the seed URL.</span>\n </div>\n </div>\n\n <div class=\"cs-field\" style=\"margin-top: 8px;\">\n <label>URL pattern (regex)</label>\n <input class=\"cs-input\" type=\"text\" [disabled]=\"!EditMode\"\n [ngModel]=\"URLPatternValue\"\n (ngModelChange)=\"URLPatternValue = $event\"\n placeholder=\"e.g. ^https://example\\.com/blog/.*\" />\n @if (URLPatternValidationMessage) {\n <span class=\"cs-validation\"><i class=\"fa-solid fa-circle-exclamation\"></i> {{ URLPatternValidationMessage }}</span>\n } @else {\n <span class=\"hint\">Only URLs matching this regex are added to the visited set. Leave blank to include everything.</span>\n }\n </div>\n\n <div class=\"cs-toggle-row\" style=\"margin-top: 12px;\">\n <div class=\"label\">\n <span class=\"t\">Crawl sites in lower-level domain</span>\n <span class=\"d\">When on (default), the depth-aware recursive crawler runs. Turn off to crawl only the seed page.</span>\n </div>\n <div class=\"cs-switch\" [class.on]=\"CrawlSitesInLowerLevelDomainValue\"\n (click)=\"EditMode ? (CrawlSitesInLowerLevelDomainValue = !CrawlSitesInLowerLevelDomainValue) : null\"></div>\n </div>\n <div class=\"cs-toggle-row\">\n <div class=\"label\">\n <span class=\"t\">Crawl other sites in top-level domain</span>\n <span class=\"d\">When on, also adds sibling-path URLs found on the seed page (single-pass, no recursion). Off by default to avoid accidental fan-out.</span>\n </div>\n <div class=\"cs-switch\" [class.on]=\"CrawlOtherSitesInTopLevelDomainValue\"\n (click)=\"EditMode ? (CrawlOtherSitesInTopLevelDomainValue = !CrawlOtherSitesInTopLevelDomainValue) : null\"></div>\n </div>\n</mj-collapsible-panel>\n}\n", styles: ["/* Tag Pipeline Configuration panel \u2014 dense form for the typed\n IContentSourceConfiguration knobs. The class names are shared with the\n Website Crawler Settings panel (same `cs-*` prefix family) so future\n ContentSource panels stay visually consistent without duplicating styles. */\n\n.cs-section-header {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--mj-text-muted);\n margin: 4px 0 8px;\n font-weight: 700;\n}\n.cs-section-header:not(:first-child) {\n margin-top: 16px;\n}\n.cs-section-header-note {\n text-transform: none;\n letter-spacing: 0;\n color: var(--mj-text-muted);\n font-weight: 400;\n margin-left: 8px;\n}\n\n.cs-mode-grid {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 8px;\n margin: 4px 0 12px;\n}\n.cs-mode-card {\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n border-radius: 8px;\n padding: 10px 12px;\n cursor: pointer;\n text-align: center;\n transition: background 0.12s, border-color 0.12s, box-shadow 0.12s;\n user-select: none;\n}\n.cs-mode-card:hover { background: var(--mj-bg-surface-hover); }\n.cs-mode-card.selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n border-color: var(--mj-brand-primary);\n box-shadow: inset 0 0 0 1px var(--mj-brand-primary);\n}\n.cs-mode-card .ic { font-size: 18px; color: var(--mj-text-secondary); }\n.cs-mode-card.selected .ic { color: var(--mj-brand-primary); }\n.cs-mode-card .nm { font-size: 13px; font-weight: 700; color: var(--mj-text-primary); margin: 4px 0 2px; }\n.cs-mode-card .desc { font-size: 11px; color: var(--mj-text-muted); line-height: 1.3; }\n\n.cs-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 14px 16px;\n margin: 4px 0 12px;\n}\n.cs-grid.four { grid-template-columns: repeat(4, 1fr); }\n.cs-grid.three { grid-template-columns: repeat(3, 1fr); }\n\n/* Primary budget row \u2014 MaxItemsPerRun gets its own emphasized row above\n the dense 4-col grid because it's the most user-intuitive cap. */\n.cs-primary-budget {\n margin: 4px 0 10px;\n padding: 10px 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 4%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 20%, var(--mj-border-default));\n border-radius: 6px;\n}\n.cs-field-primary label { font-size: 13px; color: var(--mj-text-primary); }\n.cs-field-primary .hint { line-height: 1.45; max-width: 78ch; }\n\n.cs-field { display: flex; flex-direction: column; gap: 4px; }\n.cs-field label { font-size: 12px; font-weight: 600; color: var(--mj-text-secondary); }\n.cs-field .hint { font-size: 11px; color: var(--mj-text-muted); }\n\n.cs-input {\n width: 100%;\n box-sizing: border-box;\n padding: 7px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n}\n.cs-input:focus {\n outline: none;\n border-color: var(--mj-border-focus, var(--mj-brand-primary));\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n.cs-input:disabled { opacity: 0.55; cursor: not-allowed; }\n\n.cs-threshold-pair {\n background: var(--mj-bg-surface-card);\n padding: 14px 16px;\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n}\n.cs-slider {\n appearance: none;\n -webkit-appearance: none;\n width: 100%;\n height: 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n margin: 8px 0 4px;\n}\n.cs-slider::-webkit-slider-thumb {\n appearance: none;\n -webkit-appearance: none;\n width: 16px; height: 16px; border-radius: 50%;\n background: var(--mj-brand-primary);\n cursor: pointer;\n border: 2px solid var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0,0,0,0.2);\n}\n.cs-slider::-moz-range-thumb {\n width: 16px; height: 16px; border-radius: 50%;\n background: var(--mj-brand-primary);\n cursor: pointer;\n border: 2px solid var(--mj-bg-surface);\n}\n.cs-slider-row {\n display: flex;\n justify-content: space-between;\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n.cs-slider-row .cur {\n font-family: ui-monospace, monospace;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.cs-validation {\n font-size: 12px;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-status-error) 12%, transparent);\n color: var(--mj-status-error-text, var(--mj-status-error));\n border-radius: 4px;\n margin-top: 8px;\n}\n.cs-nudge {\n font-size: 12px;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, transparent);\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n border-radius: 4px;\n margin-top: 8px;\n line-height: 1.4;\n}\n\n.cs-toggle-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 0;\n border-top: 1px dashed var(--mj-border-subtle);\n}\n.cs-toggle-row:first-child { border-top: 0; padding-top: 0; }\n.cs-toggle-row .label .t { font-size: 13px; font-weight: 600; }\n.cs-toggle-row .label .d { font-size: 11px; color: var(--mj-text-muted); }\n.cs-switch {\n position: relative;\n width: 36px; height: 20px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 10px;\n cursor: pointer;\n}\n.cs-switch::after {\n content: \"\";\n position: absolute;\n top: 2px; left: 2px;\n width: 16px; height: 16px;\n border-radius: 50%;\n background: var(--mj-bg-surface);\n transition: left 0.15s;\n box-shadow: 0 1px 2px rgba(0,0,0,0.2);\n}\n.cs-switch.on { background: var(--mj-brand-primary); }\n.cs-switch.on::after { left: 18px; }\n"] }]
|
|
222
|
+
args: [{ standalone: false, selector: 'mj-website-crawler-settings-panel', template: "@if (IsWebsiteSourceType) {\n<mj-collapsible-panel\n SectionKey=\"websiteCrawlerSettings\"\n [Order]=\"DisplayOrder\"\n SectionName=\"Website Crawler Settings\"\n Icon=\"fa fa-globe\"\n [Form]=\"FormComponent\"\n [FormContext]=\"FormContext\">\n\n <div class=\"cs-grid\">\n <div class=\"cs-field\">\n <label>Max depth</label>\n <input class=\"cs-input\" type=\"number\" min=\"0\" max=\"10\" step=\"1\" [disabled]=\"!EditMode\"\n [ngModel]=\"MaxDepthValue ?? ''\"\n (ngModelChange)=\"MaxDepthValue = $event\"\n placeholder=\"2 (default)\" />\n <span class=\"hint\">Recursion ceiling for in-domain links. <code>0</code> = just the start URL. <code>2</code> (default) = root + sections + content pages. Higher values multiply with the 1-second per-page delay.</span>\n </div>\n <div class=\"cs-field\">\n <label>Root URL</label>\n <input class=\"cs-input\" type=\"text\" [disabled]=\"!EditMode\"\n [ngModel]=\"RootURLValue\"\n (ngModelChange)=\"RootURLValue = $event\"\n placeholder=\"derived from start URL\" />\n <span class=\"hint\">URL prefix used for the in-domain check. Leave blank to derive from the parent directory of the seed URL.</span>\n </div>\n </div>\n\n <div class=\"cs-field\" style=\"margin-top: 8px;\">\n <label>URL pattern (regex)</label>\n <input class=\"cs-input\" type=\"text\" [disabled]=\"!EditMode\"\n [ngModel]=\"URLPatternValue\"\n (ngModelChange)=\"URLPatternValue = $event\"\n placeholder=\"e.g. ^https://example\\.com/blog/.*\" />\n @if (URLPatternValidationMessage) {\n <span class=\"cs-validation\"><i class=\"fa-solid fa-circle-exclamation\"></i> {{ URLPatternValidationMessage }}</span>\n } @else {\n <span class=\"hint\">Only URLs matching this regex are added to the visited set. Leave blank to include everything.</span>\n }\n </div>\n\n <div class=\"cs-toggle-row\" style=\"margin-top: 12px;\">\n <div class=\"label\">\n <span class=\"t\">Crawl sites in lower-level domain</span>\n <span class=\"d\">When on (default), the depth-aware recursive crawler runs. Turn off to crawl only the seed page.</span>\n </div>\n <div class=\"cs-switch\" [class.on]=\"CrawlSitesInLowerLevelDomainValue\"\n (click)=\"EditMode ? (CrawlSitesInLowerLevelDomainValue = !CrawlSitesInLowerLevelDomainValue) : null\"></div>\n </div>\n <div class=\"cs-toggle-row\">\n <div class=\"label\">\n <span class=\"t\">Crawl other sites in top-level domain</span>\n <span class=\"d\">When on, also adds sibling-path URLs found on the seed page (single-pass, no recursion). Off by default to avoid accidental fan-out.</span>\n </div>\n <div class=\"cs-switch\" [class.on]=\"CrawlOtherSitesInTopLevelDomainValue\"\n (click)=\"EditMode ? (CrawlOtherSitesInTopLevelDomainValue = !CrawlOtherSitesInTopLevelDomainValue) : null\"></div>\n </div>\n</mj-collapsible-panel>\n}\n", styles: ["/* Tag Pipeline Configuration panel \u2014 dense form for the typed\n IContentSourceConfiguration knobs. The class names are shared with the\n Website Crawler Settings panel (same `cs-*` prefix family) so future\n ContentSource panels stay visually consistent without duplicating styles. */\n\n.cs-section-header {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--mj-text-muted);\n margin: 4px 0 8px;\n font-weight: 700;\n}\n.cs-section-header:not(:first-child) {\n margin-top: 16px;\n}\n.cs-section-header-note {\n text-transform: none;\n letter-spacing: 0;\n color: var(--mj-text-muted);\n font-weight: 400;\n margin-left: 8px;\n}\n\n.cs-mode-grid {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 8px;\n margin: 4px 0 12px;\n}\n.cs-mode-card {\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n border-radius: 8px;\n padding: 10px 12px;\n cursor: pointer;\n text-align: center;\n transition: background 0.12s, border-color 0.12s, box-shadow 0.12s;\n user-select: none;\n}\n.cs-mode-card:hover { background: var(--mj-bg-surface-hover); }\n.cs-mode-card.selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n border-color: var(--mj-brand-primary);\n box-shadow: inset 0 0 0 1px var(--mj-brand-primary);\n}\n.cs-mode-card .ic { font-size: 18px; color: var(--mj-text-secondary); }\n.cs-mode-card.selected .ic { color: var(--mj-brand-primary); }\n.cs-mode-card .nm { font-size: 13px; font-weight: 700; color: var(--mj-text-primary); margin: 4px 0 2px; }\n.cs-mode-card .desc { font-size: 11px; color: var(--mj-text-muted); line-height: 1.3; }\n\n.cs-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 14px 16px;\n margin: 4px 0 12px;\n}\n.cs-grid.four { grid-template-columns: repeat(4, 1fr); }\n.cs-grid.three { grid-template-columns: repeat(3, 1fr); }\n\n/* Primary budget row \u2014 MaxItemsPerRun gets its own emphasized row above\n the dense 4-col grid because it's the most user-intuitive cap. */\n.cs-primary-budget {\n margin: 4px 0 10px;\n padding: 10px 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 4%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 20%, var(--mj-border-default));\n border-radius: 6px;\n}\n.cs-field-primary label { font-size: 13px; color: var(--mj-text-primary); }\n.cs-field-primary .hint { line-height: 1.45; max-width: 78ch; }\n\n.cs-field { display: flex; flex-direction: column; gap: 4px; }\n.cs-field label { font-size: 12px; font-weight: 600; color: var(--mj-text-secondary); }\n.cs-field .hint { font-size: 11px; color: var(--mj-text-muted); }\n\n.cs-input {\n width: 100%;\n box-sizing: border-box;\n padding: 7px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n}\n.cs-input:focus {\n outline: none;\n border-color: var(--mj-border-focus, var(--mj-brand-primary));\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n.cs-input:disabled { opacity: 0.55; cursor: not-allowed; }\n\n.cs-threshold-pair {\n background: var(--mj-bg-surface-card);\n padding: 14px 16px;\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n}\n.cs-slider {\n appearance: none;\n -webkit-appearance: none;\n width: 100%;\n height: 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n margin: 8px 0 4px;\n}\n.cs-slider::-webkit-slider-thumb {\n appearance: none;\n -webkit-appearance: none;\n width: 16px; height: 16px; border-radius: 50%;\n background: var(--mj-brand-primary);\n cursor: pointer;\n border: 2px solid var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0,0,0,0.2);\n}\n.cs-slider::-moz-range-thumb {\n width: 16px; height: 16px; border-radius: 50%;\n background: var(--mj-brand-primary);\n cursor: pointer;\n border: 2px solid var(--mj-bg-surface);\n}\n.cs-slider-row {\n display: flex;\n justify-content: space-between;\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n.cs-slider-row .cur {\n font-family: ui-monospace, monospace;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.cs-validation {\n font-size: 12px;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-status-error) 12%, transparent);\n color: var(--mj-status-error-text, var(--mj-status-error));\n border-radius: 4px;\n margin-top: 8px;\n}\n.cs-nudge {\n font-size: 12px;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, transparent);\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n border-radius: 4px;\n margin-top: 8px;\n line-height: 1.4;\n}\n\n.cs-toggle-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 0;\n border-top: 1px dashed var(--mj-border-subtle);\n}\n.cs-toggle-row:first-child { border-top: 0; padding-top: 0; }\n.cs-toggle-row .label .t { font-size: 13px; font-weight: 600; }\n.cs-toggle-row .label .d { font-size: 11px; color: var(--mj-text-muted); }\n.cs-switch {\n position: relative;\n width: 36px; height: 20px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 10px;\n cursor: pointer;\n}\n.cs-switch::after {\n content: \"\";\n position: absolute;\n top: 2px; left: 2px;\n width: 16px; height: 16px;\n border-radius: 50%;\n background: var(--mj-bg-surface);\n transition: left 0.15s;\n box-shadow: 0 1px 2px rgba(0,0,0,0.2);\n}\n.cs-switch.on { background: var(--mj-brand-primary); }\n.cs-switch.on::after { left: 18px; }\n"] }]
|
|
223
223
|
}], null, null); })();
|
|
224
224
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(WebsiteCrawlerSettingsPanel, { className: "WebsiteCrawlerSettingsPanel", filePath: "src/lib/panels/content-sources/website-crawler-settings.panel.ts", lineNumber: 38 }); })();
|
|
225
225
|
/** Tree-shake guard — call this from the consuming module's loader. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"website-crawler-settings.panel.js","sourceRoot":"","sources":["../../../../src/lib/panels/content-sources/website-crawler-settings.panel.ts","../../../../src/lib/panels/content-sources/website-crawler-settings.panel.html"],"names":[],"mappings":"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","sourcesContent":["import { Component } from '@angular/core';\nimport { RegisterClassEx } from '@memberjunction/global';\nimport { BaseFormPanel } from '@memberjunction/ng-base-forms';\nimport {\n MJContentSourceEntity,\n MJContentSourceEntity_IContentSourceConfiguration,\n MJContentSourceEntity_IContentSourceWebsiteConfiguration,\n} from '@memberjunction/core-entities';\n\n/**\n * Website Crawler Settings panel — surfaces the typed `Configuration.Website`\n * sub-object (MaxDepth, RootURL, URLPattern, crawl flags) as a dense form.\n * Only meaningful when ContentSourceType = \"Website\"; the panel silently\n * renders nothing for other source types so it can register against the\n * generic ContentSource slot without conditional templates upstream.\n *\n * Future pluggability: as more source types grow typed config (RSS, Cloud\n * Storage, etc.), each gets its own panel registered against the same slot,\n * each self-gating on ContentSourceType. The slot host doesn't need to know.\n */\n@RegisterClassEx(BaseFormPanel, {\n key: 'content-sources:website-crawler-settings',\n skipNullKeyWarning: true,\n metadata: {\n entity: 'MJ: Content Sources',\n slot: 'after-fields',\n // Lower sortKey than Tag Pipeline (100) so the source-type-specific\n // crawler knobs render BELOW the broadly-applicable budget knobs.\n sortKey: 80,\n },\n})\n@Component({\n standalone: false,\n selector: 'mj-website-crawler-settings-panel',\n templateUrl: './website-crawler-settings.panel.html',\n styleUrls: ['./tag-pipeline-configuration.panel.css'],\n})\nexport class WebsiteCrawlerSettingsPanel extends BaseFormPanel<MJContentSourceEntity> {\n /** Hide the panel for non-Website source types — keeps the slot registration generic. */\n public get IsWebsiteSourceType(): boolean {\n const typeName = this.Record?.ContentSourceType;\n return typeName != null && typeName.trim().toLowerCase() === 'website';\n }\n\n private get config(): MJContentSourceEntity_IContentSourceConfiguration {\n return this.Record?.ConfigurationObject ?? {};\n }\n\n /** Return the typed Website sub-object, defaulted to {} so getters can read freely. */\n public get WebsiteConfig(): MJContentSourceEntity_IContentSourceWebsiteConfiguration {\n return this.config.Website ?? {};\n }\n\n private setConfig(patch: Partial<MJContentSourceEntity_IContentSourceConfiguration>): void {\n if (!this.Record) return;\n const current = this.Record.ConfigurationObject ?? {};\n const merged: MJContentSourceEntity_IContentSourceConfiguration = { ...current, ...patch };\n this.Record.ConfigurationObject = merged;\n }\n\n private setWebsite(patch: Partial<MJContentSourceEntity_IContentSourceWebsiteConfiguration>): void {\n // Spread for the typed merge, then explicitly remove keys whose patched\n // value was undefined so we don't persist `\"key\": undefined` artifacts.\n const merged: MJContentSourceEntity_IContentSourceWebsiteConfiguration = { ...this.WebsiteConfig, ...patch };\n for (const key of Object.keys(patch) as Array<keyof MJContentSourceEntity_IContentSourceWebsiteConfiguration>) {\n if (patch[key] === undefined) {\n delete merged[key];\n }\n }\n this.setConfig({ Website: merged });\n }\n\n public get MaxDepthValue(): number | null {\n return this.WebsiteConfig.MaxDepth ?? null;\n }\n public set MaxDepthValue(v: number | string | null) {\n this.setWebsite({ MaxDepth: this.normalizeNullableNumber(v) });\n }\n\n public get CrawlSitesInLowerLevelDomainValue(): boolean {\n // Default true — matches the autotagger's runtime default.\n return this.WebsiteConfig.CrawlSitesInLowerLevelDomain !== false;\n }\n public set CrawlSitesInLowerLevelDomainValue(v: boolean) {\n this.setWebsite({ CrawlSitesInLowerLevelDomain: v });\n }\n\n public get CrawlOtherSitesInTopLevelDomainValue(): boolean {\n // Default false — matches the autotagger's runtime default.\n return this.WebsiteConfig.CrawlOtherSitesInTopLevelDomain === true;\n }\n public set CrawlOtherSitesInTopLevelDomainValue(v: boolean) {\n this.setWebsite({ CrawlOtherSitesInTopLevelDomain: v });\n }\n\n public get URLPatternValue(): string {\n return this.WebsiteConfig.URLPattern ?? '';\n }\n public set URLPatternValue(v: string | null | undefined) {\n const trimmed = (v ?? '').trim();\n this.setWebsite({ URLPattern: trimmed === '' ? undefined : trimmed });\n }\n\n public get RootURLValue(): string {\n return this.WebsiteConfig.RootURL ?? '';\n }\n public set RootURLValue(v: string | null | undefined) {\n const trimmed = (v ?? '').trim();\n this.setWebsite({ RootURL: trimmed === '' ? undefined : trimmed });\n }\n\n /** Live validation: a non-empty URLPattern must be a valid JavaScript regex. */\n public get URLPatternValidationMessage(): string | null {\n const v = this.URLPatternValue;\n if (!v) return null;\n try { new RegExp(v); return null; }\n catch (e) { return `Invalid regex — ${e instanceof Error ? e.message : String(e)}`; }\n }\n\n private normalizeNullableNumber(v: number | string | null | undefined): number | undefined {\n if (v == null) return undefined;\n if (typeof v === 'string') {\n const trimmed = v.trim();\n if (trimmed === '') return undefined;\n const n = Number(trimmed);\n return Number.isFinite(n) ? n : undefined;\n }\n return Number.isFinite(v) ? v : undefined;\n }\n}\n\n/** Tree-shake guard — call this from the consuming module's loader. */\nexport function LoadWebsiteCrawlerSettingsPanel(): void { /* no-op marker */ }\n","@if (IsWebsiteSourceType) {\n<mj-collapsible-panel\n SectionKey=\"websiteCrawlerSettings\"\n SectionName=\"Website Crawler Settings\"\n Icon=\"fa fa-globe\"\n [Form]=\"FormComponent\"\n [FormContext]=\"FormContext\">\n\n <div class=\"cs-grid\">\n <div class=\"cs-field\">\n <label>Max depth</label>\n <input class=\"cs-input\" type=\"number\" min=\"0\" max=\"10\" step=\"1\" [disabled]=\"!EditMode\"\n [ngModel]=\"MaxDepthValue ?? ''\"\n (ngModelChange)=\"MaxDepthValue = $event\"\n placeholder=\"2 (default)\" />\n <span class=\"hint\">Recursion ceiling for in-domain links. <code>0</code> = just the start URL. <code>2</code> (default) = root + sections + content pages. Higher values multiply with the 1-second per-page delay.</span>\n </div>\n <div class=\"cs-field\">\n <label>Root URL</label>\n <input class=\"cs-input\" type=\"text\" [disabled]=\"!EditMode\"\n [ngModel]=\"RootURLValue\"\n (ngModelChange)=\"RootURLValue = $event\"\n placeholder=\"derived from start URL\" />\n <span class=\"hint\">URL prefix used for the in-domain check. Leave blank to derive from the parent directory of the seed URL.</span>\n </div>\n </div>\n\n <div class=\"cs-field\" style=\"margin-top: 8px;\">\n <label>URL pattern (regex)</label>\n <input class=\"cs-input\" type=\"text\" [disabled]=\"!EditMode\"\n [ngModel]=\"URLPatternValue\"\n (ngModelChange)=\"URLPatternValue = $event\"\n placeholder=\"e.g. ^https://example\\.com/blog/.*\" />\n @if (URLPatternValidationMessage) {\n <span class=\"cs-validation\"><i class=\"fa-solid fa-circle-exclamation\"></i> {{ URLPatternValidationMessage }}</span>\n } @else {\n <span class=\"hint\">Only URLs matching this regex are added to the visited set. Leave blank to include everything.</span>\n }\n </div>\n\n <div class=\"cs-toggle-row\" style=\"margin-top: 12px;\">\n <div class=\"label\">\n <span class=\"t\">Crawl sites in lower-level domain</span>\n <span class=\"d\">When on (default), the depth-aware recursive crawler runs. Turn off to crawl only the seed page.</span>\n </div>\n <div class=\"cs-switch\" [class.on]=\"CrawlSitesInLowerLevelDomainValue\"\n (click)=\"EditMode ? (CrawlSitesInLowerLevelDomainValue = !CrawlSitesInLowerLevelDomainValue) : null\"></div>\n </div>\n <div class=\"cs-toggle-row\">\n <div class=\"label\">\n <span class=\"t\">Crawl other sites in top-level domain</span>\n <span class=\"d\">When on, also adds sibling-path URLs found on the seed page (single-pass, no recursion). Off by default to avoid accidental fan-out.</span>\n </div>\n <div class=\"cs-switch\" [class.on]=\"CrawlOtherSitesInTopLevelDomainValue\"\n (click)=\"EditMode ? (CrawlOtherSitesInTopLevelDomainValue = !CrawlOtherSitesInTopLevelDomainValue) : null\"></div>\n </div>\n</mj-collapsible-panel>\n}\n"]}
|
|
1
|
+
{"version":3,"file":"website-crawler-settings.panel.js","sourceRoot":"","sources":["../../../../src/lib/panels/content-sources/website-crawler-settings.panel.ts","../../../../src/lib/panels/content-sources/website-crawler-settings.panel.html"],"names":[],"mappings":"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","sourcesContent":["import { Component } from '@angular/core';\nimport { RegisterClassEx } from '@memberjunction/global';\nimport { BaseFormPanel } from '@memberjunction/ng-base-forms';\nimport {\n MJContentSourceEntity,\n MJContentSourceEntity_IContentSourceConfiguration,\n MJContentSourceEntity_IContentSourceWebsiteConfiguration,\n} from '@memberjunction/core-entities';\n\n/**\n * Website Crawler Settings panel — surfaces the typed `Configuration.Website`\n * sub-object (MaxDepth, RootURL, URLPattern, crawl flags) as a dense form.\n * Only meaningful when ContentSourceType = \"Website\"; the panel silently\n * renders nothing for other source types so it can register against the\n * generic ContentSource slot without conditional templates upstream.\n *\n * Future pluggability: as more source types grow typed config (RSS, Cloud\n * Storage, etc.), each gets its own panel registered against the same slot,\n * each self-gating on ContentSourceType. The slot host doesn't need to know.\n */\n@RegisterClassEx(BaseFormPanel, {\n key: 'content-sources:website-crawler-settings',\n skipNullKeyWarning: true,\n metadata: {\n entity: 'MJ: Content Sources',\n slot: 'after-fields',\n // Lower sortKey than Tag Pipeline (100) so the source-type-specific\n // crawler knobs render BELOW the broadly-applicable budget knobs.\n sortKey: 80,\n },\n})\n@Component({\n standalone: false,\n selector: 'mj-website-crawler-settings-panel',\n templateUrl: './website-crawler-settings.panel.html',\n styleUrls: ['./tag-pipeline-configuration.panel.css'],\n})\nexport class WebsiteCrawlerSettingsPanel extends BaseFormPanel<MJContentSourceEntity> {\n /** Hide the panel for non-Website source types — keeps the slot registration generic. */\n public get IsWebsiteSourceType(): boolean {\n const typeName = this.Record?.ContentSourceType;\n return typeName != null && typeName.trim().toLowerCase() === 'website';\n }\n\n private get config(): MJContentSourceEntity_IContentSourceConfiguration {\n return this.Record?.ConfigurationObject ?? {};\n }\n\n /** Return the typed Website sub-object, defaulted to {} so getters can read freely. */\n public get WebsiteConfig(): MJContentSourceEntity_IContentSourceWebsiteConfiguration {\n return this.config.Website ?? {};\n }\n\n private setConfig(patch: Partial<MJContentSourceEntity_IContentSourceConfiguration>): void {\n if (!this.Record) return;\n const current = this.Record.ConfigurationObject ?? {};\n const merged: MJContentSourceEntity_IContentSourceConfiguration = { ...current, ...patch };\n this.Record.ConfigurationObject = merged;\n }\n\n private setWebsite(patch: Partial<MJContentSourceEntity_IContentSourceWebsiteConfiguration>): void {\n // Spread for the typed merge, then explicitly remove keys whose patched\n // value was undefined so we don't persist `\"key\": undefined` artifacts.\n const merged: MJContentSourceEntity_IContentSourceWebsiteConfiguration = { ...this.WebsiteConfig, ...patch };\n for (const key of Object.keys(patch) as Array<keyof MJContentSourceEntity_IContentSourceWebsiteConfiguration>) {\n if (patch[key] === undefined) {\n delete merged[key];\n }\n }\n this.setConfig({ Website: merged });\n }\n\n public get MaxDepthValue(): number | null {\n return this.WebsiteConfig.MaxDepth ?? null;\n }\n public set MaxDepthValue(v: number | string | null) {\n this.setWebsite({ MaxDepth: this.normalizeNullableNumber(v) });\n }\n\n public get CrawlSitesInLowerLevelDomainValue(): boolean {\n // Default true — matches the autotagger's runtime default.\n return this.WebsiteConfig.CrawlSitesInLowerLevelDomain !== false;\n }\n public set CrawlSitesInLowerLevelDomainValue(v: boolean) {\n this.setWebsite({ CrawlSitesInLowerLevelDomain: v });\n }\n\n public get CrawlOtherSitesInTopLevelDomainValue(): boolean {\n // Default false — matches the autotagger's runtime default.\n return this.WebsiteConfig.CrawlOtherSitesInTopLevelDomain === true;\n }\n public set CrawlOtherSitesInTopLevelDomainValue(v: boolean) {\n this.setWebsite({ CrawlOtherSitesInTopLevelDomain: v });\n }\n\n public get URLPatternValue(): string {\n return this.WebsiteConfig.URLPattern ?? '';\n }\n public set URLPatternValue(v: string | null | undefined) {\n const trimmed = (v ?? '').trim();\n this.setWebsite({ URLPattern: trimmed === '' ? undefined : trimmed });\n }\n\n public get RootURLValue(): string {\n return this.WebsiteConfig.RootURL ?? '';\n }\n public set RootURLValue(v: string | null | undefined) {\n const trimmed = (v ?? '').trim();\n this.setWebsite({ RootURL: trimmed === '' ? undefined : trimmed });\n }\n\n /** Live validation: a non-empty URLPattern must be a valid JavaScript regex. */\n public get URLPatternValidationMessage(): string | null {\n const v = this.URLPatternValue;\n if (!v) return null;\n try { new RegExp(v); return null; }\n catch (e) { return `Invalid regex — ${e instanceof Error ? e.message : String(e)}`; }\n }\n\n private normalizeNullableNumber(v: number | string | null | undefined): number | undefined {\n if (v == null) return undefined;\n if (typeof v === 'string') {\n const trimmed = v.trim();\n if (trimmed === '') return undefined;\n const n = Number(trimmed);\n return Number.isFinite(n) ? n : undefined;\n }\n return Number.isFinite(v) ? v : undefined;\n }\n}\n\n/** Tree-shake guard — call this from the consuming module's loader. */\nexport function LoadWebsiteCrawlerSettingsPanel(): void { /* no-op marker */ }\n","@if (IsWebsiteSourceType) {\n<mj-collapsible-panel\n SectionKey=\"websiteCrawlerSettings\"\n [Order]=\"DisplayOrder\"\n SectionName=\"Website Crawler Settings\"\n Icon=\"fa fa-globe\"\n [Form]=\"FormComponent\"\n [FormContext]=\"FormContext\">\n\n <div class=\"cs-grid\">\n <div class=\"cs-field\">\n <label>Max depth</label>\n <input class=\"cs-input\" type=\"number\" min=\"0\" max=\"10\" step=\"1\" [disabled]=\"!EditMode\"\n [ngModel]=\"MaxDepthValue ?? ''\"\n (ngModelChange)=\"MaxDepthValue = $event\"\n placeholder=\"2 (default)\" />\n <span class=\"hint\">Recursion ceiling for in-domain links. <code>0</code> = just the start URL. <code>2</code> (default) = root + sections + content pages. Higher values multiply with the 1-second per-page delay.</span>\n </div>\n <div class=\"cs-field\">\n <label>Root URL</label>\n <input class=\"cs-input\" type=\"text\" [disabled]=\"!EditMode\"\n [ngModel]=\"RootURLValue\"\n (ngModelChange)=\"RootURLValue = $event\"\n placeholder=\"derived from start URL\" />\n <span class=\"hint\">URL prefix used for the in-domain check. Leave blank to derive from the parent directory of the seed URL.</span>\n </div>\n </div>\n\n <div class=\"cs-field\" style=\"margin-top: 8px;\">\n <label>URL pattern (regex)</label>\n <input class=\"cs-input\" type=\"text\" [disabled]=\"!EditMode\"\n [ngModel]=\"URLPatternValue\"\n (ngModelChange)=\"URLPatternValue = $event\"\n placeholder=\"e.g. ^https://example\\.com/blog/.*\" />\n @if (URLPatternValidationMessage) {\n <span class=\"cs-validation\"><i class=\"fa-solid fa-circle-exclamation\"></i> {{ URLPatternValidationMessage }}</span>\n } @else {\n <span class=\"hint\">Only URLs matching this regex are added to the visited set. Leave blank to include everything.</span>\n }\n </div>\n\n <div class=\"cs-toggle-row\" style=\"margin-top: 12px;\">\n <div class=\"label\">\n <span class=\"t\">Crawl sites in lower-level domain</span>\n <span class=\"d\">When on (default), the depth-aware recursive crawler runs. Turn off to crawl only the seed page.</span>\n </div>\n <div class=\"cs-switch\" [class.on]=\"CrawlSitesInLowerLevelDomainValue\"\n (click)=\"EditMode ? (CrawlSitesInLowerLevelDomainValue = !CrawlSitesInLowerLevelDomainValue) : null\"></div>\n </div>\n <div class=\"cs-toggle-row\">\n <div class=\"label\">\n <span class=\"t\">Crawl other sites in top-level domain</span>\n <span class=\"d\">When on, also adds sibling-path URLs found on the seed page (single-pass, no recursion). Off by default to avoid accidental fan-out.</span>\n </div>\n <div class=\"cs-switch\" [class.on]=\"CrawlOtherSitesInTopLevelDomainValue\"\n (click)=\"EditMode ? (CrawlOtherSitesInTopLevelDomainValue = !CrawlOtherSitesInTopLevelDomainValue) : null\"></div>\n </div>\n</mj-collapsible-panel>\n}\n"]}
|
|
@@ -51,7 +51,7 @@ let EntityRelationshipFormRolePanel = class EntityRelationshipFormRolePanel exte
|
|
|
51
51
|
this.Record.ConfigurationObject = Object.keys(next).length === 0 ? null : next;
|
|
52
52
|
}
|
|
53
53
|
static { this.ɵfac = /*@__PURE__*/ (() => { let ɵEntityRelationshipFormRolePanel_BaseFactory; return function EntityRelationshipFormRolePanel_Factory(__ngFactoryType__) { return (ɵEntityRelationshipFormRolePanel_BaseFactory || (ɵEntityRelationshipFormRolePanel_BaseFactory = i0.ɵɵgetInheritedFactory(EntityRelationshipFormRolePanel)))(__ngFactoryType__ || EntityRelationshipFormRolePanel); }; })(); }
|
|
54
|
-
static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: EntityRelationshipFormRolePanel, selectors: [["mj-entity-relationship-form-role-panel"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 8, vars:
|
|
54
|
+
static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: EntityRelationshipFormRolePanel, selectors: [["mj-entity-relationship-form-role-panel"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 8, vars: 7, consts: [["SectionKey", "formChrome", "SectionName", "Form chrome", "Icon", "fa-solid fa-table-columns", 3, "Order", "Form", "FormContext"], [1, "mj-form-chrome-editor"], [1, "mj-form-chrome-reason"], [1, "mj-form-chrome-field"], ["TextField", "text", "ValueField", "value", 3, "ngModelChange", "Data", "ValuePrimitive", "ngModel", "Disabled"]], template: function EntityRelationshipFormRolePanel_Template(rf, ctx) { if (rf & 1) {
|
|
55
55
|
i0.ɵɵelementStart(0, "mj-collapsible-panel", 0)(1, "div", 1)(2, "p", 2);
|
|
56
56
|
i0.ɵɵtext(3, " Weight of this relationship on the parent form. Auto uses the parent's smart ranker (same-schema children stay top-level; cross-schema hang-ons fold into More once the budget is exceeded). ");
|
|
57
57
|
i0.ɵɵelementEnd();
|
|
@@ -62,7 +62,7 @@ let EntityRelationshipFormRolePanel = class EntityRelationshipFormRolePanel exte
|
|
|
62
62
|
i0.ɵɵlistener("ngModelChange", function EntityRelationshipFormRolePanel_Template_mj_dropdown_ngModelChange_7_listener($event) { return ctx.OnRoleChange($event); });
|
|
63
63
|
i0.ɵɵelementEnd()()()();
|
|
64
64
|
} if (rf & 2) {
|
|
65
|
-
i0.ɵɵproperty("Form", ctx.FormComponent)("FormContext", ctx.FormContext);
|
|
65
|
+
i0.ɵɵproperty("Order", ctx.DisplayOrder)("Form", ctx.FormComponent)("FormContext", ctx.FormContext);
|
|
66
66
|
i0.ɵɵadvance(7);
|
|
67
67
|
i0.ɵɵproperty("Data", ctx.Choices)("ValuePrimitive", true)("ngModel", ctx.FormRole)("Disabled", !ctx.EditMode);
|
|
68
68
|
} }, dependencies: [i1.NgControlStatus, i1.NgModel, i2.MJDropdownComponent, i3.MjCollapsiblePanelComponent], styles: [".mj-form-chrome-editor[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.mj-form-chrome-knobs[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 12px 16px;\n}\n\n.mj-form-chrome-field[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n font-weight: var(--mj-font-semibold);\n}\n\n.mj-form-chrome-summary[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.mj-form-chrome-pill[_ngcontent-%COMP%] {\n padding: 2px 10px;\n border-radius: var(--mj-radius-full);\n font-size: var(--mj-text-xs);\n background: color-mix(in srgb, var(--mj-status-success) 14%, var(--mj-bg-surface));\n color: var(--mj-status-success-text);\n}\n\n.mj-form-chrome-pill.is-detail[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.mj-form-chrome-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--mj-text-sm);\n}\n\n.mj-form-chrome-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%], \n.mj-form-chrome-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 8px 10px;\n text-align: left;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.mj-form-chrome-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-weight: var(--mj-font-semibold);\n font-size: var(--mj-text-xs);\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n.mj-form-chrome-table[_ngcontent-%COMP%] tr.is-detail[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.mj-form-chrome-role[_ngcontent-%COMP%] {\n font-weight: var(--mj-font-semibold);\n color: var(--mj-status-success-text);\n}\n\n.mj-form-chrome-role.is-detail[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n.mj-form-chrome-reason[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-family: var(--mj-font-mono, monospace);\n font-size: var(--mj-text-xs);\n}\n\n.mj-form-chrome-score[_ngcontent-%COMP%] {\n font-variant-numeric: tabular-nums;\n}"] }); }
|
|
@@ -81,7 +81,7 @@ EntityRelationshipFormRolePanel = __decorate([
|
|
|
81
81
|
export { EntityRelationshipFormRolePanel };
|
|
82
82
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(EntityRelationshipFormRolePanel, [{
|
|
83
83
|
type: Component,
|
|
84
|
-
args: [{ standalone: false, selector: 'mj-entity-relationship-form-role-panel', template: "<mj-collapsible-panel\n SectionKey=\"formChrome\"\n SectionName=\"Form chrome\"\n Icon=\"fa-solid fa-table-columns\"\n [Form]=\"FormComponent\"\n [FormContext]=\"FormContext\">\n <div class=\"mj-form-chrome-editor\">\n <p class=\"mj-form-chrome-reason\">\n Weight of this relationship on the parent form. Auto uses the parent's\n smart ranker (same-schema children stay top-level; cross-schema hang-ons\n fold into More once the budget is exceeded).\n </p>\n <label class=\"mj-form-chrome-field\">\n <span>Form role</span>\n <mj-dropdown\n [Data]=\"Choices\"\n TextField=\"text\"\n ValueField=\"value\"\n [ValuePrimitive]=\"true\"\n [ngModel]=\"FormRole\"\n [Disabled]=\"!EditMode\"\n (ngModelChange)=\"OnRoleChange($event)\">\n </mj-dropdown>\n </label>\n </div>\n</mj-collapsible-panel>\n", styles: [".mj-form-chrome-editor {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.mj-form-chrome-knobs {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 12px 16px;\n}\n\n.mj-form-chrome-field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n font-weight: var(--mj-font-semibold);\n}\n\n.mj-form-chrome-summary {\n display: flex;\n gap: 8px;\n}\n\n.mj-form-chrome-pill {\n padding: 2px 10px;\n border-radius: var(--mj-radius-full);\n font-size: var(--mj-text-xs);\n background: color-mix(in srgb, var(--mj-status-success) 14%, var(--mj-bg-surface));\n color: var(--mj-status-success-text);\n}\n\n.mj-form-chrome-pill.is-detail {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.mj-form-chrome-table {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--mj-text-sm);\n}\n\n.mj-form-chrome-table th,\n.mj-form-chrome-table td {\n padding: 8px 10px;\n text-align: left;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.mj-form-chrome-table th {\n color: var(--mj-text-muted);\n font-weight: var(--mj-font-semibold);\n font-size: var(--mj-text-xs);\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n.mj-form-chrome-table tr.is-detail td {\n color: var(--mj-text-secondary);\n}\n\n.mj-form-chrome-role {\n font-weight: var(--mj-font-semibold);\n color: var(--mj-status-success-text);\n}\n\n.mj-form-chrome-role.is-detail {\n color: var(--mj-text-muted);\n}\n\n.mj-form-chrome-reason {\n color: var(--mj-text-muted);\n font-family: var(--mj-font-mono, monospace);\n font-size: var(--mj-text-xs);\n}\n\n.mj-form-chrome-score {\n font-variant-numeric: tabular-nums;\n}\n"] }]
|
|
84
|
+
args: [{ standalone: false, selector: 'mj-entity-relationship-form-role-panel', template: "<mj-collapsible-panel\n SectionKey=\"formChrome\"\n [Order]=\"DisplayOrder\"\n SectionName=\"Form chrome\"\n Icon=\"fa-solid fa-table-columns\"\n [Form]=\"FormComponent\"\n [FormContext]=\"FormContext\">\n <div class=\"mj-form-chrome-editor\">\n <p class=\"mj-form-chrome-reason\">\n Weight of this relationship on the parent form. Auto uses the parent's\n smart ranker (same-schema children stay top-level; cross-schema hang-ons\n fold into More once the budget is exceeded).\n </p>\n <label class=\"mj-form-chrome-field\">\n <span>Form role</span>\n <mj-dropdown\n [Data]=\"Choices\"\n TextField=\"text\"\n ValueField=\"value\"\n [ValuePrimitive]=\"true\"\n [ngModel]=\"FormRole\"\n [Disabled]=\"!EditMode\"\n (ngModelChange)=\"OnRoleChange($event)\">\n </mj-dropdown>\n </label>\n </div>\n</mj-collapsible-panel>\n", styles: [".mj-form-chrome-editor {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.mj-form-chrome-knobs {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 12px 16px;\n}\n\n.mj-form-chrome-field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n font-weight: var(--mj-font-semibold);\n}\n\n.mj-form-chrome-summary {\n display: flex;\n gap: 8px;\n}\n\n.mj-form-chrome-pill {\n padding: 2px 10px;\n border-radius: var(--mj-radius-full);\n font-size: var(--mj-text-xs);\n background: color-mix(in srgb, var(--mj-status-success) 14%, var(--mj-bg-surface));\n color: var(--mj-status-success-text);\n}\n\n.mj-form-chrome-pill.is-detail {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.mj-form-chrome-table {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--mj-text-sm);\n}\n\n.mj-form-chrome-table th,\n.mj-form-chrome-table td {\n padding: 8px 10px;\n text-align: left;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.mj-form-chrome-table th {\n color: var(--mj-text-muted);\n font-weight: var(--mj-font-semibold);\n font-size: var(--mj-text-xs);\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n.mj-form-chrome-table tr.is-detail td {\n color: var(--mj-text-secondary);\n}\n\n.mj-form-chrome-role {\n font-weight: var(--mj-font-semibold);\n color: var(--mj-status-success-text);\n}\n\n.mj-form-chrome-role.is-detail {\n color: var(--mj-text-muted);\n}\n\n.mj-form-chrome-reason {\n color: var(--mj-text-muted);\n font-family: var(--mj-font-mono, monospace);\n font-size: var(--mj-text-xs);\n}\n\n.mj-form-chrome-score {\n font-variant-numeric: tabular-nums;\n}\n"] }]
|
|
85
85
|
}], null, null); })();
|
|
86
86
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(EntityRelationshipFormRolePanel, { className: "EntityRelationshipFormRolePanel", filePath: "src/lib/panels/form-chrome/entity-relationship-form-role.panel.ts", lineNumber: 30 }); })();
|
|
87
87
|
//# sourceMappingURL=entity-relationship-form-role.panel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity-relationship-form-role.panel.js","sourceRoot":"","sources":["../../../../src/lib/panels/form-chrome/entity-relationship-form-role.panel.ts","../../../../src/lib/panels/form-chrome/entity-relationship-form-role.panel.html"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;;;;;AAQ9D;;;GAGG;AAgBI,IAAM,+BAA+B,GAArC,MAAM,+BAAgC,SAAQ,aAAyC;IAAvF;;QACa,YAAO,GAA8C;YACjE,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,MAAM,EAAE;YAC/C,EAAE,IAAI,EAAE,4BAA4B,EAAE,KAAK,EAAE,SAAS,EAAE;YACxD,EAAE,IAAI,EAAE,yBAAyB,EAAE,KAAK,EAAE,QAAQ,EAAE;SACvD,CAAC;KA0BL;IAxBG,IAAW,QAAQ;QACf,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,mBAAmB,EAAE,EAAE,EAAE,QAAQ,CAAC;QAC5D,OAAO,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;IACnE,CAAC;IAEM,YAAY,CAAC,KAA+B;QAC/C,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,QAAQ;YAAE,OAAO;QAC1E,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QACzB,MAAM,OAAO,GACT,IAAI,CAAC,MAAM,CAAC,mBAAmB,IAAI,EAAE,CAAC;QAC1C,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QACrC,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;YACnB,OAAO,EAAE,CAAC,QAAQ,CAAC;QACvB,CAAC;aAAM,CAAC;YACJ,EAAE,CAAC,QAAQ,GAAG,KAAK,CAAC;QACxB,CAAC;QACD,MAAM,IAAI,GAAgE,EAAE,GAAG,OAAO,EAAE,CAAC;QACzF,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC,EAAE,CAAC;QACnB,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACjB,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,mBAAmB,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACnF,CAAC;gTA9BQ,+BAA+B,yBAA/B,+BAA+B;oEAA/B,+BAA+B;
|
|
1
|
+
{"version":3,"file":"entity-relationship-form-role.panel.js","sourceRoot":"","sources":["../../../../src/lib/panels/form-chrome/entity-relationship-form-role.panel.ts","../../../../src/lib/panels/form-chrome/entity-relationship-form-role.panel.html"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;;;;;AAQ9D;;;GAGG;AAgBI,IAAM,+BAA+B,GAArC,MAAM,+BAAgC,SAAQ,aAAyC;IAAvF;;QACa,YAAO,GAA8C;YACjE,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,MAAM,EAAE;YAC/C,EAAE,IAAI,EAAE,4BAA4B,EAAE,KAAK,EAAE,SAAS,EAAE;YACxD,EAAE,IAAI,EAAE,yBAAyB,EAAE,KAAK,EAAE,QAAQ,EAAE;SACvD,CAAC;KA0BL;IAxBG,IAAW,QAAQ;QACf,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,mBAAmB,EAAE,EAAE,EAAE,QAAQ,CAAC;QAC5D,OAAO,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;IACnE,CAAC;IAEM,YAAY,CAAC,KAA+B;QAC/C,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,QAAQ;YAAE,OAAO;QAC1E,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QACzB,MAAM,OAAO,GACT,IAAI,CAAC,MAAM,CAAC,mBAAmB,IAAI,EAAE,CAAC;QAC1C,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QACrC,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;YACnB,OAAO,EAAE,CAAC,QAAQ,CAAC;QACvB,CAAC;aAAM,CAAC;YACJ,EAAE,CAAC,QAAQ,GAAG,KAAK,CAAC;QACxB,CAAC;QACD,MAAM,IAAI,GAAgE,EAAE,GAAG,OAAO,EAAE,CAAC;QACzF,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC,EAAE,CAAC;QACnB,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACjB,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,mBAAmB,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACnF,CAAC;gTA9BQ,+BAA+B,yBAA/B,+BAA+B;oEAA/B,+BAA+B;YCrBpC,AADJ,AAPJ,+CAMgC,aACO,WACE;YAC7B,8MAGJ;YAAA,iBAAI;YAEA,AADJ,gCAAoC,WAC1B;YAAA,yBAAS;YAAA,iBAAO;YACtB,sCAO2C;YAAvC,uIAAiB,wBAAoB,IAAC;YAItD,AADI,AADI,AADI,iBAAc,EACV,EACN,EACa;;YApBnB,AADA,AAHA,wCAAsB,2BAGA,gCACK;YAUf,eAAgB;YAKhB,AADA,AADA,AAHA,kCAAgB,wBAGO,yBACH,2BACE;;;ADQzB,+BAA+B;IAf3C,eAAe,CAAC,aAAa,EAAE;QAC5B,GAAG,EAAE,gCAAgC;QACrC,kBAAkB,EAAE,IAAI;QACxB,QAAQ,EAAE;YACN,MAAM,EAAE,0BAA0B;YAClC,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,GAAG;SACf;KACJ,CAAC;GAOW,+BAA+B,CA+B3C;;iFA/BY,+BAA+B;cAN3C,SAAS;6BACM,KAAK,YACP,wCAAwC;;kFAIzC,+BAA+B","sourcesContent":["import { Component } from '@angular/core';\nimport { RegisterClassEx } from '@memberjunction/global';\nimport { BaseFormPanel } from '@memberjunction/ng-base-forms';\nimport {\n MJEntityRelationshipEntity,\n MJEntityRelationshipEntity_IEntityRelationshipConfiguration,\n} from '@memberjunction/core-entities';\n\ntype FormRoleChoice = 'Auto' | 'Primary' | 'Detail';\n\n/**\n * Form-role editor for a single Entity Relationship. Writes `Configuration.UI.FormRole`\n * (or clears it for Auto) so the parent entity's ranker / explicit punches stay in sync.\n */\n@RegisterClassEx(BaseFormPanel, {\n key: 'entity-relationships:form-role',\n skipNullKeyWarning: true,\n metadata: {\n entity: 'MJ: Entity Relationships',\n slot: 'after-fields',\n sortKey: 120,\n },\n})\n@Component({\n standalone: false,\n selector: 'mj-entity-relationship-form-role-panel',\n templateUrl: './entity-relationship-form-role.panel.html',\n styleUrls: ['./entity-form-chrome-editor.component.css'],\n})\nexport class EntityRelationshipFormRolePanel extends BaseFormPanel<MJEntityRelationshipEntity> {\n public readonly Choices: { text: string; value: FormRoleChoice }[] = [\n { text: 'Auto (parent ranker)', value: 'Auto' },\n { text: 'Primary (always top-level)', value: 'Primary' },\n { text: 'Detail (always in More)', value: 'Detail' },\n ];\n\n public get FormRole(): FormRoleChoice {\n const role = this.Record?.ConfigurationObject?.UI?.FormRole;\n return role === 'Primary' || role === 'Detail' ? role : 'Auto';\n }\n\n public OnRoleChange(value: FormRoleChoice | unknown): void {\n if (value !== 'Auto' && value !== 'Primary' && value !== 'Detail') return;\n if (!this.Record) return;\n const current: MJEntityRelationshipEntity_IEntityRelationshipConfiguration =\n this.Record.ConfigurationObject ?? {};\n const ui = { ...(current.UI ?? {}) };\n if (value === 'Auto') {\n delete ui.FormRole;\n } else {\n ui.FormRole = value;\n }\n const next: MJEntityRelationshipEntity_IEntityRelationshipConfiguration = { ...current };\n if (Object.keys(ui).length === 0) {\n delete next.UI;\n } else {\n next.UI = ui;\n }\n this.Record.ConfigurationObject = Object.keys(next).length === 0 ? null : next;\n }\n}\n","<mj-collapsible-panel\n SectionKey=\"formChrome\"\n [Order]=\"DisplayOrder\"\n SectionName=\"Form chrome\"\n Icon=\"fa-solid fa-table-columns\"\n [Form]=\"FormComponent\"\n [FormContext]=\"FormContext\">\n <div class=\"mj-form-chrome-editor\">\n <p class=\"mj-form-chrome-reason\">\n Weight of this relationship on the parent form. Auto uses the parent's\n smart ranker (same-schema children stay top-level; cross-schema hang-ons\n fold into More once the budget is exceeded).\n </p>\n <label class=\"mj-form-chrome-field\">\n <span>Form role</span>\n <mj-dropdown\n [Data]=\"Choices\"\n TextField=\"text\"\n ValueField=\"value\"\n [ValuePrimitive]=\"true\"\n [ngModel]=\"FormRole\"\n [Disabled]=\"!EditMode\"\n (ngModelChange)=\"OnRoleChange($event)\">\n </mj-dropdown>\n </label>\n </div>\n</mj-collapsible-panel>\n"]}
|